Skip to content

Commit

Permalink
feat(ui-outputs): add outputs synthesis view (#1737)
Browse files Browse the repository at this point in the history
  • Loading branch information
hdinia authored Oct 3, 2023
1 parent 1e7e1b1 commit 83e17c4
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 88 deletions.
2 changes: 1 addition & 1 deletion webapp/public/locales/fr/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@
"study.timeLimitHelper": "Limite de temps en heures (max: {{max}}h)",
"study.nbCpu": "Nombre de coeurs",
"study.clusterLoad": "Charge du cluster",
"study.synthesis": "Synthesis",
"study.synthesis": "Synthèse",
"study.level": "Niveau",
"study.years": "Années",
"study.type": "Type",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
Box,
Button,
Paper,
Skeleton,
ToggleButton,
ToggleButtonGroup,
Expand Down Expand Up @@ -32,7 +33,13 @@ import PropertiesView from "../../../../../common/PropertiesView";
import SplitLayoutView from "../../../../../common/SplitLayoutView";
import ListElement from "../../common/ListElement";
import SelectionDrawer, { SelectionDrawerProps } from "./SelectionDrawer";
import { createPath, DataType, OutputItemType, Timestep } from "./utils";
import {
createPath,
DataType,
OutputItemType,
SYNTHESIS_ITEMS,
Timestep,
} from "./utils";
import UsePromiseCond, {
mergeResponses,
} from "../../../../../common/utils/UsePromiseCond";
Expand All @@ -57,6 +64,7 @@ function ResultDetails() {
const [itemType, setItemType] = useState(OutputItemType.Areas);
const [selectedItemId, setSelectedItemId] = useState("");
const [searchValue, setSearchValue] = useState("");
const isSynthesis = itemType === OutputItemType.Synthesis;
const { t } = useTranslation();
const navigate = useNavigate();

Expand All @@ -67,10 +75,12 @@ function ResultDetails() {
) as Array<{ id: string; name: string; label?: string }>;

const filteredItems = useMemo(() => {
return items.filter((item) =>
isSearchMatching(searchValue, item.label || item.name)
);
}, [items, searchValue]);
return isSynthesis
? SYNTHESIS_ITEMS
: items.filter((item) =>
isSearchMatching(searchValue, item.label || item.name)
);
}, [isSynthesis, items, searchValue]);

