From 21f2e6fee62129b051d1e84db8760305fc23ff8b Mon Sep 17 00:00:00 2001 From: masterdraco Date: Tue, 29 Sep 2026 17:28:30 +0200 Subject: [PATCH] =?UTF-8?q?docs(spec):=20Flows/Fields=20som=20farvet=20lis?= =?UTF-8?q?te=20med=20Start/Stop=20pr.=20r=C3=A6kke=20+=20redigeringsvindu?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...09-29-flow-field-list-edit-panel-design.md | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 docs/superpowers/specs/2026-09-29-flow-field-list-edit-panel-design.md diff --git a/docs/superpowers/specs/2026-09-29-flow-field-list-edit-panel-design.md b/docs/superpowers/specs/2026-09-29-flow-field-list-edit-panel-design.md new file mode 100644 index 0000000..564574f --- /dev/null +++ b/docs/superpowers/specs/2026-09-29-flow-field-list-edit-panel-design.md @@ -0,0 +1,131 @@ +# Flows og Fields: farvet liste + redigeringsvindue + +Dato: 2026-09-29 · Status: godkendt i chat ("men kør"), afventer review af denne spec + +## Formål + +Flows- og Fields-fanen er i dag én lang rullende side: listen over flows/marker efterfulgt af den valgte +posts redigeringslinjer. Det er svært at overskue (brugerens screenshot 29/9 17:15). Målet: + +- Fanen viser **kun listen**, med farvet status og **Start/Stop pr. række**. +- **Klik på en række** åbner et **redigeringsvindue** (popup) oven på listen med de nuværende linjer. + +Succes = man kan se med ét blik hvad der kører/venter/fejler, starte/stoppe en post uden at vælge den først, +og redigere i et vindue der lukkes med Luk/ESC — uden at noget af flow-/mark-logikken ændres. + +## Ikke-mål + +- Ingen ændring af flow-/mark-logik, guiderne ("Nyt flow", "Opsæt mark") eller deres trin. +- Oversigt-tavlen og Fields' flåde-visning er uændrede. +- Ingen ny FS25-GUI-skærm/dialog (fravalgt: al rækkekode skulle genbygges; fokus/ESC oven på ESC-menuen er + skrøbeligt). "Popup" er et panel inde i samme frame. + +## Brugeroplevelse + +### Flows-fanen (liste) + +Én række pr. flow: `● navn · varer · kørende/i alt · statustekst · [Start]/[Stop]`. + +| Niveau | Prik/statusfarve | Hvornår | +|---|---|---| +| running | grøn | mindst én traktor kører og ingen er blokeret | +| waiting | gul | startet, men venter: ingen varer at hente, venter på vogn, traktor optaget, holder ved Wait | +| error | rød | kan ikke køre: sidste start afvist (fx ingen vogn), advarsel (`!!`) | +| stopped | grå | stoppet / aldrig startet | + +- `[Start]/[Stop]` bruger den eksisterende `ADRunsController.startRun/stopRun` (samme regler som knaplinjen, inkl. + sprunget-over-besked i højre side). +- Klik på rækken (ikke knappen) åbner redigeringsvinduet for flowet. +- Knaplinjen (i dag Tilbage, Start/Stop, Opsæt flow, Nyt flow, Slet) bliver: Tilbage, Nyt flow. Start/Stop sidder på + rækkerne; "Opsæt flow" og "Slet" flyttes ind i vinduet. + +### Fields-fanen (liste) + +Nuværende kolonner (Mark, Afgrøde, Plan, Kørsel, Status, Traktorer) + `●` forrest og `[Start]/[Stop]` bagerst. + +| Niveau | Hvornår | +|---|---| +| running (grøn) | marken har aktive opgaver der arbejder | +| waiting (gul) | startet men venter: på maskine, vejr, påfyldning, "startes når en maskine er ledig" | +| error (rød) | mangler markør, arbejdsbredde for bred/ukendt, ingen egnet maskine | +| stopped (grå) | ingen plan / stoppet | + +- `[Start]/[Stop]` genbruger `onClickFieldStartStop` (inkl. "Overtag høster"). +- Klik på rækken åbner vinduet med markens resumé og [Ret]-linjer. + +### Redigeringsvinduet (fælles) + +- Mørk halvgennemsigtig baggrund over listen; centreret panel (~70 % bredde, ~80 % højde). +- Top: titel ("Rediger: Cow Food" / "Mark F12"), statuslinje i niveau-farve. +- Midte: egen rullende liste med præcis det indhold, der i dag vises under listen: + flow → `fillFlowSummary`-linjerne; mark → `fillFieldOverview`-linjerne. [Edit]/[Ret] åbner trinnet + (guiden i enkelt-trin-tilstand) **inde i vinduet** med Gem/Tilbage som i dag. +- Bund: `Luk` · `Start/Stop` · `Slet` (kun flow). ESC/Tilbage lukker vinduet (ikke menuen); står et trin åbent, + går ESC først tilbage til resuméet. +- Mens vinduet er åbent, opdateres statuslinjen og listen bagved hvert sekund som i dag. + +## Arkitektur + +### Rene funktioner (testbare) + +- `ADFlowView.flowStatus(s)` → `{level, text}` hvor `s = {running, total, canStop, lastStartSkipped, warning, + waitReason, holdReason, stopped}`. Afgør niveau efter tabellen ovenfor. +- `ADFieldView.fieldStatus(s)` → `{level, text}` hvor `s = {working, awaiting, starting, missingMarker, + widthProblem, noMachine, hasPlan}`. +- `ADFlowView.LEVEL_COLORS` (grøn/gul/rød/grå) — flyttes/udleveres fra `SmartPickupStorageView`s lokale tabel, + som også eksporterer `setTextColor` til genbrug. + +### GUI + +- **XML** (`SmartPickupFrame.xml`): efter `boxLayout` et `GuiElement id="editOverlay"` (skjult) med + `Bitmap id="editBackdrop"` (fuld flade, sort ~60 %), `Bitmap id="editPanel"` (centreret, baggrund som + fs25-paneler) med `Text id="editTitle"`, `Text id="editStatus"`, `ScrollingLayout id="editLayout"` (+ slider) og + en knaplinje med tre `Button`s (`editClose`, `editStartStop`, `editDelete`). +- **Rækkeprefabs**: `flowPrefab` og `fieldPrefab` får en `Bitmap name="dot"` (profil `spuDot`) forrest og en + `Button name="rowAction"` bagerst. Kolonnebredder justeres så rækken stadig er ≈835 px. +- **Mål-layout for rækker**: `addRow`/`addTextRow`/`addCellRow`/`addLinkRow`/`addGuideRow` kloner i dag altid ind i + `self.boxLayout`. Der indføres `self.rowTarget` (standard `boxLayout`); vinduet sætter det til `editLayout` + mens det fyldes. `clearRows` holder klonerne pr. layout, så listen og vinduet kan genopbygges hver for sig. +- **Ny fil** `gui/SmartPickupEditPanel.lua` (mixin på `SmartPickupFrame`, `source()`s som de andre): + `openEditPanel(kind, id)`, `closeEditPanel()`, `fillEditPanel(adEnv)`, `refreshEditPanel(adEnv)`, + knap-callbacks. `kind ∈ {"flow","field"}`. +- **Input**: `backButtonInfo`-callback og ESC tjekker først `self.editPanelOpen` (luk trin → luk vindue → + normal Tilbage). Klik på backdrop gør intet (blokerer klik til listen bagved via `mouseEvent` der returnerer + "brugt"). +- **Guide i vinduet**: `openFlowStep`/`openFieldStep` sætter `returnTo = "panel"`, så Gem/Tilbage vender tilbage til + vinduets resumé i stedet for at lukke guiden til fanen. + +### Dataflow + +Klik på række → `openEditPanel(kind, id)` → `selectedRunId`/`selectedFieldId` sættes (eksisterende felter) → +`requestRebuild` → `rebuild` tegner listen i `boxLayout` og, når vinduet er åbent, vinduets indhold i +`editLayout`. Start/Stop i række eller vindue kalder de eksisterende controller-funktioner og `requestRebuild`. + +## Fejlhåndtering + +- Alt nyt GUI-arbejde kører i `self:safe(...)` som resten af frame'n; fejl vises i statuslinjen og logges. +- Forsvinder flowet/marken mens vinduet er åbent (slettet), lukkes vinduet og statuslinjen siger hvorfor. +- `rowAction`-knappen er deaktiveret når handlingen ikke er mulig (fx mark uden markør → ingen Start). + +## Test + +- luajit: `tests/test_flowStatus.lua` og `tests/test_fieldStatus.lua` for alle niveauer i tabellerne + + grænsetilfælde (0 traktorer, stoppet med advarsel, venter + afvist). +- Eksisterende tests skal forblive grønne (`test_noStrayGlobals` dækker den nye fil). +- In-game (brugeren): liste med farver, Start/Stop pr. række, åbn/luk vindue med klik/Luk/ESC, [Edit] → Gem inde i + vinduet, Slet flow fra vinduet, klik på listen bag vinduet gør intet, mark "Overtag høster" virker fra rækken. + +## Levering + +To etaper, hver sin version og in-game test: + +1. **Flows**: rene statusfunktioner + fælles vindue + Flows-liste. +2. **Fields**: mark-status + Fields-liste genbruger vinduet. + +## Risici + +- **Klik gennem backdrop** til listen: afbødes ved at backdrop'en fanger `mouseEvent`; fallback: skjul listens rækker + (`setVisible(false)`) mens vinduet er åbent. +- **Musehjul/rulning** i to ScrollingLayouts: hver får sin egen slider; FS25 ruller det layout musen er over. +- **Knapper i rækkeprefabs** (Button i en klonet Bitmap) er ikke brugt før i modden: onClick sættes efter + `clone` pr. række (som `makeRowClickable`), ikke via XML-callback.