Skip to content

Commit

Permalink
feat(ui-ts): update TimeSeriesManagement page to allow the generation…
Browse files Browse the repository at this point in the history
… of TS
  • Loading branch information
skamril committed Oct 4, 2024
1 parent 5302e32 commit 449b2f7
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 164 deletions.
8 changes: 8 additions & 0 deletions webapp/public/locales/en/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
"global.enabled": "Enabled",
"global.close": "Close",
"global.replace": "Replace",
"global.status": "Status",
"global.time.hourly": "Hourly",
"global.time.daily": "Daily",
"global.time.weekly": "Weekly",
Expand Down Expand Up @@ -171,6 +172,7 @@
"tasks.UNARCHIVE": "Unarchive",
"tasks.SCAN": "Scan",
"tasks.UNKNOWN": "Unknown",
"tasks.thermalClusterSeriesGeneration": "Generating TS...",
"settings.createUser": "Create user",
"settings.createToken": "Create token",
"settings.createGroup": "Create group",
Expand Down Expand Up @@ -361,6 +363,12 @@
"study.configuration.general.thematicTrimming.group.generationThermals": "Generation / Thermals",
"study.configuration.general.thematicTrimming.group.links": "Links",
"study.configuration.general.filtering": "Filtering",
"study.configuration.tsManagement.numberStochasticTs": "Number Stochastic TS",
"study.configuration.tsManagement.status.toBeGenerated": "To Be Generated",
"study.configuration.tsManagement.status.readyMade": "Ready Made",
"study.configuration.tsManagement.generateTs": "Generate TS",
"study.configuration.tsManagement.generateTs.error": "Failed to run generate TS task",
"study.configuration.tsManagement.generateTs.pending": "Launch of the TS generation task...",
"study.configuration.optimization.legend.general": "General",
"study.configuration.optimization.legend.links": "Links",
"study.configuration.optimization.legend.thermalClusters": "Thermal Clusters",
Expand Down
8 changes: 8 additions & 0 deletions webapp/public/locales/fr/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
"global.enabled": "Activé",
"global.close": "Fermer",
"global.replace": "Remplacer",
"global.status": "Statut",
"global.time.hourly": "Horaire",
"global.time.daily": "Journalier",
"global.time.weekly": "Hebdomadaire",
Expand Down Expand Up @@ -171,6 +172,7 @@
"tasks.UNARCHIVE": "Désarchivage",
"tasks.SCAN": "Scan",
"tasks.UNKNOWN": "Inconnu",
"tasks.thermalClusterSeriesGeneration": "Génération des TS..",
"settings.createUser": "Créer un utilisateur",
"settings.createToken": "Créer un token",
"settings.createGroup": "Créer un groupe",
Expand Down Expand Up @@ -361,6 +363,12 @@
"study.configuration.general.thematicTrimming.group.generationThermals": "Génération / Thermiques",
"study.configuration.general.thematicTrimming.group.links": "Liens",
"study.configuration.general.filtering": "Filtering",
"study.configuration.tsManagement.numberStochasticTs": "Nombre stochastique TS",
"study.configuration.tsManagement.status.toBeGenerated": "À générer",
"study.configuration.tsManagement.status.readyMade": "Prête à l'emploi",
"study.configuration.tsManagement.generateTs": "Générer les TS",
"study.configuration.tsManagement.generateTs.error": "Échec de l'exécution de la tâche de génération de TS",
"study.configuration.tsManagement.generateTs.pending": "Lancement de la tâche de génération de TS...",
"study.configuration.optimization.legend.general": "Générale",
"study.configuration.optimization.legend.links": "Liens",
"study.configuration.optimization.legend.thermalClusters": "Cluster thermiques",
Expand Down
1 change: 1 addition & 0 deletions webapp/src/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,7 @@ export enum TaskType {
DOWNLOAD = "DOWNLOAD",
SCAN = "SCAN",
UPGRADE_STUDY = "UPGRADE_STUDY",
THERMAL_CLUSTER_SERIES_GENERATION = "THERMAL_CLUSTER_SERIES_GENERATION",
UNKNOWN = "UNKNOWN",
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,43 +21,27 @@ import {
TableRow,
} from "@mui/material";
import { capitalize } from "lodash";
import * as R from "ramda";
import CheckBoxFE from "../../../../../common/fieldEditors/CheckBoxFE";
import NumberFE from "../../../../../common/fieldEditors/NumberFE";
import SelectFE from "../../../../../common/fieldEditors/SelectFE";
import SwitchFE from "../../../../../common/fieldEditors/SwitchFE";
import { useFormContextPlus } from "../../../../../common/Form";
import { TSFormFields, SEASONAL_CORRELATION_OPTIONS, TSType } from "./utils";
import { TSFormFields, TSType } from "./utils";
import BooleanFE from "../../../../../common/fieldEditors/BooleanFE";
import { useTranslation } from "react-i18next";

const borderStyle = "1px solid rgba(255, 255, 255, 0.12)";

function Fields() {
const { control, getValues, setValue } = useFormContextPlus<TSFormFields>();
const { control, watch } = useFormContextPlus<TSFormFields>();
const isReadyMade = watch("thermal.stochasticTsStatus") === false;
const { t } = useTranslation();

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

return (
<TableContainer>
<Table sx={{ minWidth: "1050px" }} size="small">
<Table size="small" sx={{ width: "auto" }}>
<TableHead>
<TableRow sx={{ th: { py: 1, borderBottom: "none" } }}>
<TableCell />
<TableCell sx={{ borderRight: borderStyle }} align="center">
Ready made TS
</TableCell>
<TableCell
sx={{ borderRight: borderStyle }}
align="center"
colSpan={7}
>
Stochastic TS
</TableCell>
<TableCell align="center" colSpan={2}>
Draw correlation
</TableCell>
</TableRow>
<TableRow
sx={{
th: {
Expand All @@ -67,147 +51,48 @@ function Fields() {
}}
>
<TableCell />
<TableCell align="center">Status</TableCell>
<TableCell align="center">Status</TableCell>
<TableCell align="center">Number</TableCell>
<TableCell align="center">Refresh</TableCell>
<TableCell align="center">Refresh interval</TableCell>
<TableCell align="center">Season correlation</TableCell>
<TableCell align="center">Store in input</TableCell>
<TableCell align="center">Store in output</TableCell>
<TableCell align="center">Intra-modal</TableCell>
<TableCell align="center">inter-modal</TableCell>
<TableCell align="center">{t("global.status")}</TableCell>
<TableCell align="center">
{t("study.configuration.tsManagement.numberStochasticTs")}
</TableCell>
</TableRow>
</TableHead>
<TableBody
sx={{
"th, td": { borderBottom: borderStyle },
"tr:last-child td": {
borderBottomColor: "transparent", // 'border: none' change the color of `TableHead` border
},
}}
>
{R.values(TSType)
.filter((type) => !!getValues(type))
.map((type) => {
const isSpecialType =
type === TSType.Renewables || type === TSType.NTC;
const emptyDisplay = "-";
const notApplicableDisplay = "n/a";
const isReadyMadeStatusEnable = !getValues(
`${type}.stochasticTsStatus`,
);

const ifNotSpecialType = (
fn: (
t: Exclude<TSType, TSType.Renewables | TSType.NTC>,
) => React.ReactNode,
) => {
return isSpecialType ? emptyDisplay : fn(type);
};

return (
<TableRow key={type}>
<TableCell sx={{ fontWeight: "bold" }}>
{capitalize(type)}
</TableCell>
<TableCell align="center">
<SwitchFE
value={isReadyMadeStatusEnable}
onChange={(_, checked) => {
setValue(
`${type}.stochasticTsStatus`,
!checked as never,
);
}}
/>
</TableCell>
<TableCell align="center">
<SwitchFE
name={`${type}.stochasticTsStatus` as const}
control={control}
/>
</TableCell>
<TableCell align="center">
{ifNotSpecialType((t) => (
<NumberFE
name={`${t}.number` as const}
control={control}
size="small"
fullWidth
disabled={isReadyMadeStatusEnable}
/>
))}
</TableCell>
<TableCell align="center">
{ifNotSpecialType((t) => (
<CheckBoxFE
name={`${t}.refresh` as const}
control={control}
disabled={isReadyMadeStatusEnable}
/>
))}
</TableCell>
<TableCell align="center">
{ifNotSpecialType((t) => (
<NumberFE
name={`${t}.refreshInterval` as const}
control={control}
size="small"
fullWidth
disabled={isReadyMadeStatusEnable}
/>
))}
</TableCell>
<TableCell align="center">
{ifNotSpecialType((t) =>
t !== TSType.Thermal ? (
<SelectFE
name={`${t}.seasonCorrelation` as const}
options={SEASONAL_CORRELATION_OPTIONS}
control={control}
size="small"
disabled={isReadyMadeStatusEnable}
/>
) : (
notApplicableDisplay
),
)}
</TableCell>
<TableCell align="center">
{ifNotSpecialType((t) => (
<CheckBoxFE
name={`${t}.storeInInput` as const}
control={control}
disabled={isReadyMadeStatusEnable}
/>
))}
</TableCell>
<TableCell align="center">
{ifNotSpecialType((t) => (
<CheckBoxFE
name={`${t}.storeInOutput` as const}
control={control}
disabled={isReadyMadeStatusEnable}
/>
))}
</TableCell>
<TableCell align="center">
<CheckBoxFE
name={`${type}.intraModal` as const}
control={control}
/>
</TableCell>
<TableCell align="center">
{type !== TSType.NTC ? (
<CheckBoxFE
name={`${type}.interModal` as const}
control={control}
/>
) : (
emptyDisplay
)}
</TableCell>
</TableRow>
);
})}
<TableRow>
<TableCell sx={{ fontWeight: "bold" }}>
{capitalize(TSType.Thermal)}
</TableCell>
<TableCell align="center">
<BooleanFE
name={"thermal.stochasticTsStatus"}
control={control}
trueText={t(
"study.configuration.tsManagement.status.toBeGenerated",
)}
falseText={t(
"study.configuration.tsManagement.status.readyMade",
)}
variant="outlined"
size="small"
/>
</TableCell>
<TableCell align="center">
<NumberFE
name={"thermal.number"}
control={control}
size="small"
disabled={isReadyMade}
sx={{ width: 80 }}
/>
</TableCell>
</TableRow>
</TableBody>
</Table>
</TableContainer>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,43 @@
*/

import { useOutletContext } from "react-router";
import { StudyMetadata } from "../../../../../../common/types";
import type { StudyMetadata } from "../../../../../../common/types";
import Form from "../../../../../common/Form";
import { SubmitHandlerPlus } from "../../../../../common/Form/types";
import type { SubmitHandlerPlus } from "../../../../../common/Form/types";
import Fields from "./Fields";
import {
getTimeSeriesFormFields,
setTimeSeriesFormFields,
TSFormFields,
} from "./utils";
import { useTranslation } from "react-i18next";
import usePromiseHandler from "../../../../../../hooks/usePromiseHandler";
import { generateTimeSeries } from "../../../../../../services/api/studies/timeseries";
import BuildIcon from "@mui/icons-material/Build";

function TimeSeriesManagement() {
const { study } = useOutletContext<{ study: StudyMetadata }>();
const { t } = useTranslation();

const handleGenerateTs = usePromiseHandler({
fn: generateTimeSeries,
errorMessage: t("study.configuration.tsManagement.generateTs.error"),
pendingMessage: t("study.configuration.tsManagement.generateTs.pending"),
});

////////////////////////////////////////////////////////////////
// Event Handlers
////////////////////////////////////////////////////////////////

const handleSubmit = async (data: SubmitHandlerPlus<TSFormFields>) => {
const handleSubmit = (data: SubmitHandlerPlus<TSFormFields>) => {
return setTimeSeriesFormFields(study.id, data.dirtyValues);
};

const handleSubmitSuccessful = () => {
// The WebSocket will trigger an event after the fulfillment of the promise
handleGenerateTs({ studyId: study.id });
};

////////////////////////////////////////////////////////////////
// JSX
////////////////////////////////////////////////////////////////
Expand All @@ -43,7 +59,10 @@ function TimeSeriesManagement() {
key={study.id}
config={{ defaultValues: () => getTimeSeriesFormFields(study.id) }}
onSubmit={handleSubmit}
enableUndoRedo
onSubmitSuccessful={handleSubmitSuccessful}
submitButtonText={t("study.configuration.tsManagement.generateTs")}
submitButtonIcon={<BuildIcon />}
allowSubmitOnPristine
>
<Fields />
</Form>
Expand Down
7 changes: 4 additions & 3 deletions webapp/src/components/App/Tasks/NotificationBadge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,16 @@ function NotificationBadge(props: Props) {
);

useEffect(() => {
const listener = async (ev: WSMessage) => {
const listener = async (ev: WSMessage<TaskEventPayload>) => {
if (ev.type === WSEvent.DOWNLOAD_CREATED) {
newNotification("downloads.newDownload");
} else if (ev.type === WSEvent.DOWNLOAD_READY) {
newNotification("downloads.downloadReady");
} else if (ev.type === WSEvent.DOWNLOAD_FAILED) {
newNotification("study.error.exportOutput", "error");
} else if (ev.type === WSEvent.TASK_ADDED) {
const taskId = (ev.payload as TaskEventPayload).id;
try {
const task = await getTask(taskId);
const task = await getTask(ev.payload.id);
if (task.type === "COPY") {
newNotification("studies.studycopying");
} else if (task.type === "ARCHIVE") {
Expand All @@ -78,6 +77,8 @@ function NotificationBadge(props: Props) {
newNotification("studies.success.scanFolder");
} else if (task.type === "UPGRADE_STUDY") {
newNotification("study.message.upgradeInProgress");
} else if (task.type === "THERMAL_CLUSTER_SERIES_GENERATION") {
newNotification("tasks.thermalClusterSeriesGeneration");
}
} catch (error) {
logError(error);
Expand Down
Loading

0 comments on commit 449b2f7

Please sign in to comment.