feat(taiga): Anlage-Knöpfe neu geschnitten — ein Story-Knopf mit Dialog, dialogfreie Task unter einem Story-Vorfahren (D91-Nachtrag 9)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
mhoennig
2026-08-28 11:08:13 +02:00
co-authored by Claude Opus 5
parent 4f6d45045a
commit 0ed30e9eae
7 changed files with 226 additions and 42 deletions
+5
View File
@@ -17,6 +17,11 @@ the git history of `docs/examples/werkbaum.werkbaum`. A day can therefore carry
a link without having a note (someone forgot to write one) — but never the
reverse.
## 2026-08-28
- The create buttons in the node window are recut: one "create story" button always opens the dialog with project choice and sub-package checkboxes — unchecking covers the story-only case
- A "create task" button appears where an ancestor node already carries a story: the task lands in that story without any dialog — project and story follow from the tree, only an error gets a surface
## 2026-08-27
- Where a ticket and the plan disagree, the node window says so and offers both directions as explicit buttons — nothing happens by itself
+55
View File
@@ -8331,3 +8331,58 @@ Wer i18n-Texte mit Anführungszeichen schreibt, nimmt die typografischen
(`„…“`, `«…»`, `“…”`) und prüft die Datei einmal mit `npx esbuild src/app.js
--outfile=…` — das ist die schnellste ehrliche Syntaxprobe für eine Datei,
die kein Test anfasst.
**Nachtrag 9 — die Anlage-Knöpfe neu geschnitten: ein Story-Knopf mit
Dialog, ein dialogfreier Task-Knopf (2026-08-28).** Nutzerwunsch nach dem
ersten Arbeiten mit der Anlage: statt „Story anlegen"/„Story + Tasks
anlegen" **ein** „Story anlegen" (mit dem Häkchen-Dialog über die
Teilpakete, wie bisher bei der zweiten Aktion) und daneben **„Task
anlegen"** — nur dort, wo ein übergeordneter Knoten schon eine Story trägt,
denn in der wird die Task angelegt; „für Task-Anlegen braucht man dann auch
keine Auswahl". Die Entscheidungen des Baus:
- **Der eine Story-Knopf trägt den Dialog immer** — wer nur die Story will,
wählt die Häkchen ab (an einem Blatt gibt es ohnehin keine). Der frühere
Story-only-Knopf entfällt ersatzlos; ein Knopf, dessen ganze Aussage „wie
der andere, nur ohne Häkchen" ist, war einer zu viel.
- **„Task anlegen" hängt am nächsten Vorfahren mit `#US-…`-Ref**
(`storyAncestor`, headless in taiga.js). Vorfahren mit **Task**-Ref werden
übersprungen: Taiga-Tasks haben keine Subtasks (D91), die Task eines
Task-Knotens gehört in die Story darüber.
- **Ohne Dialog, weil es nichts zu wählen gibt:** Das Projekt folgt aus dem
geerbten `&taiga.<slug>`, die Story aus dem Baum. Das weicht bewusst von
der Haupttext-Festlegung „das Projekt wird bei jeder Anlage gefragt" ab —
hier hätte die Frage genau eine richtige Antwort, und eine Frage mit einer
Antwort ist keine. Der Story-Dialog fragt unverändert.
- **Der Knopf entfällt, wo ein `&taiga.*` zwischen Story und Knoten den Slug
übersteuert:** Die Ref an so einer Zeile würde später gegen das **falsche**
Projekt aufgelöst (Fenster, Öffnen, Status) — lieber kein Knopf als eine
Adresse, die lügt.
- **Drei Umläufe, kein Backend-Umbau:** Mitgliederliste (die Projekt-Id zum
Slug — der Lese-Endpunkt trägt keine), Story-Detail per `by_ref` (die
Story-Id, das `id`-Feld liefert Nachtrag 6 schon), `POST /tasks`.
- **Der Erfolg zeigt sich als Ref an der Zeile** (der Neubau ist die
Rückmeldung, wie beim Falten); nur ein **Fehler** bekommt eine Fläche —
ein kleiner Dialog mit Taigas Meldung (Ok-Knopf verborgen, Abbrechen
schließt), kein `window.alert` (D22-Lehre). Ein Slug außerhalb der eigenen
Projekte meldet sich mit eigenem Text (`taigaTaskNoProject`).
- i18n: `taigaTaskBtn`/`taigaTaskNoProject` neu ×9, `taigaTasksBtn` entfällt.
**Nachgemessen** Ende-zu-Ende im Browser gegen das lokale Backend mit
Taiga-Stub, alle vier Knopf-Konstellationen: Story + Task unter einem
Story-Vorfahren; nur Story bei übersteuerndem Slug; nur Story ohne
Story-Vorfahren; keine Anlage-Knöpfe an einer Ref (dort Stand + Öffnen wie
gehabt). Der Task-Klick schreibt `#T-201` an die Zeile, ohne Dialog;
Stub-Mitschnitt: `projects``by_slug``by_ref` → `POST /tasks
{project: 7, user_story: 1234}`. Der Story-Knopf auf einem Knoten mit
Kindern öffnet den Dialog mit Projekt-Vorbelegung und beiden Häkchen; der
Fremd-Slug-Fehlerpfad zeigt den Dialog mit Taigas Meldung und lässt die
Zeile unangetastet. 602 Tests (6 neue für `storyAncestor`); Gegenprobe per
Mutation: ohne das Überspringen der Task-Refs fällt genau der danach
benannte Test.
**Werkzeug-Notiz:** Die JavaScript-Ausführung des Prüf-Panes lebt in einer
**isolierten Welt** — ein überschriebenes `window.confirm` erreicht die
Seite nicht (Klicks schon: das DOM ist geteilt, die JS-Objekte nicht). Eine
Rückfrage lässt sich dort also nicht wegstubben; Aufräumen, das durch eine
Rückfrage führt, geht stattdessen über die Ablage selbst (D83-Schema).
+11 -2
View File
@@ -211,6 +211,7 @@
- [^] #trk.create.project: The project comes from the inherited tag (S) :#not.tag.project
- [^] #trk.create.story: A "create story" action in the node window (S) :#trk.create.login
- [^] #trk.create.tasks: Sub-packages become tasks, picked in a dialog (M) :#trk.create.story
- [x] #trk.create.task: A dialog-free "create task" under a story ancestor (S) :#trk.create.tasks,#trk.resolve.read
- [^] #trk.create.ref: The ref lands in the line beside the id (S) :#trk.create.story
- [^] #trk.open: Open a ticket ref in Taiga (S) :#trk.create.ref,#not.tag.project
- [-] #trk.plugin: A plugin inside Taiga itself (L) %% legacy frontend, self-hosted only
@@ -1192,10 +1193,18 @@
created. A node that already carries a ticket ref is left alone.
#trk.create.tasks
The second action also creates the direct sub-packages as tasks under the
The story dialog also creates the direct sub-packages as tasks under the
story, chosen in a checkbox dialog: preselected are required and optional
children plus the realized alternatives of a |/= group; discarded ones
never appear, finished ones start unchecked.
never appear, finished ones start unchecked. Unchecking everything covers
the story-only case, so there is just one create-story button.
#trk.create.task
Where an ancestor node already carries a story ref, the node window offers
"create task": the task lands in that story, without any dialog — project
and story follow from the tree. Ancestors with a task ref are skipped
(Taiga tasks have no subtasks), and the button is absent where a &taiga
tag in between would resolve the new ref against the wrong project.
#trk.create.project
The dialog's project choice is prefilled from the nearest (&taiga.slug)