@@ -750,6 +750,38 @@ function getActionType(state: string): ActionType {
750750 }
751751}
752752
753+ /*
754+ * A charge and export plan can share one half-hour slot. Predbat supplies
755+ * the two display states separately for the legacy table; its `state` field
756+ * contains only the final action, so use both labels when they are present.
757+ */
758+ function getActionTypeFromDisplayState ( state ?: string | null ) : ActionType | null {
759+ if ( ! state ) {
760+ return null
761+ }
762+
763+ if ( state . includes ( 'FrzChrg' ) ) return 'freeze-charge'
764+ if ( state . includes ( 'HoldChrg' ) ) return 'hold-charge'
765+ if ( state . includes ( 'Chrg' ) ) return 'charge'
766+ if ( state . includes ( 'FrzExp' ) ) return 'freeze-export'
767+ if ( state . includes ( 'HoldExp' ) ) return 'hold-export'
768+ if ( state . includes ( 'Exp' ) ) return 'export'
769+
770+ return null
771+ }
772+
773+ function getPlannedActions ( row : PlanRow ) : ActionType [ ] {
774+ const splitActions = [ row . state_text , row . state2_text ]
775+ . map ( getActionTypeFromDisplayState )
776+ . filter ( ( action ) : action is ActionType => action !== null )
777+
778+ if ( splitActions . length > 1 ) {
779+ return [ ...new Set ( splitActions ) ]
780+ }
781+
782+ return [ getActionType ( row . state ) ]
783+ }
784+
753785/*
754786 * Friendly action label.
755787 */
@@ -1326,7 +1358,11 @@ export default function PlanTable({
13261358
13271359 const newDay = ! previousRow || getDateKey ( previousRow . time ) !== getDateKey ( row . time )
13281360
1329- const action = getActionType ( row . state )
1361+ const actions = getPlannedActions ( row )
1362+
1363+ const action = actions [ 0 ]
1364+
1365+ const hasMultipleActions = actions . length > 1
13301366
13311367 const reason = getReasonText ( plan , row )
13321368
@@ -1386,7 +1422,7 @@ export default function PlanTable({
13861422 className = { [
13871423 'plan-action' ,
13881424 'plan-tooltip-trigger' ,
1389- getActionClass ( action ) ,
1425+ hasMultipleActions ? 'plan-action-multiple' : getActionClass ( action ) ,
13901426 manualOverride ? 'is-manual' : ''
13911427 ]
13921428 . filter ( Boolean )
@@ -1409,9 +1445,26 @@ export default function PlanTable({
14091445 setOpenOverrideTime ( menuOpen ? null : row . time )
14101446 } }
14111447 >
1412- { getActionIcon ( action ) }
1448+ { hasMultipleActions ? (
1449+ < span className = "plan-action-badges" >
1450+ { actions . map ( ( plannedAction ) => (
1451+ < span
1452+ key = { plannedAction }
1453+ className = { [ 'plan-action-badge' , getActionClass ( plannedAction ) ] . join ( ' ' ) }
1454+ >
1455+ { getActionIcon ( plannedAction ) }
1456+
1457+ < span > { getActionLabel ( plannedAction ) } </ span >
1458+ </ span >
1459+ ) ) }
1460+ </ span >
1461+ ) : (
1462+ < >
1463+ { getActionIcon ( action ) }
14131464
1414- < span > { getActionLabel ( action ) } </ span >
1465+ < span > { getActionLabel ( action ) } </ span >
1466+ </ >
1467+ ) }
14151468
14161469 { rateEvent && (
14171470 < span className = { `plan-saving-session-badge is-${ rateEvent . colour } ` } >
0 commit comments