Verfahrensablauf: re-surface hidden optional events — add 'show hidden' toggle #122

Open
opened 2026-05-26 07:27:05 +00:00 by mAi · 1 comment
Collaborator

m's report (2026-05-26 09:26)

our option to hide optional submissions / events in the timeline should be improved. We need to be able to re-surface them somehow, probably with another option.

Scope

atlas's #96 Slice A added per-card 'skip optional' choices (stored in paliad.project_event_choices). Once an optional card is skipped, there's no obvious way to un-skip — the card is gone from the timeline.

Fix: add a 'show hidden' toggle on the Verfahrensablauf page. When toggled ON, all skipped-optional cards render again with a visual indicator that they're hidden (e.g. faded background + a small 'wieder einblenden' chip on each).

What to do

  1. Add a toggle near the page-level perspective + appellant selectors (#88 / #111). Label: 'Ausgeblendete anzeigen' / 'Show hidden'. Default OFF.
  2. When ON, the verfahrensablauf-core projection includes skipped cards but with a Hidden=true flag.
  3. Frontend renders hidden cards faded (opacity ~50% / dotted border) with an action chip 'Wieder einblenden' that deletes the skip choice.
  4. URL state: ?show_hidden=1 so the state survives reload + is shareable.
  5. Hidden count badge: 'Ausgeblendete (3)' on the toggle so the user knows there's something to re-surface even when the toggle is OFF.

Files most likely touched

  • frontend/src/client/verfahrensablauf.ts — toggle UI + URL state
  • frontend/src/client/views/verfahrensablauf-core.ts — render hidden cards conditionally
  • frontend/src/client/views/event-card-choices.ts (atlas's #96 module) — 're-surface' button
  • frontend/src/styles/global.css — faded-hidden styling
  • internal/services/projection_service.go — include-hidden flag in the projection call
  • frontend/src/client/i18n.ts + frontend/src/i18n-keys.ts

Hard rules

  • Don't change the skip-choice storage shape (atlas's table).
  • Default state OFF — m's not asking to see hidden by default, just to be able to.
  • go build ./... && go test ./internal/... && cd frontend && bun run build clean.
  • Branch: mai/<worker>/resurface-hidden-optionals.

Out of scope

  • Bulk hide / bulk re-surface UI.
  • Per-user hidden preferences across projects.
  • Hiding non-optional events (atlas #96's contract).

Reporting

mai report completed with branch + SHAs + UX path: open a project where you previously hid an optional event → toggle 'Ausgeblendete anzeigen' → confirm the hidden card re-appears faded → click 'Wieder einblenden' → confirm card returns to normal opacity + skip choice cleared from DB.

## m's report (2026-05-26 09:26) > our option to hide optional submissions / events in the timeline should be improved. We need to be able to re-surface them somehow, probably with another option. ## Scope atlas's #96 Slice A added per-card 'skip optional' choices (stored in `paliad.project_event_choices`). Once an optional card is skipped, there's no obvious way to un-skip — the card is gone from the timeline. Fix: add a 'show hidden' toggle on the Verfahrensablauf page. When toggled ON, all skipped-optional cards render again with a visual indicator that they're hidden (e.g. faded background + a small 'wieder einblenden' chip on each). ## What to do 1. Add a toggle near the page-level perspective + appellant selectors (#88 / #111). Label: 'Ausgeblendete anzeigen' / 'Show hidden'. Default OFF. 2. When ON, the verfahrensablauf-core projection includes skipped cards but with a `Hidden=true` flag. 3. Frontend renders hidden cards faded (opacity ~50% / dotted border) with an action chip 'Wieder einblenden' that deletes the skip choice. 4. URL state: `?show_hidden=1` so the state survives reload + is shareable. 5. Hidden count badge: 'Ausgeblendete (3)' on the toggle so the user knows there's something to re-surface even when the toggle is OFF. ## Files most likely touched - `frontend/src/client/verfahrensablauf.ts` — toggle UI + URL state - `frontend/src/client/views/verfahrensablauf-core.ts` — render hidden cards conditionally - `frontend/src/client/views/event-card-choices.ts` (atlas's #96 module) — 're-surface' button - `frontend/src/styles/global.css` — faded-hidden styling - `internal/services/projection_service.go` — include-hidden flag in the projection call - `frontend/src/client/i18n.ts` + `frontend/src/i18n-keys.ts` ## Hard rules - Don't change the skip-choice storage shape (atlas's table). - Default state OFF — m's not asking to see hidden by default, just to be able to. - `go build ./... && go test ./internal/... && cd frontend && bun run build` clean. - Branch: `mai/<worker>/resurface-hidden-optionals`. ## Out of scope - Bulk hide / bulk re-surface UI. - Per-user hidden preferences across projects. - Hiding non-optional events (atlas #96's contract). ## Reporting `mai report completed` with branch + SHAs + UX path: open a project where you previously hid an optional event → toggle 'Ausgeblendete anzeigen' → confirm the hidden card re-appears faded → click 'Wieder einblenden' → confirm card returns to normal opacity + skip choice cleared from DB.
mAi self-assigned this 2026-05-26 07:27:05 +00:00
Author
Collaborator

Shipped on mai/artemis/gitster-re-surface @ 80883ea.

What landed

Backend (internal/services/fristenrechner.go + internal/handlers/fristenrechner.go)

  • CalcOptions.IncludeHidden bool (default false). When true, the rule loop no longer drops skipRules entries: it marks the resulting UIDeadline.IsHidden=true and bypasses descendant cascade-suppression (so children compute their dates off the un-suppressed parent, exactly as if the user had never hidden it). Default false preserves atlas's #96 skip semantic.
  • UIDeadline.IsHidden + UIResponse.HiddenCount on the wire (camelCase JSON, omitempty on the bool).
  • HiddenCount is independent of the toggle — it always counts gate-passed rules whose submission_code is in skipRules, so the badge stays accurate even when the toggle is OFF.
  • POST /api/tools/fristenrechner accepts includeHidden: true on the body.

Frontend

  • frontend/src/client/verfahrensablauf.tsshowHidden state hydrated from ?show_hidden=1, written back on toggle change, passed as includeHidden to calculateDeadlines. Recalc on flip (response shape changes; can't reuse lastResponse). New syncHiddenBadge(n) updates the badge after every calc and hides the whole row when count == 0.
  • frontend/src/client/views/verfahrensablauf-core.tsCalculatedDeadline.isHidden? + DeadlineResponse.hiddenCount? + CalcParams.includeHidden? in TS types. deadlineCardHtml emits a <button class="event-card-choices-unhide" data-submission-code=…>Wieder einblenden</button> when isHidden && code !== "". renderTimelineBody / renderColumnsBody wrap items with timeline-item--hidden / fr-col-item--hidden so the fade is consistent across both views.
  • frontend/src/client/views/event-card-choices.ts — new delegated click handler on .event-card-choices-unhide calls state.opts.remove(code, "skip") then reseedChips(). The page's existing remove callback already triggers a recalc, so the un-hide chip works on both /tools/verfahrensablauf (URL state) and any future project-bound consumer (server persistence).
  • frontend/src/verfahrensablauf.tsx — new row #show-hidden-row inside .verfahrensablauf-perspective, hidden by default; the client reveals it whenever hiddenCount > 0. Badge text Ausgeblendete (3) lives in a #show-hidden-count span.
  • frontend/src/styles/global.css.timeline-item--hidden .timeline-content and .fr-col-item--hidden: opacity: 0.55 + 1px dotted border + rounded corners. .event-card-choices-unhide is a lime-accent chip with opacity: 1 so it stays high-contrast against the faded parent. .show-hidden-count is the muted badge text.
  • 3 new i18n keys (DE + EN, codegen-clean): choices.show_hidden.label ("Ausgeblendete anzeigen" / "Show hidden"), choices.show_hidden.count ("Ausgeblendete ({n})" / "Hidden ({n})"), choices.unhide.chip ("Wieder einblenden" / "Show again").

Hard-rules compliance

  • Skip-choice storage shape unchanged — un-hide is a DELETE on paliad.project_event_choices via the existing EventChoiceService.Delete path (URL-state on the unbound surface; same remove callback regardless).
  • Default state OFF.
  • go build ./... && go test ./internal/... clean.
  • bun test src/ — 172 pass / 0 fail (3 new cases pin the unhide-chip contract).
  • bun run build clean — 2903 i18n keys, no data-i18n leaks, IIFE-prologue intact.
  • Branch: mai/artemis/gitster-re-surface.

UX path (manual smoke pending)

  1. Open /tools/verfahrensablauf (no project).
  2. Pick a proceeding with optional rows (e.g. UPC INF — Klageerhebung has optional cards downstream).
  3. Click the ▾ caret on an optional card → "Für diese Akte überspringen" → "Überspringen". Card disappears. URL gets ?event_choices=…:skip=true.
  4. The new "Ausgeblendete anzeigen" row reveals itself with Ausgeblendete (1).
  5. Toggle ON → card reappears faded with dotted border and a lime "Wieder einblenden" chip. URL gains ?show_hidden=1.
  6. Click the chip → card returns to normal opacity, skip choice cleared from event_choices, badge count drops.

Project-bound /tools/fristenrechner is unaffected (no toggle added there per the issue scope: "on the Verfahrensablauf page"). The shared verfahrensablauf-core.ts module stays a no-op for it because includeHidden defaults to undefined.

Commit: https://mgit.msbls.de/m/paliad/commit/80883ea

Shipped on `mai/artemis/gitster-re-surface` @ `80883ea`. ## What landed **Backend (`internal/services/fristenrechner.go` + `internal/handlers/fristenrechner.go`)** - `CalcOptions.IncludeHidden bool` (default `false`). When `true`, the rule loop no longer drops `skipRules` entries: it marks the resulting `UIDeadline.IsHidden=true` and **bypasses descendant cascade-suppression** (so children compute their dates off the un-suppressed parent, exactly as if the user had never hidden it). Default `false` preserves atlas's #96 skip semantic. - `UIDeadline.IsHidden` + `UIResponse.HiddenCount` on the wire (camelCase JSON, `omitempty` on the bool). - `HiddenCount` is **independent of the toggle** — it always counts gate-passed rules whose `submission_code` is in `skipRules`, so the badge stays accurate even when the toggle is OFF. - `POST /api/tools/fristenrechner` accepts `includeHidden: true` on the body. **Frontend** - `frontend/src/client/verfahrensablauf.ts` — `showHidden` state hydrated from `?show_hidden=1`, written back on toggle change, passed as `includeHidden` to `calculateDeadlines`. Recalc on flip (response shape changes; can't reuse `lastResponse`). New `syncHiddenBadge(n)` updates the badge after every calc and hides the whole row when `count == 0`. - `frontend/src/client/views/verfahrensablauf-core.ts` — `CalculatedDeadline.isHidden?` + `DeadlineResponse.hiddenCount?` + `CalcParams.includeHidden?` in TS types. `deadlineCardHtml` emits a `<button class="event-card-choices-unhide" data-submission-code=…>Wieder einblenden</button>` when `isHidden && code !== ""`. `renderTimelineBody` / `renderColumnsBody` wrap items with `timeline-item--hidden` / `fr-col-item--hidden` so the fade is consistent across both views. - `frontend/src/client/views/event-card-choices.ts` — new delegated click handler on `.event-card-choices-unhide` calls `state.opts.remove(code, "skip")` then `reseedChips()`. The page's existing `remove` callback already triggers a recalc, so the un-hide chip works on both `/tools/verfahrensablauf` (URL state) and any future project-bound consumer (server persistence). - `frontend/src/verfahrensablauf.tsx` — new row `#show-hidden-row` inside `.verfahrensablauf-perspective`, hidden by default; the client reveals it whenever `hiddenCount > 0`. Badge text `Ausgeblendete (3)` lives in a `#show-hidden-count` span. - `frontend/src/styles/global.css` — `.timeline-item--hidden .timeline-content` and `.fr-col-item--hidden`: `opacity: 0.55` + `1px dotted border` + rounded corners. `.event-card-choices-unhide` is a lime-accent chip with `opacity: 1` so it stays high-contrast against the faded parent. `.show-hidden-count` is the muted badge text. - 3 new i18n keys (DE + EN, codegen-clean): `choices.show_hidden.label` ("Ausgeblendete anzeigen" / "Show hidden"), `choices.show_hidden.count` ("Ausgeblendete ({n})" / "Hidden ({n})"), `choices.unhide.chip` ("Wieder einblenden" / "Show again"). ## Hard-rules compliance - Skip-choice storage shape unchanged — un-hide is a `DELETE` on `paliad.project_event_choices` via the existing `EventChoiceService.Delete` path (URL-state on the unbound surface; same `remove` callback regardless). - Default state OFF. - `go build ./... && go test ./internal/...` clean. - `bun test src/` — 172 pass / 0 fail (3 new cases pin the unhide-chip contract). - `bun run build` clean — 2903 i18n keys, no data-i18n leaks, IIFE-prologue intact. - Branch: `mai/artemis/gitster-re-surface`. ## UX path (manual smoke pending) 1. Open `/tools/verfahrensablauf` (no project). 2. Pick a proceeding with optional rows (e.g. UPC INF — Klageerhebung has optional cards downstream). 3. Click the ▾ caret on an optional card → "Für diese Akte überspringen" → "Überspringen". Card disappears. URL gets `?event_choices=…:skip=true`. 4. The new "Ausgeblendete anzeigen" row reveals itself with `Ausgeblendete (1)`. 5. Toggle ON → card reappears faded with dotted border and a lime "Wieder einblenden" chip. URL gains `?show_hidden=1`. 6. Click the chip → card returns to normal opacity, skip choice cleared from `event_choices`, badge count drops. Project-bound `/tools/fristenrechner` is unaffected (no toggle added there per the issue scope: "on the Verfahrensablauf page"). The shared `verfahrensablauf-core.ts` module stays a no-op for it because `includeHidden` defaults to `undefined`. Commit: https://mgit.msbls.de/m/paliad/commit/80883ea
mAi added the
done
label 2026-05-26 07:39:33 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: m/paliad#122
No description provided.