Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import styled from "styled-components";
import { BrowserRouter as Router, Navigate, Route, Routes } from "react-router-dom";
import TopBar from "./components/TopBar";
import Dashboard from "./pages/Home";
import ErrorDialog from "./components/ErrorDialog";
import LabResults from "./pages/LabResults";
import HelpPage from "./pages/HelpPage";
import DynamicBreadcrumbs from "./components/DynamicBreadcrumbs";
Expand Down Expand Up @@ -63,7 +62,6 @@ const Layout: React.FC = () => (
</Routes>
</Content>
</Main>
<ErrorDialog />
</AppContainer>
);

Expand Down
28 changes: 0 additions & 28 deletions frontend/src/components/ErrorDialog.tsx

This file was deleted.

23 changes: 23 additions & 0 deletions frontend/src/components/Simulation/InputStep.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ModelConfig } from "@/dto/FormConfig";
import React from "react";
import ModelInputs from "./ModelInputs";
import noModelImage from "@/assets/no-model-light.svg";
import CenteredImage from "@/components/CenteredImage";

type InputStepProps = {
currentPrimaryModel?: ModelConfig;
currentSecondaryModel?: ModelConfig;
setModelInput: (modelInput: any) => void;
};

const InputStep: React.FC<InputStepProps> = ({ currentPrimaryModel, currentSecondaryModel, setModelInput }) => {
const selectedModel = currentPrimaryModel || currentSecondaryModel;

if (selectedModel !== undefined) {
return <ModelInputs model={selectedModel} onSubmit={setModelInput} />;
} else {
return <CenteredImage src={noModelImage} caption="No model selected" />;
}
};

export default InputStep;
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { ChangeEvent, useState } from "react";
import { ModelConfig } from "@/dto/FormConfig";
import { Autocomplete, Button, NativeSelect, TextField, Typography } from "@equinor/eds-core-react";
import ConvertibleTextField from "./ConvertibleTextField";
import ConvertibleTextField from "../ConvertibleTextField";
import { FORMULA_TO_NAME_MAPPER } from "@/constants/formula_map";
import { MetaTooltip } from "@/functions/Tooltip";
import { Columns } from "@/components/styles";
Expand Down
44 changes: 44 additions & 0 deletions frontend/src/components/Simulation/ResultStep.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { convertSimulationQueriesResultToTabulatedData, convertTabulatedDataToCSVFormat } from "@/functions/Formatting";
import DownloadButton from "../DownloadButton";
import { SimulationResults } from "@/dto/SimulationResults";
import Working from "./Working";
import NoResults from "./NoResults";
import Results from "./Results";

type ResultStepProps = {
simulationResults?: SimulationResults;
isLoading: boolean;
};
const ResultStep: React.FC<ResultStepProps> = ({ simulationResults, isLoading }) => {
if (isLoading) {
return <Working />;
} else if (simulationResults === undefined) {
return <NoResults />;
} else {
return (
<>
<Results simulationResults={simulationResults} />
<div
style={{
display: "flex",
justifyContent: "flex-end",
marginTop: "1rem",
marginBottom: "2rem",
}}
>
<DownloadButton
csvContent={convertTabulatedDataToCSVFormat([
...convertSimulationQueriesResultToTabulatedData({
[`${simulationResults.modelInput.modelId}`]: [simulationResults],
}),
])}
fileName={`AcidWatch-ModelResults-${new Date().toISOString().replace(/[:.]/g, "-")}.csv`}
isLoading={isLoading}
/>
</div>
</>
);
}
};

export default ResultStep;
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import React from "react";
import { Tabs, Typography } from "@equinor/eds-core-react";
import { useState } from "react";
import { Panel, SimulationResults } from "@/dto/SimulationResults";
import ResultConcTable from "@/components/ConcResultTable";
import Reactions from "../pages/Reactions";
import { MassBalanceError } from "@/components/MassBalanceError";
import ResultConcTable from "@/components/Simulation/ConcResultTable";
import Reactions from "../../pages/Reactions";
import { MassBalanceError } from "@/components/Simulation/MassBalanceError";
import { extractPlotData } from "@/functions/Formatting";
import BarChart from "@/components/BarChart";
import GenericTable from "@/components/GenericTable";
Expand Down
12 changes: 0 additions & 12 deletions frontend/src/hooks/useErrorState.ts

This file was deleted.

