diff --git a/src/components/editor/faultTree/menu/faultEvent/FaultEventMenu.tsx b/src/components/editor/faultTree/menu/faultEvent/FaultEventMenu.tsx index dbcdd897..2608d902 100644 --- a/src/components/editor/faultTree/menu/faultEvent/FaultEventMenu.tsx +++ b/src/components/editor/faultTree/menu/faultEvent/FaultEventMenu.tsx @@ -28,10 +28,12 @@ import { useSelectedSystemSummaries } from "@hooks/useSelectedSystemSummaries"; import { useForm } from "react-hook-form"; import UnsavedChangesDialog from "./UnsavedChangesDialog"; import { useAppBar } from "@contexts/AppBarContext"; -import { warnIcon } from "@components/Icons"; +import { syncProblemIcon, warnIcon } from "@components/Icons"; +import HintText from "@components/hintText/HintText"; interface Props { selectedShapeToolData?: FaultEvent; + outOfSync?: string; onEventUpdated: (faultEvent: FaultEvent) => void; refreshTree: () => void; rootIri?: string; @@ -60,7 +62,7 @@ const getFailureRateIris = (supertypes) => { ); }; -const FaultEventMenu = ({ selectedShapeToolData, onEventUpdated, refreshTree, rootIri }: Props) => { +const FaultEventMenu = ({ selectedShapeToolData, outOfSync = null, onEventUpdated, refreshTree, rootIri }: Props) => { const { t } = useTranslation(); const formMethods = useForm(); const { formState, getValues } = formMethods; @@ -289,12 +291,68 @@ const FaultEventMenu = ({ selectedShapeToolData, onEventUpdated, refreshTree, ro const basedFailureRate = shapeToolData?.supertypes?.hasFailureRate?.estimate?.value; const { predictionIri, operationalIri } = getFailureRateIris(shapeToolData?.supertypes?.supertypes); - const FailureRateBox = ({ value, label, rate, selected, outdated }) => ( + const propertyLabelWithHint = (propertyKey: string) => { + return ( + + {t(propertyKey + ".title")} + : + + ); + }; + + const propertyWithValue = (propertyKey: string, value) => { + return ( + <> + {propertyLabelWithHint(propertyKey)} + + {value} + + + ); + }; + + const requiredFailureRateComponent = (failureRate, requirementStatusColor, violates) => { + return ( + + {propertyLabelWithHint("eventDescription.requiredFailureRate")} + + {failureRate}}> + {failureRate.toExponential(2)} + + {violates && + warnIcon( + {t("faultEventMessage.requirementViolated")}, + requirementStatusColor, + )} + + + ); + }; + + const calculatedFailureRateComponent = (failureRate, failureRateStatusColor, outOfSync) => { + return ( + + {propertyLabelWithHint("eventDescription.calculatedFailureRate")} + + {failureRate}}> + {failureRate.toExponential(2)} + + {outOfSync && + syncProblemIcon( + {t("faultEventMessage.outOfSyncValue")}, + failureRateStatusColor, + )} + + + ); + }; + + const FailureRateBox = ({ value, failureRateKey, rate, selected, outdated }) => ( } - label={`${label}:`} + label={propertyLabelWithHint(failureRateKey)} className={selected ? classes.selected : classes.notSelected} /> @@ -305,7 +363,7 @@ const FaultEventMenu = ({ selectedShapeToolData, onEventUpdated, refreshTree, ro ); - const renderFailureRateBox = (rateType, rateValue, iri, selectedRadioButton, labelKey) => { + const renderFailureRateBox = (rateType, rateValue, iri, selectedRadioButton, failureRateKey) => { const rate = shapeToolData.probability !== rateValue && shapeToolData?.selectedEstimate?.iri === iri ? shapeToolData.probability @@ -313,7 +371,17 @@ const FaultEventMenu = ({ selectedShapeToolData, onEventUpdated, refreshTree, ro const selected = selectedRadioButton === rateType; const outdated = selected && shapeToolData.probability !== rateValue; - return ; + const calculatedFailureRateStatusColor = outOfSync ? theme.notSynchronized.color : theme.main.black; + + return ( + + ); }; const violatesRequirement = @@ -321,6 +389,8 @@ const FaultEventMenu = ({ selectedShapeToolData, onEventUpdated, refreshTree, ro const requiredFailureRateStatusColor = violatesRequirement ? theme.requirementViolation.color : theme.main.black; + const calculatedFailureRateStatusColor = outOfSync ? theme.notSynchronized.color : theme.main.black; + return ( @@ -339,20 +409,12 @@ const FaultEventMenu = ({ selectedShapeToolData, onEventUpdated, refreshTree, ro {basedFailureRate && ( - {t("faultEventMenu.fhaBasedFailureRate")}: - {basedFailureRate.toExponential(2)} + {propertyWithValue("eventDescription.fhaBasedFailureRate", basedFailureRate.toExponential(2))} )} - {getRequiredFailureRate() && ( - - - {t("faultEventMenu.requiredFailureRate")}: - {getRequiredFailureRate().toExponential(2)} - - {violatesRequirement && warnIcon(t("faultEventMessage.requirementViolated"))} - - )} + {getRequiredFailureRate() && + requiredFailureRateComponent(getRequiredFailureRate(), requiredFailureRateStatusColor, violatesRequirement)} )} @@ -362,26 +424,24 @@ const FaultEventMenu = ({ selectedShapeToolData, onEventUpdated, refreshTree, ro <> {shapeToolData?.probability && ( - - {t("faultEventMenu.calculatedFailureRate")}: - {shapeToolData?.probability.toExponential(2)} - + {calculatedFailureRateComponent(shapeToolData.probability, calculatedFailureRateStatusColor, outOfSync)} )} {basedFailureRate && ( - {t("faultEventMenu.fhaBasedFailureRate")}: - {shapeToolData?.supertypes?.supertypes?.hasFailureRate?.estimate?.value.toExponential(2)} + {propertyWithValue( + "eventDescription.fhaBasedFailureRate", + shapeToolData?.supertypes?.supertypes?.hasFailureRate?.estimate?.value.toExponential(2), + )} )} {getRequiredFailureRate() && ( - {t("faultEventMenu.requiredFailureRate")}: - {getRequiredFailureRate().toExponential(2)} + {propertyWithValue("eventDescription.requiredFailureRate", getRequiredFailureRate().toExponential(2))} {violatesRequirement && warnIcon(t("faultEventMessage.requirementViolated"))} @@ -395,10 +455,7 @@ const FaultEventMenu = ({ selectedShapeToolData, onEventUpdated, refreshTree, ro <> {shapeToolData?.probability && ( - - {t("faultEventMenu.calculatedFailureRate")}: - {shapeToolData?.probability.toExponential(2)} - + {calculatedFailureRateComponent(shapeToolData.probability, calculatedFailureRateStatusColor, outOfSync)} )} @@ -415,7 +472,7 @@ const FaultEventMenu = ({ selectedShapeToolData, onEventUpdated, refreshTree, ro snsPredictedFailureRate, predictionIri, selectedRadioButton, - "faultEventMenu.predictedFailureRate", + "eventDescription.predictedFailureRate", )} {snsOperationalFailureRate && renderFailureRateBox( @@ -423,13 +480,13 @@ const FaultEventMenu = ({ selectedShapeToolData, onEventUpdated, refreshTree, ro snsOperationalFailureRate, operationalIri, selectedRadioButton, - "faultEventMenu.operationalFailureRate", + "eventDescription.operationalFailureRate", )} : <>} - label={`${t("faultEventMenu.manuallyDefinedFailureRate")}:`} + label={propertyLabelWithHint("eventDescription.manuallyDefinedFailureRate")} className={selectedRadioButton === RadioButtonType.Manual ? classes.selected : classes.notSelected} // Compensate the removal of the radio button, 16px is the MUI default left padding sx={snsOperationalFailureRate || snsPredictedFailureRate ? {} : { pl: "16px" }} @@ -455,7 +512,9 @@ const FaultEventMenu = ({ selectedShapeToolData, onEventUpdated, refreshTree, ro {/* EXTERNAL NODE */} {shapeToolData && shapeToolData.eventType === EventType.EXTERNAL && !shapeToolData.isReference && ( - {`${t("faultEventMenu.manuallyDefinedFailureRate")}:`} + + {propertyLabelWithHint("eventDescription.manuallyDefinedFailureRate")} + - {criticality && ( - - {t("faultEventMenu.criticality")}: - {criticality} - - )} + {criticality && {propertyWithValue("eventDescription.severity", criticality)}} {ataSystem && ( {t("faultEventMenu.ataSystem")}: diff --git a/src/components/hintText/HintText.styles.tsx b/src/components/hintText/HintText.styles.tsx index 5462f7ae..73c06f77 100644 --- a/src/components/hintText/HintText.styles.tsx +++ b/src/components/hintText/HintText.styles.tsx @@ -2,20 +2,12 @@ import { makeStyles } from "tss-react/mui"; import { Theme } from "@mui/material"; const useStyles = makeStyles()((theme: Theme) => ({ - container: { - width: "100%", - }, - innerContainer: { - position: "relative", - display: "inline-block", - }, - toolTip: { - position: "absolute", - top: -6, - right: -16, - }, hintFont: { - fontSize: 12, + fontSize: 16, + }, + helpIcon: { + transform: "scale(0.88)", + color: "#777777", }, })); diff --git a/src/components/hintText/HintText.tsx b/src/components/hintText/HintText.tsx index 5b79fe7b..8b0e6e6f 100644 --- a/src/components/hintText/HintText.tsx +++ b/src/components/hintText/HintText.tsx @@ -1,28 +1,19 @@ import React from "react"; -import { Typography, IconButton, Tooltip } from "@mui/material"; -import QuestionMarkIcon from "@mui/icons-material/QuestionMark"; +import { Tooltip } from "@mui/material"; import useStyles from "./HintText.styles"; +import { HelpOutline } from "@mui/icons-material"; interface HintTextProps { text: string; hint: string; } -const HintText: React.FC = ({ text, hint }) => { +const HintText: React.FC = ({ hint }) => { const { classes } = useStyles(); return ( -
-
- {text} -
- - - - - -
-
-
+ {hint}} arrow placement="bottom"> + + ); }; diff --git a/src/styles/App.styles.declarations.tsx b/src/styles/App.styles.declarations.tsx index f89071dd..841a1328 100644 --- a/src/styles/App.styles.declarations.tsx +++ b/src/styles/App.styles.declarations.tsx @@ -50,6 +50,9 @@ declare module "@mui/material/styles" { requirementViolation?: { color: COLOR; }; + hint?: { + fontSize: number; + }; } // allow configuration using `createMuiTheme` interface DeprecatedThemeOptions { diff --git a/src/styles/App.styles.tsx b/src/styles/App.styles.tsx index 9a36a4ae..ff9b9975 100644 --- a/src/styles/App.styles.tsx +++ b/src/styles/App.styles.tsx @@ -49,4 +49,7 @@ export const appTheme = createCustomMuiTheme({ requirementViolation: { color: "#FF0000", }, + hint: { + fontSize: 16, + }, });