Skip to content

Commit 0018bd7

Browse files
Refactor to reuse the phase model setup
1 parent d61e14f commit 0018bd7

6 files changed

Lines changed: 65 additions & 67 deletions

File tree

frontend/src/components/GridSimulation/CompareGridSimulations.tsx

Lines changed: 9 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, { useMemo, useState } from "react";
22
import { useQueries } from "@tanstack/react-query";
3-
import { Accordion, CircularProgress, NativeSelect, Typography } from "@equinor/eds-core-react";
3+
import { CircularProgress, NativeSelect, Typography } from "@equinor/eds-core-react";
44
import { getGridSimulationResult, ResultIsPending } from "@/api/api";
55
import { MainContainer } from "@/components/styles";
66
import { GridSimulationResult } from "@/dto/GridSimulation";
@@ -13,7 +13,8 @@ import {
1313
} from "@/functions/GridSimulation";
1414
import { optionName } from "@/functions/Substance";
1515
import { useAvailableModels } from "@/contexts/ModelContext";
16-
import { buildModelSections } from "@/utils/modelUtils";
16+
import { buildModelSections, phaseLabel } from "@/utils/modelUtils";
17+
import ModelAccordionLayout, { AccordionItem } from "@/components/ModelAccordionLayout";
1718

1819
interface CompareGridSimulationsProps {
1920
gridIds: string[];
@@ -25,10 +26,6 @@ const modelChainLabel = (result: GridSimulationResult): string => {
2526
return firstSim.input.models.map((m) => m.modelId).join(" → ") || "Unknown model";
2627
};
2728

28-
function phaseLabel(kind: string): string {
29-
return kind === "aqueous" ? "Aqueous" : "CO2-rich";
30-
}
31-
3229
interface CompareSectionProps {
3330
results: GridSimulationResult[];
3431
modelIndex: number;
@@ -172,27 +169,25 @@ const CompareGridSimulations: React.FC<CompareGridSimulationsProps> = ({ gridIds
172169
});
173170
});
174171