2 changes: 1 addition & 1 deletion frontend/src/hooks/useSecondaryModelQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export const useSecondaryModelQuery = ({

return {
secondaryResults,
isLoadingSecondary: isStartingSecondary || isLoadingSecondaryResults,
isSecondaryLoading: isStartingSecondary || isLoadingSecondaryResults,
secondaryError: startError || resultsError,
hasSecondaryResults: !!secondaryResults,
secondarySimulationId,
Expand Down
91 changes: 22 additions & 69 deletions frontend/src/pages/Models.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
import React, { ReactNode, useState, useEffect } from "react";
import ModelSelect from "@/components/ModelSelect";
import React, { useState, useEffect } from "react";
import ModelSelect from "@/components/Simulation/ModelSelect";
import { ModelConfig } from "@/dto/FormConfig";
import ModelInputs from "@/components/ModelInputs";
import Results from "@/components/Results";
import { useAvailableModels } from "@/contexts/ModelContext";
import NoResults from "@/components/Simulation/NoResults";
import Working from "@/components/Simulation/Working";
import { useMutation, useQuery } from "@tanstack/react-query";
import { getResultForSimulation, ResultIsPending, startSimulation } from "@/api/api";
import Step from "@/components/Step";
import { MainContainer } from "@/components/styles";
import CenteredImage from "@/components/CenteredImage";
import noModelImage from "@/assets/no-model-light.svg";
import { useNavigate, useParams } from "react-router-dom";
import DownloadButton from "@/components/DownloadButton";
import { convertSimulationQueriesResultToTabulatedData, convertTabulatedDataToCSVFormat } from "@/functions/Formatting";
import { simulationHistory } from "@/hooks/useSimulationHistory.ts";
import { getModelInputStore } from "@/hooks/useModelInputStore";
import { useSecondaryModelQuery } from "@/hooks/useSecondaryModelQuery";
import InputStep from "@/components/Simulation/InputStep";
import ResultStep from "@/components/Simulation/ResultStep";

const Models: React.FC = () => {
const [currentPrimaryModel, setCurrentPrimaryModel] = useState<ModelConfig | undefined>(undefined);
Expand All @@ -38,7 +32,7 @@ const Models: React.FC = () => {
},
});

const { data, isLoading } = useQuery({
const { data, isLoading: isPrimaryLoading } = useQuery({
queryKey: ["simulation", simulationId],
queryFn: () => getResultForSimulation(simulationId!),
enabled: simulationId !== undefined,
Expand All @@ -49,10 +43,10 @@ const Models: React.FC = () => {
let simulationResults = data;

useEffect(() => {
if (simulationId && !isLoading) {
if (simulationId && !isPrimaryLoading) {
simulationHistory.finalizeEntry(simulationId);
}
}, [simulationId, isLoading]);
}, [simulationId, isPrimaryLoading]);

useEffect(() => {
if (simulationResults && models.length > 0) {
Expand All @@ -79,62 +73,17 @@ const Models: React.FC = () => {
simulationResults !== undefined && currentSecondaryModel !== undefined && currentPrimaryModel !== undefined,
});

let inputsStep: ReactNode | null = null;

if (currentPrimaryModel === undefined && currentSecondaryModel === undefined) {
inputsStep = <CenteredImage src={noModelImage} caption="No model selected" />;
} else if (currentPrimaryModel !== undefined && currentSecondaryModel === undefined) {
inputsStep = <ModelInputs model={currentPrimaryModel} onSubmit={setModelInput} />;
} else if (currentPrimaryModel === undefined && currentSecondaryModel !== undefined) {
inputsStep = <ModelInputs model={currentSecondaryModel} onSubmit={setModelInput} />;
} else if (currentPrimaryModel !== undefined && currentSecondaryModel !== undefined) {
inputsStep = <ModelInputs model={currentPrimaryModel} onSubmit={setModelInput} />;

if (secondaryModelResults.hasSecondaryResults) {
simulationResults = {
...simulationResults,
status: simulationResults?.status ?? "done",
modelInput: simulationResults?.modelInput ?? { concentrations: {}, parameters: {}, modelId: "" },
finalConcentrations: simulationResults?.finalConcentrations ?? {},
panels: [
...(simulationResults?.panels ?? []),
...(secondaryModelResults.secondaryResults?.panels ?? []),
],
};
}
}

let resultsStep: ReactNode | null = null;
if (isLoading || (currentSecondaryModel !== undefined && secondaryModelResults.isLoadingSecondary)) {
resultsStep = <Working />;
} else if (simulationResults === undefined) {
resultsStep = <NoResults />;
} else {
resultsStep = (
<>
<Results simulationResults={simulationResults} />
<div
style={{
display: "flex",
justifyContent: "flex-end",
marginTop: "1rem",
marginBottom: "2rem",
}}
>
<DownloadButton
csvContent={convertTabulatedDataToCSVFormat([
...convertSimulationQueriesResultToTabulatedData({
[`${simulationResults.modelInput.modelId}`]: [simulationResults],
}),
])}
fileName={`AcidWatch-ModelResults-${new Date().toISOString().replace(/[:.]/g, "-")}.csv`}
isLoading={isLoading}
/>
</div>
</>
);
if (secondaryModelResults.hasSecondaryResults) {
simulationResults = {
...simulationResults,
status: simulationResults?.status ?? "done",
modelInput: simulationResults?.modelInput ?? { concentrations: {}, parameters: {}, modelId: "" },
finalConcentrations: simulationResults?.finalConcentrations ?? {},
panels: [...(simulationResults?.panels ?? []), ...(secondaryModelResults.secondaryResults?.panels ?? [])],
};
}

const isLoading = isPrimaryLoading || secondaryModelResults.isSecondaryLoading;
return (
<MainContainer>
<Step
Expand All @@ -149,9 +98,13 @@ const Models: React.FC = () => {
setCurrentSecondaryModel={setCurrentSecondaryModel}
/>
<Step step={2} title="Inputs" />
{inputsStep}
<InputStep
currentPrimaryModel={currentPrimaryModel}
currentSecondaryModel={currentSecondaryModel}
setModelInput={setModelInput}
/>
<Step step={3} title="Results" />
{resultsStep}
<ResultStep simulationResults={simulationResults} isLoading={isLoading} />
<div style={{ height: "25dvh" }} />
</MainContainer>
);
Expand Down
2 changes: 1 addition & 1 deletion frontend/tests/components/MassBalanceError.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, it, expect } from "vitest";
import { getMasses, getMassBalanceError } from "@/components/MassBalanceError";
import { getMasses, getMassBalanceError } from "@/components/Simulation/MassBalanceError";

describe("getMasses", () => {
it("empty", () => {
Expand Down