From 493434a4448ba307c53b3fc70dc2225643f36d91 Mon Sep 17 00:00:00 2001 From: Eric F Date: Wed, 17 Jun 2026 19:09:07 -0400 Subject: [PATCH] fix: Fetch actual EVSEs instead of VariableAttributes in charging station detail - page.tsx: Added evses relationship to Server Component query - charging.station.detail.card.tsx: Replaced VariableAttributes alias with real evses relationship - evses.ts: Fixed stationId type from Int! to String! (2 queries) - evse.dto.tsx: Removed ocppConnectionName (not a DB column on Evses) - evses.upsert.tsx: Removed ocppConnectionName prop, added String(stationId) coercion - evses.list.tsx: Fixed id type to string, extract ChargingStations[0] from GraphQL response - charging.station.detail.tabs.card.tsx: Fixed id type to string --- .../charging-stations/[id]/page.tsx | 1 + .../detail/charging.station.detail.card.tsx | 2 +- .../detail/charging.station.detail.tabs.card.tsx | 2 +- .../charging-stations/detail/evses/evses.list.tsx | 14 ++++++++++---- .../detail/evses/evses.upsert.tsx | 7 ++----- .../apps/operator-ui/src/lib/cls/evse.dto.tsx | 1 - .../apps/operator-ui/src/lib/queries/evses.ts | 4 ++-- 7 files changed, 17 insertions(+), 14 deletions(-) diff --git a/tools/citrineos-core-main/apps/operator-ui/src/app/(authenticated)/charging-stations/[id]/page.tsx b/tools/citrineos-core-main/apps/operator-ui/src/app/(authenticated)/charging-stations/[id]/page.tsx index e48ccbb..00959c2 100644 --- a/tools/citrineos-core-main/apps/operator-ui/src/app/(authenticated)/charging-stations/[id]/page.tsx +++ b/tools/citrineos-core-main/apps/operator-ui/src/app/(authenticated)/charging-stations/[id]/page.tsx @@ -37,6 +37,7 @@ async function fetchStation(id: string) { coordinates use16StatusNotification0 location { id name address city postalCode state country coordinates createdAt updatedAt } + evses { id stationId evseId evseTypeId physicalReference removed createdAt updatedAt } variableAttributes { id stationId variableId value dataType } latestStatusNotifications { id stationId statusNotificationId updatedAt createdAt StatusNotification { connectorId connectorStatus createdAt evseId id stationId timestamp updatedAt } } transactions(where: {isActive: {_eq: true}}) { id stationId timeSpentCharging isActive chargingState stoppedReason transactionId evseId remoteStartId totalKwh createdAt updatedAt } diff --git a/tools/citrineos-core-main/apps/operator-ui/src/lib/client/pages/charging-stations/detail/charging.station.detail.card.tsx b/tools/citrineos-core-main/apps/operator-ui/src/lib/client/pages/charging-stations/detail/charging.station.detail.card.tsx index 953ae2c..73e747a 100644 --- a/tools/citrineos-core-main/apps/operator-ui/src/lib/client/pages/charging-stations/detail/charging.station.detail.card.tsx +++ b/tools/citrineos-core-main/apps/operator-ui/src/lib/client/pages/charging-stations/detail/charging.station.detail.card.tsx @@ -125,7 +125,7 @@ export const ChargingStationDetailCard = ({ coordinates use16StatusNotification0 location { id name address city postalCode state country coordinates createdAt updatedAt } - evses: VariableAttributes(where: {stationId: {_eq: $id}, variableId: {_eq: "1"}}) { id stationId variableId value dataType } + evses { id stationId evseId evseTypeId physicalReference removed createdAt updatedAt } latestStatusNotifications { id stationId statusNotificationId updatedAt createdAt statusNotification { connectorId connectorStatus createdAt evseId id stationId timestamp updatedAt } } transactions(where: {isActive: {_eq: true}}) { id stationId timeSpentCharging isActive chargingState stoppedReason transactionId evseId remoteStartId totalKwh createdAt updatedAt } connectors { id stationId evseId connectorId status type maximumPowerWatts maximumAmperage maximumVoltage format powerType termsAndConditionsUrl tariffId errorCode timestamp info vendorId vendorErrorCode createdAt updatedAt } diff --git a/tools/citrineos-core-main/apps/operator-ui/src/lib/client/pages/charging-stations/detail/charging.station.detail.tabs.card.tsx b/tools/citrineos-core-main/apps/operator-ui/src/lib/client/pages/charging-stations/detail/charging.station.detail.tabs.card.tsx index c6f67e7..edec3c6 100644 --- a/tools/citrineos-core-main/apps/operator-ui/src/lib/client/pages/charging-stations/detail/charging.station.detail.tabs.card.tsx +++ b/tools/citrineos-core-main/apps/operator-ui/src/lib/client/pages/charging-stations/detail/charging.station.detail.tabs.card.tsx @@ -35,7 +35,7 @@ enum ChargingStationDetailTabType { aggregated = 'aggregated', } -export const ChargingStationDetailTabsCard = ({ id }: { id: number }) => { +export const ChargingStationDetailTabsCard = ({ id }: { id: string }) => { const translate = useTranslate(); const { renderedVisibleColumns } = useColumnPreferences( diff --git a/tools/citrineos-core-main/apps/operator-ui/src/lib/client/pages/charging-stations/detail/evses/evses.list.tsx b/tools/citrineos-core-main/apps/operator-ui/src/lib/client/pages/charging-stations/detail/evses/evses.list.tsx index 7aeb042..bf3c8c7 100644 --- a/tools/citrineos-core-main/apps/operator-ui/src/lib/client/pages/charging-stations/detail/evses/evses.list.tsx +++ b/tools/citrineos-core-main/apps/operator-ui/src/lib/client/pages/charging-stations/detail/evses/evses.list.tsx @@ -21,7 +21,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useDispatch } from 'react-redux'; interface EVSESListProps { - id: number; + id: string; } export const evsesFormUpsertGrid = 'grid grid-cols-2 xs:grid-cols-1 gap-6'; @@ -45,8 +45,15 @@ export const EVSESList: React.FC = ({ id }) => { }); const station = React.useMemo(() => { - const station = { ...data?.data } as ChargingStationDto; - return station; + const raw = data?.data; + if (!raw) return undefined; + // GraphQL response wraps in { ChargingStations: [...] }, extract first item + const stations = (raw as any).ChargingStations; + if (Array.isArray(stations) && stations.length > 0) { + return stations[0] as ChargingStationDto; + } + // Fallback: data might already be the station object + return { ...raw } as ChargingStationDto; }, [data?.data]); const openModal = useCallback( @@ -128,7 +135,6 @@ export const EVSESList: React.FC = ({ id }) => { ); diff --git a/tools/citrineos-core-main/apps/operator-ui/src/lib/client/pages/charging-stations/detail/evses/evses.upsert.tsx b/tools/citrineos-core-main/apps/operator-ui/src/lib/client/pages/charging-stations/detail/evses/evses.upsert.tsx index 6322608..6ad8f11 100644 --- a/tools/citrineos-core-main/apps/operator-ui/src/lib/client/pages/charging-stations/detail/evses/evses.upsert.tsx +++ b/tools/citrineos-core-main/apps/operator-ui/src/lib/client/pages/charging-stations/detail/evses/evses.upsert.tsx @@ -19,15 +19,13 @@ import { useTenantId } from '@lib/client/hooks/useTenantId'; interface EvseUpsertProps { onSubmit: () => void; - stationId: number; - ocppConnectionName?: string; + stationId: string; evse: EvseDto | null; } export const EvseUpsert: React.FC = ({ onSubmit, stationId, - ocppConnectionName, evse, }) => { const tenantId = useTenantId(); @@ -74,8 +72,7 @@ export const EvseUpsert: React.FC = ({ } newItem.updatedAt = now; - newItem.stationId = stationId; - newItem.ocppConnectionName = ocppConnectionName ?? evse?.ocppConnectionName; + newItem.stationId = String(stationId); form.refineCore.onFinish(newItem).then(() => reset()); }; diff --git a/tools/citrineos-core-main/apps/operator-ui/src/lib/cls/evse.dto.tsx b/tools/citrineos-core-main/apps/operator-ui/src/lib/cls/evse.dto.tsx index f7993e9..cdc4343 100644 --- a/tools/citrineos-core-main/apps/operator-ui/src/lib/cls/evse.dto.tsx +++ b/tools/citrineos-core-main/apps/operator-ui/src/lib/cls/evse.dto.tsx @@ -6,7 +6,6 @@ import type { ChargingStationDto, ConnectorDto, EvseDto } from '@citrineos/base' export class EvseClass implements Partial { id?: number; - ocppConnectionName!: string; evseTypeId?: number; evseId!: string; physicalReference?: string | null; diff --git a/tools/citrineos-core-main/apps/operator-ui/src/lib/queries/evses.ts b/tools/citrineos-core-main/apps/operator-ui/src/lib/queries/evses.ts index 98c7377..18d0ab0 100644 --- a/tools/citrineos-core-main/apps/operator-ui/src/lib/queries/evses.ts +++ b/tools/citrineos-core-main/apps/operator-ui/src/lib/queries/evses.ts @@ -32,7 +32,7 @@ export const EVSE_LIST_QUERY = gql` export const GET_EVSE_LIST_FOR_STATION = gql` query GetPaginatedEvseListForStation( - $stationId: Int! + $stationId: String! $where: Evses_bool_exp = {} $order_by: [Evses_order_by!] = {} $offset: Int @@ -76,7 +76,7 @@ export const GET_EVSE_LIST_FOR_STATION = gql` `; export const GET_EVSES_FOR_STATION = gql` - query GetEvseListForStation($stationId: Int!) { + query GetEvseListForStation($stationId: String!) { Evses(where: { stationId: { _eq: $stationId } }) { id ocppConnectionName