175-
const allAccordions: { key: string; header: string; modelIndex: number; phaseKind: string }[] = [];
172+
const items: AccordionItem[] = [];
176173
sections.forEach((section) => {
177174
section.indices.forEach((modelIndex) => {
178175
const phases = allPhasesByModel.get(modelIndex) ?? [];
179176
const modelName =
180177
models.find((m) => m.modelId === inputModels[modelIndex]?.modelId)?.displayName ??
181178
inputModels[modelIndex]?.modelId;
182179
if (phases.length === 1) {
183-
allAccordions.push({
180+
items.push({
184181
key: `${section.category}-${modelIndex}`,
185182
header: `${section.category}: ${modelName}`,
186-
modelIndex,
187-
phaseKind: phases[0],
183+
content: <CompareSection results={results} modelIndex={modelIndex} phaseKind={phases[0]} />,
188184
});
189185
} else {
190186
phases.forEach((phaseKind) => {
191-
allAccordions.push({
187+
items.push({
192188
key: `${section.category}-${modelIndex}-${phaseKind}`,
193189
header: `${section.category}: ${modelName}${phaseLabel(phaseKind)}`,
194-
modelIndex,
195-
phaseKind,
190+
content: <CompareSection results={results} modelIndex={modelIndex} phaseKind={phaseKind} />,
196191
});
197192
});
198193
}
@@ -207,22 +202,7 @@ const CompareGridSimulations: React.FC<CompareGridSimulationsProps> = ({ gridIds
207202
across the configured range.
208203
</Typography>
209204

210-
<div style={{ display: "flex", flexDirection: "column", gap: "1rem" }}>
211-
{allAccordions.map((item, index) => (
212-
<Accordion key={item.key}>
213-
<Accordion.Item isExpanded={index === allAccordions.length - 1}>
214-
<Accordion.Header>{item.header}</Accordion.Header>
215-
<Accordion.Panel>
216-
<CompareSection
217-
results={results}
218-
modelIndex={item.modelIndex}
219-
phaseKind={item.phaseKind}
220-
/>
221-
</Accordion.Panel>
222-
</Accordion.Item>
223-
</Accordion>
224-
))}
225-
</div>
205+
<ModelAccordionLayout items={items} />
226206
</MainContainer>
227207
);
228208
};

frontend/src/components/GridSimulation/GridResults.tsx

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useMemo, useState } from "react";
2-
import { Accordion, Autocomplete, Banner, Table, Typography } from "@equinor/eds-core-react";
2+
import { Autocomplete, Banner, Table, Typography } from "@equinor/eds-core-react";
33
import { GridSimulationResult } from "@/dto/GridSimulation";
44
import { formatConcentration } from "@/functions/Formatting";
55
import {
@@ -13,7 +13,8 @@ import { optionName } from "@/functions/Substance";
1313
import LineChart, { LineSeries } from "@/components/LineChart";
1414
import DownloadButton from "@/components/DownloadButton";
1515
import { useAvailableModels } from "@/contexts/ModelContext";
16-
import { buildModelSections, ModelSection } from "@/utils/modelUtils";
16+
import { buildModelSections, phaseLabel } from "@/utils/modelUtils";
17+
import ModelAccordionLayout, { AccordionItem } from "@/components/ModelAccordionLayout";
1718

1819
interface GridResultsProps {
1920
result: GridSimulationResult;
@@ -25,10 +26,6 @@ interface GridPhaseChartProps {
2526
phaseKind: string;
2627
}
2728

28-
function phaseLabel(kind: string): string {
29-
return kind === "aqueous" ? "Aqueous" : "CO2-rich";
30-
}
31-
3229
const GridPhaseChart: React.FC<GridPhaseChartProps> = ({ result, modelIndex, phaseKind }) => {
3330
const { simulations, axes } = result;
3431

@@ -146,13 +143,21 @@ const GridResults: React.FC<GridResultsProps> = ({ result }) => {
146143
const firstSim = simulations[0];
147144
const inputModels = firstSim?.input.models ?? [];
148145

149-
const sections: ModelSection[] = buildModelSections(inputModels, models);
146+
const sections = buildModelSections(inputModels, models);
150147

151148
const erroredSimulations = simulations.filter((sim) => sim.status === "error");
152149

153150
const xAxisSubstance = axes[0]?.substance ?? "Unknown";
154151
const modelLabel = inputModels.map((model) => model.modelId).join(" → ") || "Unknown model";
155152

153+
const items: AccordionItem[] = sections.flatMap((section) =>
154+
section.indices.map((modelIndex) => ({
155+
key: `${section.category}-${modelIndex}`,
156+
header: `${section.category}: ${models.find((m) => m.modelId === inputModels[modelIndex]?.modelId)?.displayName ?? inputModels[modelIndex]?.modelId}`,
157+
content: <GridSection result={result} modelIndex={modelIndex} />,
158+
}))
159+
);
160+
156161
return (
157162
<>
158163
<Typography variant="body_short" style={{ marginBottom: "1rem" }}>
@@ -169,22 +174,7 @@ const GridResults: React.FC<GridResultsProps> = ({ result }) => {
169174
</Banner>
170175
)}
171176

172-
<div style={{ display: "flex", flexDirection: "column", gap: "1rem" }}>
173-
{sections.map((section, sectionIndex) =>
174-
section.indices.map((modelIndex) => (
175-
<Accordion key={`${section.category}-${modelIndex}`}>
176-
<Accordion.Item isExpanded={sectionIndex === sections.length - 1}>
177-
<Accordion.Header>
178-
{`${section.category}: ${models.find((m) => m.modelId === inputModels[modelIndex]?.modelId)?.displayName ?? inputModels[modelIndex]?.modelId}`}
179-
</Accordion.Header>
180-
<Accordion.Panel>
181-
<GridSection result={result} modelIndex={modelIndex} />
182-
</Accordion.Panel>
183-
</Accordion.Item>
184-
</Accordion>
185-
))
186-
)}
187-
</div>
177+
<ModelAccordionLayout items={items} />
188178

189179
<div style={{ display: "flex", justifyContent: "flex-end", marginTop: "1rem", marginBottom: "2rem" }}>
190180
<DownloadButton
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import React from "react";
2+
import { Accordion } from "@equinor/eds-core-react";
3+
4+
export interface AccordionItem {
5+
key: string;
6+
header: string;
7+
content: React.ReactNode;
8+
}
9+
10+
interface ModelAccordionLayoutProps {
11+
items: AccordionItem[];
12+
}
13+
14+
const ModelAccordionLayout: React.FC<ModelAccordionLayoutProps> = ({ items }) => {
15+
return (
16+
<div style={{ display: "flex", flexDirection: "column", gap: "1rem" }}>
17+
{items.map((item, index) => (
18+
<Accordion key={item.key}>
19+
<Accordion.Item isExpanded={index === items.length - 1}>
20+
<Accordion.Header>{item.header}</Accordion.Header>
21+
<Accordion.Panel>{item.content}</Accordion.Panel>
22+
</Accordion.Item>
23+
</Accordion>
24+
))}
25+
</div>
26+
);
27+
};
28+
29+
export default ModelAccordionLayout;

frontend/src/components/Simulation/PhaseResultTable.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Table } from "@equinor/eds-core-react";
22
import { Phase } from "@/dto/SimulationResults";
33
import { formatConcentration, formatPhaseFraction } from "@/functions/Formatting";
44
import { ppmMolToWeightPercent } from "@/functions/UnitConversion";
5+
import { phaseLabel } from "@/utils/modelUtils";
56

67
interface PhaseResultTableProps {
78
initialConcentrations: Record<string, number>;
@@ -19,10 +20,6 @@ function convertUnitAccordingToPhase(phase: Phase): Record<string, number> {
1920
return phase.concentrations;
2021
}
2122

22-
function phaseLabel(phase: Phase): string {
23-
return phase.kind === "aqueous" ? "Aqueous" : "CO2-rich";
24-
}
25-
2623
function sortPhases(phases: Phase[]): Phase[] {
2724
return [...phases].sort((a, b) => {
2825
if (a.kind === "co2-rich" && b.kind === "aqueous") return -1;
@@ -54,7 +51,7 @@ function buildPhaseGroup(label: string, phases: Phase[]): PhaseGroup {
5451

5552
function phaseColumnHeader(phase: Phase): string {
5653
const fraction = phase.fraction < 1 ? ` (${formatPhaseFraction(phase.fraction)})` : "";
57-
return `${phaseLabel(phase)} [${unitLabel(phase)}]${fraction}`;
54+
return `${phaseLabel(phase.kind)} [${unitLabel(phase)}]${fraction}`;
5855
}
5956

6057
function weightedTotal(phases: Phase[], component: string): number {

frontend/src/components/Simulation/Results.tsx

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import BarChart from "@/components/BarChart";
1010
import GenericTable from "@/components/GenericTable";
1111
import { useAvailableModels } from "@/contexts/ModelContext";
1212
import { buildModelSections } from "@/utils/modelUtils";
13+
import ModelAccordionLayout, { AccordionItem } from "@/components/ModelAccordionLayout";
1314

1415
interface ResultsProps {
1516
simulationResults?: SimulationResults;
@@ -129,18 +130,15 @@ const Results: React.FC<ResultsProps> = ({ simulationResults }) => {
129130

130131
const sections = buildModelSections(simulationResults.input.models, models);
131132

133+
const items: AccordionItem[] = sections.map((section) => ({
134+
key: section.category,
135+
header: `${section.category}: ${section.modelNames.join(", ")}`,
136+
content: <ModelResultTabs simulationResults={simulationResults} modelIndices={section.indices} />,
137+
}));
138+
132139
return (
133140
<div style={{ display: "flex", flexDirection: "column", gap: "1rem" }}>
134-
{sections.map((section, i) => (
135-
<Accordion key={section.category}>
136-
<Accordion.Item isExpanded={i === sections.length - 1}>
137-
<Accordion.Header>{`${section.category}: ${section.modelNames.join(", ")}`}</Accordion.Header>
138-
<Accordion.Panel>
139-
<ModelResultTabs simulationResults={simulationResults} modelIndices={section.indices} />
140-
</Accordion.Panel>
141-
</Accordion.Item>
142-
</Accordion>
143-
))}
141+
<ModelAccordionLayout items={items} />
144142

145143
<Accordion>
146144
<Accordion.Item isExpanded={false}>

frontend/src/utils/modelUtils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,7 @@ export function buildModelSections(inputModels: ModelInput["models"], availableM
3131
});
3232
return sections;
3333
}
34+
35+
export function phaseLabel(kind: string): string {
36+
return kind === "aqueous" ? "Aqueous" : "CO2-rich";
37+
}

0 commit comments

Comments
 (0)