Skip to content

Commit

Permalink
Add links form view (#950)
Browse files Browse the repository at this point in the history
  • Loading branch information
3lbanna authored Jun 15, 2022
1 parent 34746e7 commit d8da3eb
Show file tree
Hide file tree
Showing 18 changed files with 852 additions and 31 deletions.
31 changes: 31 additions & 0 deletions webapp/public/locales/en/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"global.upload": "Upload",
"global.key": "Key",
"global.value": "Value",
"global.number": "Number",
"global.emptyString": "Empty string",
"global.edit": "Edit",
"global.download": "Download",
Expand Down Expand Up @@ -218,6 +219,36 @@
"study.copyJobId": "Copy the job id",
"study.modelization.map.newArea": "New Area",
"study.modelization.map.areaName": "Area name",
"study.modelization.links.hurdleCost": "Hurdle costs",
"study.modelization.links.loopFlows": "Loop flows",
"study.modelization.links.pst": "PST",
"study.modelization.links.type": "Type",
"study.modelization.links.transmissionCapa": "Transmission capacities",
"study.modelization.links.transmissionCapa.infinite": "Infinite",
"study.modelization.links.transmissionCapa.ignore": "Ignore",
"study.modelization.links.transmissionCapa.enabled": "Enabled",
"study.modelization.links.type.ac": "AC",
"study.modelization.links.type.dc": "DC",
"study.modelization.links.type.gaz": "Gas",
"study.modelization.links.type.virt": "Virt",
"study.modelization.links.type.other": "Other",
"study.modelization.links.matrix.parameters": "Parameters",
"study.modelization.links.matrix.capacities": "Capacities",
"study.modelization.links.matrix.columns.transCapaDirect": "Trans. capacity direct",
"study.modelization.links.matrix.columns.transCapaIndirect": "Trans. capacity indirect",
"study.modelization.links.matrix.columns.hurdleCostsDirect": "Hurdle costs direct",
"study.modelization.links.matrix.columns.hurdleCostsIndirect": "Hurdle costs indirect",
"study.modelization.links.matrix.columns.inpedances": "Inpedances",
"study.modelization.links.matrix.columns.loopFlow": "Loop flow",
"study.modelization.links.matrix.columns.pShiftMin": "P.Shift Min",
"study.modelization.links.matrix.columns.pShiftMax": "P.Shift Max",
"study.modelization.configuration.general.firstDay": "First day",
"study.modelization.configuration.general.lastDay": "Last day",
"study.modelization.configuration.general.calendar": "Calendar",
"study.modelization.configuration.general.year": "Year",
"study.modelization.configuration.general.week": "Week",
"study.modelization.configuration.general.firstDayOfYear": "1st January",
"study.modelization.configuration.general.leapYear": "Leap year",
"study.modelization.nodeProperties.nodalOptimization": "Nodal Optimization",
"study.modelization.nodeProperties.energyCost": "Energy cost",
"study.modelization.nodeProperties.unsupplied": "Unsupplied",
Expand Down
39 changes: 35 additions & 4 deletions webapp/public/locales/fr/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"global.upload": "Charger",
"global.key": "Clé",
"global.value": "Valeur",
"global.number": "Nombre",
"global.emptyString": "Chaine de caractères vide",
"global.edit": "Editer",
"global.download": "Télécharger",
Expand Down Expand Up @@ -218,14 +219,44 @@
"study.copyJobId": "Copier l'identifiant de la tâche",
"study.modelization.map.newArea": "Nouvelle zone",
"study.modelization.map.areaName": "Nom de la zone",
"study.modelization.links.hurdleCost": "Hurdle costs",
"study.modelization.links.loopFlows": "Loop flows",
"study.modelization.links.pst": "PST",
"study.modelization.links.type": "Type",
"study.modelization.links.transmissionCapa": "Transmission capacities",
"study.modelization.links.transmissionCapa.infinite": "Infinite",
"study.modelization.links.transmissionCapa.ignore": "Ignore",
"study.modelization.links.transmissionCapa.enabled": "Enabled",
"study.modelization.links.type.ac": "AC",
"study.modelization.links.type.dc": "DC",
"study.modelization.links.type.gaz": "Gas",
"study.modelization.links.type.virt": "Virt",
"study.modelization.links.type.other": "Other",
"study.modelization.links.matrix.parameters": "Paramètres",
"study.modelization.links.matrix.capacities": "Capacités",
"study.modelization.links.matrix.columns.transCapaDirect": "Trans. capacity direct",
"study.modelization.links.matrix.columns.transCapaIndirect": "Trans. capacity indirect",
"study.modelization.links.matrix.columns.hurdleCostsDirect": "Hurdle costs direct",
"study.modelization.links.matrix.columns.hurdleCostsIndirect": "Hurdle costs indirect",
"study.modelization.links.matrix.columns.inpedances": "Inpedances",
"study.modelization.links.matrix.columns.loopFlow": "Loop flow",
"study.modelization.links.matrix.columns.pShiftMin": "P.Shift Min",
"study.modelization.links.matrix.columns.pShiftMax": "P.Shift Max",
"study.modelization.configuration.general.firstDay": "Premier jour",
"study.modelization.configuration.general.lastDay": "Dernier jour",
"study.modelization.configuration.general.calendar": "Calendrier",
"study.modelization.configuration.general.year": "Année",
"study.modelization.configuration.general.week": "Semaine",
"study.modelization.configuration.general.firstDayOfYear": "1er Janvier",
"study.modelization.configuration.general.leapYear": "Année bissextile",
"study.modelization.nodeProperties.nodalOptimization": "Optimisation nodale",
"study.modelization.nodeProperties.energyCost": "Coût de l'énergie",
"study.modelization.nodeProperties.unsupplied": "Non distribuée",
"study.modelization.nodeProperties.splilled": "Non évacuée",
"study.modelization.nodeProperties.lastResortShedding": "Last resort shedding status",
"study.modelization.nodeProperties.nonDispatchPower": "Non dispatch. power",
"study.modelization.nodeProperties.dispatchHydroPower": "Dispatch hydropower",
"study.modelization.nodeProperties.otherDispatchPower": "Other dispatch power",
"study.modelization.nodeProperties.lastResortShedding": "Moyen de dernier recours pour l'écrêtement",
"study.modelization.nodeProperties.nonDispatchPower": "Production non pilotable",
"study.modelization.nodeProperties.dispatchHydroPower": "Hydrolique pilotable",
"study.modelization.nodeProperties.otherDispatchPower": "Autres productions pilotables",
"study.modelization.nodeProperties.outputFilter": "Affichage des sorties",
"study.modelization.nodeProperties.filterByYear": "Sorties année par année",
"study.modelization.nodeProperties.filterSynthesis": "Sorties de la synthèse",
Expand Down
7 changes: 7 additions & 0 deletions webapp/src/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,13 @@ export interface FileStudyTreeConfigDTO {
archive_input_series: Array<string>;
enr_modelling: string;
}
export interface LinkElement {
label: string;
name: string;
area1: string;
area2: string;
}
export type LinkListElement = { [elm: string]: LinkElement };

export enum StudyOutputDownloadType {
LINKS = "LINKS",
Expand Down
6 changes: 4 additions & 2 deletions webapp/src/components/common/MatrixInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ interface PropsType {
study: StudyMetadata;
url: string;
columnsNames?: string[];
title?: string;
computStats: MatrixStats;
}

function MatrixInput(props: PropsType) {
const { study, url, columnsNames, computStats } = props;
const { study, url, columnsNames, title, computStats } = props;
const { enqueueSnackbar } = useSnackbar();
const enqueueErrorSnackbar = useEnqueueErrorSnackbar();
const [t] = useTranslation();
Expand Down Expand Up @@ -118,7 +119,7 @@ function MatrixInput(props: PropsType) {
lineHeight: 1.334,
}}
>
{t("xpansion.timeSeries")}
{title || t("xpansion.timeSeries")}
</Typography>
<Box sx={{ display: "flex", alignItems: "center" }}>
{!isLoading && data?.columns?.length > 1 && (
Expand Down Expand Up @@ -188,6 +189,7 @@ function MatrixInput(props: PropsType) {

MatrixInput.defaultProps = {
columnsNames: undefined,
title: undefined,
};

export default MatrixInput;
5 changes: 4 additions & 1 deletion webapp/src/components/common/fieldEditors/SelectFE.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
FormControl,
FormControlProps,
FormHelperText,
InputLabel,
MenuItem,
Expand All @@ -22,6 +23,7 @@ export interface SelectFEProps
options: Array<string | OptionObj>;
helperText?: React.ReactNode;
emptyValue?: boolean;
formControlProps?: FormControlProps;
}

function formatOptions(
Expand All @@ -39,6 +41,7 @@ const SelectFE = forwardRef((props: SelectFEProps, ref) => {
helperText,
emptyValue,
variant = "filled",
formControlProps,
...selectProps
} = props;
const { label } = selectProps;
Expand All @@ -51,7 +54,7 @@ const SelectFE = forwardRef((props: SelectFEProps, ref) => {
);

return (
<FormControl variant={variant}>
<FormControl variant={variant} {...formControlProps}>
<InputLabel id={labelId}>{label}</InputLabel>
<Select
{...selectProps}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as R from "ramda";
import { Box, Divider, TextField } from "@mui/material";
import { useEffect } from "react";
import { useTranslation } from "react-i18next";
import { StyledFieldset } from "../styles";
import SelectFE from "../../../../../common/fieldEditors/SelectFE";
import { StudyMetadata } from "../../../../../../common/types";
Expand All @@ -24,6 +25,7 @@ interface Props {
function Fields(props: Props) {
const { study } = props;
const studyVersion = Number(study.version);
const [t] = useTranslation();
const { register, setValue, watch, getValues } = useFormContext<FormValues>();
const buildingMode = watch("buildingMode");

Expand All @@ -45,9 +47,9 @@ function Fields(props: Props) {
return "First day must be lower or equal to last day";
}
if (getValues("leapYear")) {
return v <= 365 ? true : "Maximum is 365 for a leap year";
return v <= 366 ? true : "Maximum is 366 for a leap year";
}
return v <= 364 ? true : "Maximum is 364 for a non-leap year";
return v <= 365 ? true : "Maximum is 365 for a non-leap year";
};

////////////////////////////////////////////////////////////////
Expand All @@ -73,7 +75,7 @@ function Fields(props: Props) {
})}
/>
<TextField
label="First day"
label={t("study.modelization.configuration.general.firstDay")}
variant="filled"
{...register("firstDay", {
deps: "lastDay",
Expand All @@ -83,7 +85,7 @@ function Fields(props: Props) {
})}
/>
<TextField
label="Last day"
label={t("study.modelization.configuration.general.lastDay")}
variant="filled"
{...register("lastDay", {
deps: "firstDay",
Expand All @@ -93,7 +95,9 @@ function Fields(props: Props) {
})}
/>
</StyledFieldset>
<StyledFieldset legend="Calendar">
<StyledFieldset
legend={t("study.modelization.configuration.general.calendar")}
>
<TextField
label="Horizon"
variant="filled"
Expand All @@ -102,29 +106,29 @@ function Fields(props: Props) {
})}
/>
<SelectFE
label="Year"
label={t("study.modelization.configuration.general.year")}
options={YEAR_OPTIONS}
{...register("firstMonth", {
onAutoSubmit: saveValue("general/first-month-in-year"),
})}
/>
<SelectFE
label="Week"
label={t("study.modelization.configuration.general.week")}
options={WEEK_OPTIONS}
{...register("firstWeekDay", {
onAutoSubmit: saveValue("general/first.weekday"),
})}
/>
<SelectFE
label="1st January"
label={t("study.modelization.configuration.general.firstDayOfYear")}
options={FIRST_JANUARY_OPTIONS}
{...register("firstJanuary", {
onAutoSubmit: saveValue("general/january.1st"),
})}
/>
<SwitchFE
sx={{ flex: 1, flexBasis: "100%" }}
label="Leap year"
label={t("study.modelization.configuration.general.leapYear")}
{...register("leapYear", {
deps: ["firstDay", "lastDay"],
onAutoSubmit: saveValue("general/leapyear"),
Expand All @@ -142,7 +146,7 @@ function Fields(props: Props) {
}}
>
<TextField
label="Number"
label={t("global.number")}
variant="filled"
{...register("nbYears", {
validate: (v) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import PropertiesView from "../../../../common/PropertiesView";
import useAppSelector from "../../../../../redux/hooks/useAppSelector";
import { getStudyAreas } from "../../../../../redux/selectors";
import ListElement from "../../common/ListElement";
import { transformNameToId } from "../../../../../services/utils";

interface PropsType {
studyId: string;
Expand All @@ -27,7 +28,13 @@ function AreaPropsView(props: PropsType) {
}
return [];
};
setFilteredAreas(filter());
setFilteredAreas(
filter().map((el) => ({
...el,
name: transformNameToId(el.name),
label: el.name,
}))
);
}, [areas, areaNameFilter]);

////////////////////////////////////////////////////////////////
Expand All @@ -40,7 +47,7 @@ function AreaPropsView(props: PropsType) {
<ListElement
list={filteredAreas}
currentElement={currentArea}
setSelectedItem={(elm) => onClick(elm.name)}
setSelectedItem={(elm) => onClick(transformNameToId(elm.name))}
/>
}
secondaryContent={<div />}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ function Areas() {
// Event Handlers
////////////////////////////////////////////////////////////////

const handleAreaClick = (areaName: string): void => {
const handleAreaClick = (areaId: string): void => {
if (studyData?.areas === undefined) return;
const elm = studyData?.areas[areaName.toLowerCase()];
const elm = studyData?.areas[areaId];
if (elm) {
dispatch(setCurrentArea(areaName.toLowerCase()));
dispatch(setCurrentArea(areaId));
}
};

Expand All @@ -56,9 +56,7 @@ function Areas() {
<AreaPropsView
studyId={study.id}
onClick={handleAreaClick}
currentArea={
selectedArea !== undefined ? selectedArea.name : undefined
}
currentArea={currentArea !== undefined ? currentArea : undefined}
/>
)}
</Box>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { useEffect, useState } from "react";
import PropertiesView from "../../../../common/PropertiesView";
import useAppSelector from "../../../../../redux/hooks/useAppSelector";
import { getStudyLinks } from "../../../../../redux/selectors";
import ListElement from "../../common/ListElement";
import { LinkElement } from "../../../../../common/types";

interface PropsType {
studyId: string;
onClick: (name: string) => void;
currentLink?: string;
}
function LinkPropsView(props: PropsType) {
const { onClick, currentLink, studyId } = props;
const links = useAppSelector((state) => getStudyLinks(state, studyId));
const [linkNameFilter, setLinkNameFilter] = useState<string>();
const [filteredLinks, setFilteredLinks] = useState<Array<LinkElement>>(
links || []
);

useEffect(() => {
const filter = (): Array<LinkElement> => {
if (links) {
return links.filter(
(s) =>
!linkNameFilter ||
s.name.search(new RegExp(linkNameFilter, "i")) !== -1
);
}
return [];
};
setFilteredLinks(filter());
}, [links, linkNameFilter]);

////////////////////////////////////////////////////////////////
// JSX
////////////////////////////////////////////////////////////////

return (
<PropertiesView
mainContent={
<ListElement
list={filteredLinks}
currentElement={currentLink}
setSelectedItem={(elm) => onClick(elm.name)}
/>
}
secondaryContent={<div />}
onSearchFilterChange={(e) => setLinkNameFilter(e as string)}
/>
);
}

LinkPropsView.defaultProps = {
currentLink: undefined,
};

export default LinkPropsView;
Loading

0 comments on commit d8da3eb

Please sign in to comment.