const selectedItem = filteredItems.find(
(item) => item.id === selectedItemId
Expand All @@ -92,7 +102,7 @@ function ResultDetails() {

const matrixRes = usePromise<MatrixType | null>(
async () => {
if (output && selectedItem) {
if (output && selectedItem && !isSynthesis) {
const path = createPath({
output: { ...output, id: outputId as string },
item: selectedItem,
Expand Down Expand Up @@ -120,6 +130,20 @@ function ResultDetails() {
}
);

const { data: synthesis } = usePromise<string>(
async () => {
if (outputId && selectedItem && isSynthesis) {
const path = `output/${outputId}/economy/mc-all/grid/${selectedItem.id}`;
const res = await getStudyData(study.id, path);
return res;
}
return null;
},
{
deps: [study.id, outputId, selectedItem],
}
);

////////////////////////////////////////////////////////////////
// Event Handlers
////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -171,6 +195,7 @@ function ResultDetails() {
value={itemType}
exclusive
size="small"
orientation="vertical"
fullWidth
onChange={handleItemTypeChange}
>
Expand All @@ -180,6 +205,9 @@ function ResultDetails() {
<ToggleButton value={OutputItemType.Links}>
{t("study.links")}
</ToggleButton>
<ToggleButton value={OutputItemType.Synthesis}>
{t("study.synthesis")}
</ToggleButton>
</ToggleButtonGroup>
<ListElement
list={filteredItems}
Expand All @@ -199,92 +227,107 @@ function ResultDetails() {
flexDirection: "column",
height: 1,
width: 1,
gap: 1,
overflow: "auto",
}}
>
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
gap: 4,
}}
>
{[
[
`${t("study.results.mc")}:`,
year > 0 ? `${t("study.results.mc.year")} ${year}` : "all",
],
[`${t("study.results.display")}:`, dataType],
[`${t("study.results.temporality")}:`, timestep],
].map(([label, value]) => (
<Box key={label}>
<Box component="span" sx={{ opacity: 0.7, mr: 1 }}>
{label}
</Box>
{value}
</Box>
))}
<Button
variant="outlined"
onClick={() => setShowFilter(true)}
disabled={matrixRes.isLoading}
>
{t("global.change")}
</Button>

<Button
variant="outlined"
color="primary"
startIcon={<DownloadOutlinedIcon />}
onClick={() =>
matrixRes.data &&
handleDownload(matrixRes.data, `matrix_${study.id}`)
}
disabled={matrixRes.isLoading}
{isSynthesis ? (
<Paper
sx={{
p: 2,
overflow: "auto",
}}
>
{t("global.download")}
</Button>
</Box>
<Box sx={{ flex: 1 }}>
<UsePromiseCond
response={mergeResponses(outputRes, matrixRes)}
ifPending={() => (
<Skeleton sx={{ height: 1, transform: "none" }} />
)}
ifResolved={([, matrix]) =>
matrix && (
<EditableMatrix
matrix={matrix}
matrixTime={false}
readOnly
toggleView
/>
)
}
ifRejected={(err) => (
<Box
sx={{
height: 1,
display: "flex",
justifyContent: "center",
alignItems: "center",
flexDirection: "column",
gap: 1,
}}
<code style={{ whiteSpace: "pre" }}>{synthesis}</code>
</Paper>
) : (
<>
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
gap: 4,
}}
>
{[
[
`${t("study.results.mc")}:`,
year > 0
? `${t("study.results.mc.year")} ${year}`
: "all",
],
[`${t("study.results.display")}:`, dataType],
[`${t("study.results.temporality")}:`, timestep],
].map(([label, value]) => (
<Box key={label}>
<Box component="span" sx={{ opacity: 0.7, mr: 1 }}>
{label}
</Box>
{value}
</Box>
))}
<Button
variant="outlined"
onClick={() => setShowFilter(true)}
disabled={matrixRes.isLoading}
>
{t("global.change")}
</Button>
<Button
variant="outlined"
color="primary"
startIcon={<DownloadOutlinedIcon />}
onClick={() =>
matrixRes.data &&
handleDownload(matrixRes.data, `matrix_${study.id}`)
}
disabled={matrixRes.isLoading}
>
{axios.isAxiosError(err) && err.response?.status === 404 ? (
<>
<GridOffIcon sx={{ fontSize: "80px" }} />
{t("study.results.noData")}
</>
) : (
t("data.error.matrix")
{t("global.download")}
</Button>
</Box>
<Box sx={{ flex: 1 }}>
<UsePromiseCond
response={mergeResponses(outputRes, matrixRes)}
ifPending={() => (
<Skeleton sx={{ height: 1, transform: "none" }} />
)}
</Box>
)}
/>
</Box>
ifResolved={([, matrix]) =>
matrix && (
<EditableMatrix
matrix={matrix}
matrixTime={false}
readOnly
toggleView
/>
)
}
ifRejected={(err) => (
<Box
sx={{
height: 1,
display: "flex",
justifyContent: "center",
alignItems: "center",
flexDirection: "column",
gap: 1,
}}
>
{axios.isAxiosError(err) &&
err.response?.status === 404 ? (
<>
<GridOffIcon sx={{ fontSize: "80px" }} />
{t("study.results.noData")}
</>
) : (
t("data.error.matrix")
)}
</Box>
)}
/>
</Box>
</>
)}
</Box>
}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Area, LinkElement, Simulation } from "../../../../../../common/types";
export enum OutputItemType {
Areas = "areas",
Links = "links",
Synthesis = "synthesis",
}

export enum DataType {
Expand Down Expand Up @@ -43,3 +44,26 @@ export function createPath(params: Params): string {

return `output/${id}/${mode}/${periodFolder}/${itemType}/${itemFolder}/${dataType}-${timestep}`;
}

export const SYNTHESIS_ITEMS = [
{
id: "areas",
name: "Areas",
label: "Areas synthesis",
},
{
id: "links",
name: "Links",
label: "Links synthesis",
},
{
id: "digest",
name: "Digest",
label: "Digest",
},
{
id: "thermal",
name: "Thermal",
label: "Thermal synthesis",
},
];

0 comments on commit 83e17c4

Please sign in to comment.