From 9bdc6da6e2d24f83ec3fd122de714e8adc0f070c Mon Sep 17 00:00:00 2001 From: Frank Niessink Date: Wed, 25 Sep 2024 00:01:36 +0200 Subject: [PATCH] Migrate frontend components to MUI. - StatusIcon. Partially implements #9796. --- components/frontend/src/App.js | 1 + .../frontend/src/measurement/StatusIcon.css | 26 ------------- .../frontend/src/measurement/StatusIcon.js | 38 ++++++++----------- .../src/measurement/StatusIcon.test.js | 2 +- components/frontend/src/metric/Target.js | 28 +++++++------- components/frontend/src/metric/status.js | 18 +++++++++ .../frontend/src/subject/SubjectTableRow.js | 2 +- 7 files changed, 50 insertions(+), 65 deletions(-) delete mode 100644 components/frontend/src/measurement/StatusIcon.css diff --git a/components/frontend/src/App.js b/components/frontend/src/App.js index c05a67831b..5241036e43 100644 --- a/components/frontend/src/App.js +++ b/components/frontend/src/App.js @@ -19,6 +19,7 @@ const theme = createTheme({ colorSchemes: { dark: true, // Add a dark theme (light theme is available by default) }, + components: { MuiTooltip: { defaultProps: { arrow: true }, styleOverrides: { tooltip: { fontSize: "1em" } } } }, }) class App extends Component { diff --git a/components/frontend/src/measurement/StatusIcon.css b/components/frontend/src/measurement/StatusIcon.css deleted file mode 100644 index 4967fc5e92..0000000000 --- a/components/frontend/src/measurement/StatusIcon.css +++ /dev/null @@ -1,26 +0,0 @@ -i.inverted.circular.icon.target_met { - background-color: rgb(30, 148, 78) !important; -} - -i.inverted.circular.icon.target_not_met { - background-color: rgb(211, 59, 55) !important; -} - -i.inverted.circular.icon.near_target_met { - background-color: rgb(253, 197, 54) !important; -} - -i.inverted.circular.icon.debt_target_met { - background-color: rgb(140, 140, 140) !important; -} - -i.inverted.circular.icon.informative { - background-color: rgb(0, 165, 255) !important; -} - -i.inverted.circular.icon.unknown { - background-color: rgb(245, 245, 245) !important; - color: rgb(0, 0, 0); - border: solid 1px; - border-color: rgb(140, 140, 140); -} diff --git a/components/frontend/src/measurement/StatusIcon.js b/components/frontend/src/measurement/StatusIcon.js index 0d290e4289..fd73ed86b3 100644 --- a/components/frontend/src/measurement/StatusIcon.js +++ b/components/frontend/src/measurement/StatusIcon.js @@ -1,34 +1,28 @@ -import "./StatusIcon.css" - +import { Avatar, Tooltip } from "@mui/material" import { instanceOf, oneOfType, string } from "prop-types" -import { Icon } from "semantic-ui-react" -import { STATUS_SHORT_NAME, statusPropType } from "../metric/status" -import { Popup } from "../semantic_ui_react_wrappers" +import { STATUS_COLORS_MUI, STATUS_ICONS, STATUS_SHORT_NAME, statusPropType } from "../metric/status" import { TimeAgoWithDate } from "../widgets/TimeAgoWithDate" -export function StatusIcon({ status, status_start, size }) { +export function StatusIcon({ status, statusStart, size }) { status = status || "unknown" - const icon_name = { - target_met: "check", - near_target_met: "warning", - debt_target_met: "money", - target_not_met: "bolt", - informative: "info", - unknown: "question", - }[status] + const sizes = { small: 20, undefined: 32 } const statusName = STATUS_SHORT_NAME[status] - const icon = - return status_start ? ( - - {`${statusName} since`} - - ) : ( - icon + // Use Avatar to create a round inverted icon: + const iconStyle = { width: sizes[size], height: sizes[size], bgcolor: STATUS_COLORS_MUI[status] } + const icon = ( + + {STATUS_ICONS[status]} + ) + if (statusStart) { + const tooltipTitle = {`${statusName} since`} + return {icon} + } + return icon } StatusIcon.propTypes = { status: statusPropType, - status_start: oneOfType([string, instanceOf(Date)]), + statusStart: oneOfType([string, instanceOf(Date)]), size: string, } diff --git a/components/frontend/src/measurement/StatusIcon.test.js b/components/frontend/src/measurement/StatusIcon.test.js index 0ad025df06..909060dc5f 100644 --- a/components/frontend/src/measurement/StatusIcon.test.js +++ b/components/frontend/src/measurement/StatusIcon.test.js @@ -21,7 +21,7 @@ it("renders a question mark if the status is missing", () => { it("renders a popup with the date the status started", async () => { let startDate = new Date() startDate.setDate(startDate.getDate() - 4) - const { queryByLabelText, queryByText } = render() + const { queryByLabelText, queryByText } = render() await userEvent.hover(queryByLabelText(/Target met/)) await waitFor(() => { expect(queryByText("4 days ago")).not.toBe(null) diff --git a/components/frontend/src/metric/Target.js b/components/frontend/src/metric/Target.js index 315ad3a067..ba3fda5f49 100644 --- a/components/frontend/src/metric/Target.js +++ b/components/frontend/src/metric/Target.js @@ -1,15 +1,15 @@ +import { Box, Stack, Typography } from "@mui/material" import { bool, func, oneOf, string } from "prop-types" import { useContext } from "react" import { Segment } from "semantic-ui-react" import { set_metric_attribute } from "../api/metric" -import { DarkMode } from "../context/DarkMode" import { DataModel } from "../context/DataModel" import { EDIT_REPORT_PERMISSION } from "../context/Permissions" import { IntegerInput } from "../fields/IntegerInput" import { StringInput } from "../fields/StringInput" import { StatusIcon } from "../measurement/StatusIcon" -import { Header, Icon, Popup } from "../semantic_ui_react_wrappers" +import { Icon, Popup } from "../semantic_ui_react_wrappers" import { childrenPropType, labelPropType, metricPropType, scalePropType } from "../sharedPropTypes" import { capitalize, @@ -18,7 +18,7 @@ import { formatMetricValue, getMetricScale, } from "../utils" -import { STATUS_SHORT_NAME, statusPropType } from "./status" +import { STATUS_COLORS_MUI, STATUS_SHORT_NAME, statusPropType } from "./status" function smallerThan(target1, target2) { const t1 = target1 ?? `${Number.POSITIVE_INFINITY}` @@ -48,22 +48,20 @@ function debtTargetActive(metric, direction) { } function ColoredSegment({ children, color, show, status }) { - const darkMode = useContext(DarkMode) if (show === false) { return null } return ( - - -
- - {STATUS_SHORT_NAME[status]} - - {capitalize(color)} -
- {children} -
-
+ + + + {STATUS_SHORT_NAME[status]}  + + + + {capitalize(color)} + {children} + ) } ColoredSegment.propTypes = { diff --git a/components/frontend/src/metric/status.js b/components/frontend/src/metric/status.js index cef2ff999c..087a4ae103 100644 --- a/components/frontend/src/metric/status.js +++ b/components/frontend/src/metric/status.js @@ -1,5 +1,7 @@ // Metric status constants +import { Bolt, Check, Money, QuestionMark, Warning } from "@mui/icons-material" +import { blue, green, grey, orange, red } from "@mui/material/colors" import { oneOf } from "prop-types" import { HyperLink } from "../widgets/HyperLink" @@ -23,6 +25,22 @@ export const STATUS_COLORS_RGB = { informative: "rgb(0,165,255)", unknown: "rgb(245,245,245)", } +export const STATUS_COLORS_MUI = { + target_not_met: red[700], + target_met: green[600], + near_target_met: orange[300], + debt_target_met: grey[500], + informative: blue[500], + unknown: grey[300], +} +export const STATUS_ICONS = { + target_met: , + near_target_met: , + debt_target_met: , + target_not_met: , + informative: i, + unknown: , +} export const STATUS_NAME = { informative: "Informative", target_met: "Target met", diff --git a/components/frontend/src/subject/SubjectTableRow.js b/components/frontend/src/subject/SubjectTableRow.js index b62138dea3..705951900e 100644 --- a/components/frontend/src/subject/SubjectTableRow.js +++ b/components/frontend/src/subject/SubjectTableRow.js @@ -301,7 +301,7 @@ export function SubjectTableRow({ )} {nrDates === 1 && settings.hiddenColumns.excludes("status") && ( - + )} {nrDates === 1 && settings.hiddenColumns.excludes("measurement") && (