11import { Button , ButtonGroup , Chip , Table , Typography } from '@equinor/eds-core-react'
22import { Mission , MissionStatus } from 'models/Mission'
33import { useContext , useEffect , useState } from 'react'
4+ import styled from 'styled-components'
5+ import { tokens } from '@equinor/eds-tokens'
46import { useLanguageContext } from 'components/Contexts/LanguageContext'
57import { StyledCardsWidth , StyledPage , StyledTable , StyledTableAndMap } from 'components/Styles/StyledComponents'
68import { SignalREventLabels , useSignalRContext } from 'components/Contexts/SignalRContext'
@@ -11,6 +13,26 @@ import { formatDateTime } from 'utils/StringFormatting'
1113import { TimeseriesLinePlot , TimeseriesLinePlotData } from 'components/Displays/TimeseriesLinePlot'
1214import { DescriptionDisplay , TagIdDisplay } from 'components/Displays/TaskDisplay'
1315import { PlantMap } from 'pages/MissionPage/MapPosition/PointillaMapView'
16+ import { StyledImagesSection } from 'pages/InspectionReportPage/InspectionStyles'
17+ import { InspectionImageWithPlaceholder } from 'pages/InspectionReportPage/InspectionReportImage'
18+ import { AnalysisResultDialogContent } from 'pages/MissionPage/AnalysisResultView'
19+
20+ const CloeMapWrapper = styled . div `
21+ .leaflet-tooltip.circleLabel {
22+ background-color: ${ tokens . colors . ui . background__medium . hex } !important;
23+ padding: 0 4px !important;
24+ border-radius: 2px !important;
25+ }
26+ `
27+ const StyledTopAlignedImagesSection = styled ( StyledImagesSection ) `
28+ align-items: flex-start;
29+ `
30+ const StyledCloeImageCard = styled . div `
31+ display: flex;
32+ flex-direction: column;
33+ gap: 8px;
34+ max-width: 480px;
35+ `
1436
1537enum TimeRange {
1638 SevenDays = '7days' ,
@@ -29,7 +51,15 @@ const checkIfAnalysableDescription = (description: string) => {
2951 return Object . values ( CloeAnalysableDescriptions ) . includes ( description as CloeAnalysableDescriptions )
3052}
3153
32- const CloeDataTable = ( { tasks } : { tasks : Task [ ] } ) => {
54+ const CloeDataTable = ( {
55+ tasks,
56+ selectedTagId,
57+ onSelectTag,
58+ } : {
59+ tasks : Task [ ]
60+ selectedTagId : string | null
61+ onSelectTag : ( tagId : string | null ) => void
62+ } ) => {
3363 const { TranslateText } = useLanguageContext ( )
3464
3565 return (
@@ -45,37 +75,52 @@ const CloeDataTable = ({ tasks }: { tasks: Task[] }) => {
4575 </ Table . Head >
4676 < Table . Body >
4777 { tasks &&
48- tasks . map ( ( task , index ) => (
49- < Table . Row key = { task . id } >
50- < Table . Cell >
51- < Chip >
52- < Typography variant = "body_short_bold" > { index + 1 } </ Typography >
53- </ Chip >
54- </ Table . Cell >
55- < Table . Cell >
56- < TagIdDisplay task = { task } />
57- </ Table . Cell >
58- < Table . Cell >
59- < DescriptionDisplay task = { task } />
60- </ Table . Cell >
61- { task . inspection . analysisResult ?. value ? (
78+ tasks . map ( ( task , index ) => {
79+ const isSelected = ! ! task . tagId && task . tagId === selectedTagId
80+ return (
81+ < Table . Row
82+ key = { task . id }
83+ onClick = { ( ) => {
84+ if ( ! task . tagId ) return
85+ onSelectTag ( isSelected ? null : task . tagId )
86+ } }
87+ style = { {
88+ cursor : task . tagId ? 'pointer' : 'default' ,
89+ backgroundColor : isSelected
90+ ? tokens . colors . interactive . primary__selected_highlight . rgba
91+ : undefined ,
92+ } }
93+ >
6294 < Table . Cell >
63- < Typography >
64- { Math . round ( parseFloat ( task . inspection . analysisResult ?. value ) ) + '%' }
65- </ Typography >
95+ < Chip >
96+ < Typography variant = "body_short_bold" > { index + 1 } </ Typography >
97+ </ Chip >
6698 </ Table . Cell >
67- ) : (
6899 < Table . Cell >
69- < Typography > { TranslateText ( 'Analysis result not available' ) } </ Typography >
100+ < TagIdDisplay task = { task } / >
70101 </ Table . Cell >
71- ) }
72- { task . endTime && (
73102 < Table . Cell >
74- < Typography > { formatDateTime ( task . endTime , 'dd.MM.yy - HH:mm' ) } </ Typography >
103+ < DescriptionDisplay task = { task } / >
75104 </ Table . Cell >
76- ) }
77- </ Table . Row >
78- ) ) }
105+ { task . inspection . analysisResult ?. value ? (
106+ < Table . Cell >
107+ < Typography >
108+ { Math . round ( parseFloat ( task . inspection . analysisResult ?. value ) ) + '%' }
109+ </ Typography >
110+ </ Table . Cell >
111+ ) : (
112+ < Table . Cell >
113+ < Typography > { TranslateText ( 'Analysis result not available' ) } </ Typography >
114+ </ Table . Cell >
115+ ) }
116+ { task . endTime && (
117+ < Table . Cell >
118+ < Typography > { formatDateTime ( task . endTime , 'dd.MM.yy - HH:mm' ) } </ Typography >
119+ </ Table . Cell >
120+ ) }
121+ </ Table . Row >
122+ )
123+ } ) }
79124 </ Table . Body >
80125 </ StyledTable >
81126 )
@@ -87,6 +132,7 @@ export const CloeDataViewPage = () => {
87132 const { registerEvent, connectionReady } = useSignalRContext ( )
88133 const [ cloeMissions , setCloeMissions ] = useState < Mission [ ] > ( [ ] )
89134 const [ timeRange , setTimeRange ] = useState < TimeRange > ( TimeRange . OneMonth )
135+ const [ selectedTagId , setSelectedTagId ] = useState < string | null > ( null )
90136 const backendApi = useBackendApi ( )
91137
92138 const fetchMissions = ( ) : Promise < Mission [ ] > => {
@@ -160,6 +206,7 @@ export const CloeDataViewPage = () => {
160206 ? new Date ( ( task . endTime ?? task . startTime ) as unknown as string )
161207 : missionTimestamp
162208 if ( ! tagId || ! rawFillLevel || ! sampleTimestamp ) return
209+ if ( selectedTagId && tagId !== selectedTagId ) return
163210 if ( ! Object . hasOwn ( accumulatedData , tagId ) ) {
164211 accumulatedData [ tagId ] = [ ]
165212 }
@@ -170,16 +217,59 @@ export const CloeDataViewPage = () => {
170217 { } as TimeseriesLinePlotData
171218 )
172219
220+ const mapMission = ( ( ) => {
221+ if ( ! latestCloeMission ) return undefined
222+ if ( ! selectedTagId ) return latestCloeMission
223+ const selectedIndex = latestCloeMission . tasks . findIndex ( ( t ) => t . tagId === selectedTagId )
224+ if ( selectedIndex < 0 ) return latestCloeMission
225+ const selectedTask = latestCloeMission . tasks [ selectedIndex ]
226+ const paddedTasks : Task [ ] = Array . from ( { length : selectedIndex + 1 } , ( _ , i ) => ( {
227+ ...selectedTask ,
228+ id : `${ selectedTask . id } __pad_${ i } ` ,
229+ } ) )
230+ paddedTasks [ selectedIndex ] = selectedTask
231+ return { ...latestCloeMission , tasks : paddedTasks }
232+ } ) ( )
233+
234+ const selectedTask = selectedTagId ? latestCloeMission ?. tasks . find ( ( t ) => t . tagId === selectedTagId ) : undefined
235+
173236 return (
174237 < StyledPage >
175238 < StyledCardsWidth >
176239 < Typography variant = "h2" > { TranslateText ( 'Data View for Constant Level Oilers' ) } </ Typography >
177240 < StyledTableAndMap >
178- { latestCloeMission && < CloeDataTable tasks = { latestCloeMission . tasks } /> }
179- { plantCode && latestCloeMission && (
180- < PlantMap plantCode = { plantCode } floorId = "0" mission = { latestCloeMission } />
241+ { latestCloeMission && (
242+ < CloeDataTable
243+ tasks = { latestCloeMission . tasks }
244+ selectedTagId = { selectedTagId }
245+ onSelectTag = { setSelectedTagId }
246+ />
247+ ) }
248+ { plantCode && mapMission && (
249+ < CloeMapWrapper >
250+ < PlantMap
251+ key = { selectedTagId ?? 'all' }
252+ plantCode = { plantCode }
253+ floorId = "0"
254+ mission = { mapMission }
255+ />
256+ </ CloeMapWrapper >
181257 ) }
182258 </ StyledTableAndMap >
259+ { selectedTask && selectedTask . inspection . isarInspectionId && (
260+ < StyledTopAlignedImagesSection >
261+ < StyledCloeImageCard >
262+ < Typography variant = "h4" > { TranslateText ( 'Latest inspection' ) } </ Typography >
263+ < InspectionImageWithPlaceholder task = { selectedTask } isLargeImage = { true } />
264+ </ StyledCloeImageCard >
265+ { selectedTask . inspection . analysisResult ?. storageAccount && (
266+ < StyledCloeImageCard >
267+ < Typography variant = "h4" > { TranslateText ( 'Latest analysis result' ) } </ Typography >
268+ < AnalysisResultDialogContent currentTask = { selectedTask } />
269+ </ StyledCloeImageCard >
270+ ) }
271+ </ StyledTopAlignedImagesSection >
272+ ) }
183273 { cloeMissions . length > 0 && (
184274 < >
185275 < Typography variant = "h4" > { TranslateText ( 'Measured oil level' ) } </ Typography >
0 commit comments