diff --git a/frontend/src/components/StatePanel.tsx b/frontend/src/components/StatePanel.tsx index e60d92a..2f52a28 100644 --- a/frontend/src/components/StatePanel.tsx +++ b/frontend/src/components/StatePanel.tsx @@ -443,8 +443,9 @@ function TrackRow({ showNowLabel?: boolean }) { return ( -
-
{label}
+ // Mobil: label nad trackem (plná šířka); md+: label vlevo vedle tracku. +
+
{label}
) @@ -484,8 +485,8 @@ function StatePanelRaw({ slots, nowIndex }: StatePanelProps) {
-
-
+
+
    @@ -517,8 +518,8 @@ function StatePanelRaw({ slots, nowIndex }: StatePanelProps) {
-
-
+
+
    diff --git a/frontend/src/pages/Planning.tsx b/frontend/src/pages/Planning.tsx index 00bdb52..81484ba 100644 --- a/frontend/src/pages/Planning.tsx +++ b/frontend/src/pages/Planning.tsx @@ -9,7 +9,7 @@ import { Upload, } from 'lucide-react' import { toast } from 'sonner' -import { useCallback, useEffect, useMemo, useState } from 'react' +import { Fragment, useCallback, useEffect, useMemo, useState } from 'react' import { Area, Bar, @@ -1054,11 +1054,6 @@ export default function Planning() { return new Map(list.map((i) => [i.interval_start, i])) }, [compareData?.comparison?.intervals]) - const selectedSlot = useMemo( - () => visibleSlots.find((s) => s.interval_start === selectedStart) ?? null, - [visibleSlots, selectedStart], - ) - const tableColCount = 14 + (solverSnap != null ? 1 : 0) + (showGenCut ? 1 : 0) async function onReplan() { @@ -1612,11 +1607,11 @@ export default function Planning() { {/* Sekce 4 */} -
    +

    Tabulka slotů

    - +
    @@ -1716,8 +1711,8 @@ export default function Planning() { const phaseBadge = negSellPhaseBadge(slotMask) const pvAllowed = pvAAllowedW(i) return ( + setSelectedStart((prev) => (prev === i.interval_start ? null : i.interval_start))} @@ -1816,6 +1811,23 @@ export default function Planning() { + {sel ? ( + // Detail jako plnoširoký řádek pod vybraným slotem (žádný překryv); + // sticky left drží blok ve viewportu i při horizontálním scrollu tabulky. + + + + ) : null} + ) })} @@ -1826,14 +1838,6 @@ export default function Planning() { Žádné budoucí sloty v horizontu {tableHorizonH} h (aktivní plán může být prázdný nebo starý).

    )} - {selectedSlot != null && ( - - )} {!solverSnap && run != null && (

    Masky solveru nejsou v tomto běhu — spusťte nový rolling/denní plán po nasazení arbitráže.

    Čas
    {i.heat_pump_enabled ? 'on' : 'off'}
    +
    + +
    +