From 45840905af9c8977efc5b7e049baec2266090547 Mon Sep 17 00:00:00 2001 From: Mathias Oppedal Heggelund <98742460+mheggelund@users.noreply.github.com> Date: Wed, 31 Jan 2024 09:54:19 +0100 Subject: [PATCH] Refactor/object results (#215) * refactor: Split result tab into Variogram and Object results. * refactor: Adapted Object case result table and view. * fix: remove logging for debugging. * refactor: Adjust responsiveness to screen width. * refactor: Moved fetch results into own hook. Add variogramResult component. * refactor: Refactor VariogramResult component to match data structure. * fix: typo in filename. --- src/features/AppBar/AppBar.tsx | 4 +- .../ModelNavigationBar/ModelNavigationBar.tsx | 101 ++++++++++++------ .../CaseResultView/CaseResultView.styled.tsx | 16 ++- .../CaseResultView/CaseResultView.tsx | 54 ++++++---- .../ObjectCaseResult/ChannelResult.styled.ts | 21 ++++ .../ObjectCaseResult/ChannelResult.tsx | 37 +++++++ .../ChannelResultTable.styled.tsx | 5 +- .../ObjectCaseResult/ChannelResultTable.tsx | 94 ++++++---------- .../VariogramCaseResult.tsx | 53 +++------ .../VariogramResultTable.tsx | 51 +++++++++ src/features/Results/NoResults/NoResults.tsx | 4 +- src/hooks/useFetchResults.ts | 21 ++++ .../Results/ObjectResult/ObjectResult.tsx | 24 +++++ src/pages/ModelPages/Results/Results.tsx | 56 ---------- .../VariogramResults/VariogramResults.tsx | 27 +++++ src/router.tsx | 15 ++- 16 files changed, 359 insertions(+), 224 deletions(-) create mode 100644 src/features/Results/CaseResult/CaseResultView/ObjectCaseResult/ChannelResult.styled.ts create mode 100644 src/features/Results/CaseResult/CaseResultView/ObjectCaseResult/ChannelResult.tsx create mode 100644 src/features/Results/CaseResult/CaseResultView/VariogramCaseResult/VariogramResultTable.tsx create mode 100644 src/hooks/useFetchResults.ts create mode 100644 src/pages/ModelPages/Results/ObjectResult/ObjectResult.tsx delete mode 100644 src/pages/ModelPages/Results/Results.tsx create mode 100644 src/pages/ModelPages/Results/VariogramResults/VariogramResults.tsx diff --git a/src/features/AppBar/AppBar.tsx b/src/features/AppBar/AppBar.tsx index 5d7e34b3..96ff67f5 100644 --- a/src/features/AppBar/AppBar.tsx +++ b/src/features/AppBar/AppBar.tsx @@ -1,13 +1,11 @@ import { TopBar } from '@equinor/eds-core-react'; -import { useLocation, useNavigate } from 'react-router-dom'; +import { useNavigate } from 'react-router-dom'; import * as Styled from './AppBar.styled'; import { Icons } from './Icons/Icons'; import { Navigation } from './Navigation/Navigation'; const AppBar = ({ title }: { title: string }) => { const navigate = useNavigate(); - const location = useLocation(); - console.log(location.pathname); return ( diff --git a/src/features/ModelView/ModelNavigationBar/ModelNavigationBar.tsx b/src/features/ModelView/ModelNavigationBar/ModelNavigationBar.tsx index 6fc35c1e..ca32d5a1 100644 --- a/src/features/ModelView/ModelNavigationBar/ModelNavigationBar.tsx +++ b/src/features/ModelView/ModelNavigationBar/ModelNavigationBar.tsx @@ -1,10 +1,9 @@ /* eslint-disable max-lines-per-function */ import { SideBar, SidebarLinkProps } from '@equinor/eds-core-react'; import { + approve as APPROVE, + format_list_bulleted as FORMATLISTBULLET, IconData, - // eslint-disable-next-line sort-imports - approve, - format_list_bulleted as formatListBullet, settings, } from '@equinor/eds-icons'; import { useLocation, useNavigate } from 'react-router-dom'; @@ -27,20 +26,12 @@ export const ModelNavigationBar = () => { const path = tab[tab.length - 1]; const path2 = tab[tab.length - 2]; - const menuItems: SidebarLinkProps[] = [ - { - label: 'Details', - icon: formatListBullet, - href: 'details', - active: false, - }, - { - label: 'Results', - icon: approve, - href: 'results', - active: false, - }, - ]; + const menuItems: SidebarLinkProps = { + label: 'Details', + icon: FORMATLISTBULLET, + href: 'details', + active: false, + }; const sidebarCompute: MenuItems = { label: 'Compute', @@ -50,26 +41,46 @@ export const ModelNavigationBar = () => { { label: 'Variogram', name: 'variogram', - href: 'variogram', + href: 'compute/variogram', icon: settings, }, { label: 'Object', name: 'object', - href: 'object', + href: 'compute/object', icon: settings, }, ], }; + const sidebarResults: MenuItems = { + label: 'Results', + href: '', + icon: APPROVE, + subItems: [ + { + label: 'Variogram', + name: 'variogram', + href: 'results/variogram', + icon: APPROVE, + }, + { + label: 'Object', + name: 'object', + href: 'results/object', + icon: APPROVE, + }, + ], + }; + return ( { navigate('details'); }} @@ -77,21 +88,29 @@ export const ModelNavigationBar = () => { { - navigate('variogram'); + navigate('compute/variogram'); }} > {sidebarCompute.subItems?.map((item) => ( { navigate(`${item.href}`); }} @@ -100,16 +119,32 @@ export const ModelNavigationBar = () => { { - navigate('results'); + navigate('results/variogram'); }} > + {sidebarResults.subItems?.map((item) => ( + { + navigate(`${item.href}`); + }} + > + ))} ); diff --git a/src/features/Results/CaseResult/CaseResultView/CaseResultView.styled.tsx b/src/features/Results/CaseResult/CaseResultView/CaseResultView.styled.tsx index 0751c052..a168b607 100644 --- a/src/features/Results/CaseResult/CaseResultView/CaseResultView.styled.tsx +++ b/src/features/Results/CaseResult/CaseResultView/CaseResultView.styled.tsx @@ -1,3 +1,4 @@ +import { Divider } from '@equinor/eds-core-react'; import styled from 'styled-components'; import { spacings } from '../../../../tokens/spacings'; @@ -8,12 +9,23 @@ export const CaseResultView = styled.div` row-gap: ${spacings.XXX_LARGE}; padding: ${spacings.LARGE}; - width: 75vw; + @media (min-width: 1400px) { + width: 80%; + } `; export const CaseResultList = styled.div` display: flex; flex-direction: column; - row-gap: ${spacings.XXX_LARGE}; + width: 100%; +`; + +export const StyledDivider = styled(Divider)` + margin: ${spacings.MEDIUM} 0; + max-width: 1108px; +`; + +export const Wrapper = styled.div` + width: 100%; `; diff --git a/src/features/Results/CaseResult/CaseResultView/CaseResultView.tsx b/src/features/Results/CaseResult/CaseResultView/CaseResultView.tsx index e00d46e6..f7944e35 100644 --- a/src/features/Results/CaseResult/CaseResultView/CaseResultView.tsx +++ b/src/features/Results/CaseResult/CaseResultView/CaseResultView.tsx @@ -2,38 +2,50 @@ import * as Styled from './CaseResultView.styled'; import { Typography } from '@equinor/eds-core-react'; import { ComputeCaseDto, GetResultDto } from '../../../../api/generated'; -import { ChannelResultTable } from './ObjectCaseResult/ChannelResultTable'; +import { ChannelResult } from './ObjectCaseResult/ChannelResult'; import { VariogramCaseResult } from './VariogramCaseResult/VariogramCaseResult'; import ResultIMG from './vargrest_output-0-_variogram_slices_.png'; export const CaseResultView = ({ - objectList, + resultList, computeCases, }: { - objectList?: GetResultDto[]; + resultList: GetResultDto[]; computeCases?: ComputeCaseDto[]; }) => { + const caseType = resultList[0].resultType; + return ( - Compute results + {caseType} results - - {objectList && - objectList.map((obj) => ( - 0 - ? computeCases.filter( - (c) => c.computeCaseId === obj.computeCaseId, - ) - : [] - } - > + {caseType === 'Variogram' && ( + + )} + + {caseType === 'Object' && + resultList.map((obj, index) => ( + + 0 + ? computeCases.filter( + (c) => c.computeCaseId === obj.computeCaseId, + ) + : [] + } + > + {index < resultList.length - 1 && ( + + )} + ))} diff --git a/src/features/Results/CaseResult/CaseResultView/ObjectCaseResult/ChannelResult.styled.ts b/src/features/Results/CaseResult/CaseResultView/ObjectCaseResult/ChannelResult.styled.ts new file mode 100644 index 00000000..a1542254 --- /dev/null +++ b/src/features/Results/CaseResult/CaseResultView/ObjectCaseResult/ChannelResult.styled.ts @@ -0,0 +1,21 @@ +import styled from 'styled-components'; +import { spacings } from '../../../../../tokens/spacings'; + +export const Wrapper = styled.div` + display: flex; + flex-direction: column; +`; + +export const InnerWrapper = styled.div` + display: flex; + flex-direction: row; + column-gap: ${spacings.SMALL}; + width: 100%; +`; + +export const Info = styled.div` + display: flex; + flex-direction: column; + + width: 150px; +`; diff --git a/src/features/Results/CaseResult/CaseResultView/ObjectCaseResult/ChannelResult.tsx b/src/features/Results/CaseResult/CaseResultView/ObjectCaseResult/ChannelResult.tsx new file mode 100644 index 00000000..a2631c69 --- /dev/null +++ b/src/features/Results/CaseResult/CaseResultView/ObjectCaseResult/ChannelResult.tsx @@ -0,0 +1,37 @@ +import { Typography } from '@equinor/eds-core-react'; +import { ComputeCaseDto, GetResultDto } from '../../../../../api/generated'; +import * as Styled from './ChannelResult.styled'; +import { ChannelResultTable } from './ChannelResultTable'; + +export const ChannelResult = ({ + data, + computeCase, +}: { + data: GetResultDto; + computeCase?: ComputeCaseDto[]; +}) => { + let modelArea = ''; + if ( + computeCase && + computeCase[0] && + computeCase[0].modelArea !== undefined && + computeCase[0].modelArea !== null + ) + modelArea = computeCase && computeCase[0].modelArea.name; + + if (modelArea === '') modelArea = 'Whole model'; + const caseFilter = computeCase && computeCase[0]; + const computeMethod = caseFilter && caseFilter.computeMethod.name; + + return ( + + + + {computeMethod} + {modelArea} + + + + + ); +}; diff --git a/src/features/Results/CaseResult/CaseResultView/ObjectCaseResult/ChannelResultTable.styled.tsx b/src/features/Results/CaseResult/CaseResultView/ObjectCaseResult/ChannelResultTable.styled.tsx index c5d7c4a0..c9f38bb0 100644 --- a/src/features/Results/CaseResult/CaseResultView/ObjectCaseResult/ChannelResultTable.styled.tsx +++ b/src/features/Results/CaseResult/CaseResultView/ObjectCaseResult/ChannelResultTable.styled.tsx @@ -3,7 +3,8 @@ import { Table } from '@equinor/eds-core-react'; import styled from 'styled-components'; import { theme } from '../../../../../tokens/theme'; -export const Wrapper = styled.div` +const StyledTable = styled(Table)` + width: 100%; max-width: 950px; `; export const ColumnCell = styled(Table.Cell)` @@ -20,3 +21,5 @@ export const DataCell = styled(Table.Cell)` justify-content: right; } `; + +export { StyledTable as Table }; diff --git a/src/features/Results/CaseResult/CaseResultView/ObjectCaseResult/ChannelResultTable.tsx b/src/features/Results/CaseResult/CaseResultView/ObjectCaseResult/ChannelResultTable.tsx index dd47335c..a411a73e 100644 --- a/src/features/Results/CaseResult/CaseResultView/ObjectCaseResult/ChannelResultTable.tsx +++ b/src/features/Results/CaseResult/CaseResultView/ObjectCaseResult/ChannelResultTable.tsx @@ -1,34 +1,16 @@ /* eslint-disable max-lines-per-function */ import { Table } from '@equinor/eds-core-react'; -import { CaseCardComponent } from '../../../../../components/CaseCardComponent/CaseCardComponent'; -import { ComputeCaseDto, GetResultDto } from '../../../../../api/generated'; +import { GetResultDto } from '../../../../../api/generated'; import * as Styled from './ChannelResultTable.styled'; const NumberOfDecimals = 2; -export const ChannelResultTable = ({ - data, - computeCase, -}: { - data: GetResultDto; - computeCase?: ComputeCaseDto[]; -}) => { +export const ChannelResultTable = ({ data }: { data: GetResultDto }) => { const filterValues = (name: string) => { return data.resultValues.filter((d) => d.name === name); }; - let modelArea = ''; - if ( - computeCase && - computeCase[0] && - computeCase[0].modelArea !== undefined && - computeCase[0].modelArea !== null - ) - modelArea = computeCase && computeCase[0].modelArea.name; - - if (modelArea === '') modelArea = 'Whole model'; - const roundResultString = (value: string) => { return parseFloat(value).toFixed(NumberOfDecimals); }; @@ -42,45 +24,37 @@ export const ChannelResultTable = ({ const channelWidthSD = filterValues('channel-width_sd'); return ( - - - - - - - Mean - Standard deviation (SD) - Count - - - - - Channel width - - {roundResultString(channelWidthMean[0].value)} - - - {roundResultString(channelWidthSD[0].value)} - - {channelWidthCount[0].value} - - - Channel height - - {roundResultString(channelHeightMean[0].value)} - - - {roundResultString(channelHeightSD[0].value)} - - {channelHeightCount[0].value} - - -
-
-
+ + + + + Mean + Standard deviation (SD) + Count + + + + + Channel width + + {roundResultString(channelWidthMean[0].value)} + + + {roundResultString(channelWidthSD[0].value)} + + {channelWidthCount[0].value} + + + Channel height + + {roundResultString(channelHeightMean[0].value)} + + + {roundResultString(channelHeightSD[0].value)} + + {channelHeightCount[0].value} + + + ); }; diff --git a/src/features/Results/CaseResult/CaseResultView/VariogramCaseResult/VariogramCaseResult.tsx b/src/features/Results/CaseResult/CaseResultView/VariogramCaseResult/VariogramCaseResult.tsx index 1799f685..7e09fd8b 100644 --- a/src/features/Results/CaseResult/CaseResultView/VariogramCaseResult/VariogramCaseResult.tsx +++ b/src/features/Results/CaseResult/CaseResultView/VariogramCaseResult/VariogramCaseResult.tsx @@ -1,55 +1,26 @@ -import { Table } from '@equinor/eds-core-react'; +import { GetResultDto } from '../../../../../api/generated'; import { CaseCardComponent } from '../../../../../components/CaseCardComponent/CaseCardComponent'; import { ImageView } from '../../../../../components/ImageView/ImageView'; -import { VariogramResultListType } from '../../../../../pages/ModelPages/Results/Results'; import * as Styled from './VariogramCaseResult.styled'; +import { VariogramResultTable } from './VariogramResultTable'; export const VariogramCaseResult = ({ - caseList, + resultList, img, }: { - caseList: VariogramResultListType[]; + resultList: GetResultDto[]; img: string; }) => { return ( <> - {caseList.map((caseItem) => ( - - {caseItem.resultList.map((item) => ( - - - - - - - Quality factor - {item.quality} - - - Model area - {item.modelArea} - - - Compute method - {item.computeMethod} - - - Attribute - {item.attribute} - - - Variogram model - {item.family} - - - Sigma - {item.sigma} - - -
-
-
- ))} + {resultList.map((item) => ( + + + + + + + ))} diff --git a/src/features/Results/CaseResult/CaseResultView/VariogramCaseResult/VariogramResultTable.tsx b/src/features/Results/CaseResult/CaseResultView/VariogramCaseResult/VariogramResultTable.tsx new file mode 100644 index 00000000..fee64d25 --- /dev/null +++ b/src/features/Results/CaseResult/CaseResultView/VariogramCaseResult/VariogramResultTable.tsx @@ -0,0 +1,51 @@ +/* eslint-disable max-lines-per-function */ +import { Table } from '@equinor/eds-core-react'; + +import { GetResultDto } from '../../../../../api/generated'; + +// const NumberOfDecimals = 2; + +export const VariogramResultTable = ({ data }: { data: GetResultDto }) => { + // const filterValues = (name: string) => { + // return data.resultValues.filter((d) => d.name === name); + // }; + + // const roundResultString = (value: string) => { + // return parseFloat(value).toFixed(NumberOfDecimals); + // }; + + // const channelHeightCount = filterValues('channel-height_count'); + // const channelHeightMean = filterValues('channel-height_mean'); + // const channelHeightSD = filterValues('channel-height_sd'); + + return ( + + + + Quality factor + --Data-- + + + Model area + --Data-- + + + Compute method + --Data-- + + + Attribute + --Data-- + + + Variogram model + --Data-- + + + Sigma + --Data-- + + +
+ ); +}; diff --git a/src/features/Results/NoResults/NoResults.tsx b/src/features/Results/NoResults/NoResults.tsx index 610337ff..8d4f8040 100644 --- a/src/features/Results/NoResults/NoResults.tsx +++ b/src/features/Results/NoResults/NoResults.tsx @@ -13,12 +13,12 @@ export const NoResults = () => { To get started, try adding cases to the   - + variogram   or   - + object   page. diff --git a/src/hooks/useFetchResults.ts b/src/hooks/useFetchResults.ts new file mode 100644 index 00000000..165c01e9 --- /dev/null +++ b/src/hooks/useFetchResults.ts @@ -0,0 +1,21 @@ +import { useQuery } from '@tanstack/react-query'; +import { AnalogueModelsService } from '../api/generated/services/AnalogueModelsService'; + +import { useMsal } from '@azure/msal-react'; +import { useParams } from 'react-router-dom'; +import { useAccessToken } from './useAccessToken'; + +export const useFetchResults = () => { + const { modelId } = useParams(); + const { instance, accounts } = useMsal(); + const token = useAccessToken(instance, accounts[0]); + + const query = useQuery({ + queryKey: ['model-results', modelId], + queryFn: () => + AnalogueModelsService.getApiAnalogueModelsResults(modelId as string), + enabled: !!token, + }); + + return query; +}; diff --git a/src/pages/ModelPages/Results/ObjectResult/ObjectResult.tsx b/src/pages/ModelPages/Results/ObjectResult/ObjectResult.tsx new file mode 100644 index 00000000..a37218e2 --- /dev/null +++ b/src/pages/ModelPages/Results/ObjectResult/ObjectResult.tsx @@ -0,0 +1,24 @@ +/* eslint-disable max-lines-per-function */ +import { CaseResultView } from '../../../../features/Results/CaseResult/CaseResultView/CaseResultView'; +import { NoResults } from '../../../../features/Results/NoResults/NoResults'; +import { useFetchCases } from '../../../../hooks/useFetchCases'; +import { useFetchResults } from '../../../../hooks/useFetchResults'; + +export const ObjectResult = () => { + const cases = useFetchCases(); + const { data } = useFetchResults(); + const objectResults = data?.filter((res) => res.resultType === 'Object'); + + return ( + <> + {objectResults !== undefined && objectResults?.length > 0 ? ( + + ) : ( + + )} + + ); +}; diff --git a/src/pages/ModelPages/Results/Results.tsx b/src/pages/ModelPages/Results/Results.tsx deleted file mode 100644 index ed955e59..00000000 --- a/src/pages/ModelPages/Results/Results.tsx +++ /dev/null @@ -1,56 +0,0 @@ -/* eslint-disable max-lines-per-function */ -import { useMsal } from '@azure/msal-react'; -import { useQuery } from '@tanstack/react-query'; -import { useParams } from 'react-router-dom'; -import { AnalogueModelsService } from '../../../api/generated'; -import { CaseResultView } from '../../../features/Results/CaseResult/CaseResultView/CaseResultView'; -import { NoResults } from '../../../features/Results/NoResults/NoResults'; -import { useAccessToken } from '../../../hooks/useAccessToken'; -import { useFetchCases } from '../../../hooks/useFetchCases'; - -export interface VariogramResultListType { - caseId: number; - title: string; - resultList: VariogramResultType[]; -} - -export interface VariogramResultType { - identifier: number; - family: string; - computeMethod: string; - modelArea: string; - attribute: string; - quality: GLfloat; - sigma: GLfloat; - approved: string; -} - -export const Results = () => { - const { modelId } = useParams<{ modelId: string }>(); - const { instance, accounts } = useMsal(); - const token = useAccessToken(instance, accounts[0]); - - const { data } = useQuery({ - queryKey: ['model-results', modelId], - queryFn: () => - AnalogueModelsService.getApiAnalogueModelsResults(modelId as string), - enabled: !!token, - }); - - const cases = useFetchCases(); - - const objectResults = data?.filter((res) => res.resultType === 'Object'); - - return ( - <> - {objectResults !== undefined && objectResults?.length > 0 ? ( - - ) : ( - - )} - - ); -}; diff --git a/src/pages/ModelPages/Results/VariogramResults/VariogramResults.tsx b/src/pages/ModelPages/Results/VariogramResults/VariogramResults.tsx new file mode 100644 index 00000000..da9f7c96 --- /dev/null +++ b/src/pages/ModelPages/Results/VariogramResults/VariogramResults.tsx @@ -0,0 +1,27 @@ +/* eslint-disable max-lines-per-function */ +import { CaseResultView } from '../../../../features/Results/CaseResult/CaseResultView/CaseResultView'; +import { NoResults } from '../../../../features/Results/NoResults/NoResults'; +import { useFetchCases } from '../../../../hooks/useFetchCases'; +import { useFetchResults } from '../../../../hooks/useFetchResults'; + +export const VariogramResults = () => { + const { data } = useFetchResults(); + const cases = useFetchCases(); + + const variogramResults = data?.filter( + (res) => res.resultType === 'Variogram', + ); + + return ( + <> + {variogramResults !== undefined && variogramResults?.length > 0 ? ( + + ) : ( + + )} + + ); +}; diff --git a/src/router.tsx b/src/router.tsx index 03a49b56..5eeffc0b 100644 --- a/src/router.tsx +++ b/src/router.tsx @@ -8,7 +8,8 @@ import { InvalidURL } from './pages/InvalidURL/InvalidURL'; import { ComputeObject } from './pages/ModelPages/Compute/ComputeObject/ComputeObject'; import { ComputeVariogram } from './pages/ModelPages/Compute/ComputeVariogram/ComputeVariogram'; import { Model } from './pages/ModelPages/Model/Model'; -import { Results } from './pages/ModelPages/Results/Results'; +import { ObjectResult } from './pages/ModelPages/Results/ObjectResult/ObjectResult'; +import { VariogramResults } from './pages/ModelPages/Results/VariogramResults/VariogramResults'; interface Tab extends Required> { title: string; @@ -43,17 +44,21 @@ const appRoutes = [ }, { - path: 'variogram', + path: 'compute/variogram', element: , }, { - path: 'object', + path: 'compute/object', element: , }, { - path: 'results', - element: , + path: 'results/variogram', + element: , + }, + { + path: 'results/object', + element: , }, ], },