Skip to content

Commit

Permalink
Migrate SUIR components to MUI.
Browse files Browse the repository at this point in the history
  • Loading branch information
fniessink committed Dec 25, 2024
1 parent 7f52974 commit fa74486
Show file tree
Hide file tree
Showing 31 changed files with 325 additions and 335 deletions.
7 changes: 3 additions & 4 deletions components/frontend/src/errorMessage.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import { bool, object, oneOfType, string } from "prop-types"
import { Grid } from "semantic-ui-react"

import { Message } from "./semantic_ui_react_wrappers"
import { WarningMessage } from "./widgets/WarningMessage"

export function ErrorMessage({ formatAsText, message, title }) {
return (
<Grid.Row>
<Grid.Column>
<Message negative>
<Message.Header>{title}</Message.Header>
<WarningMessage title={title}>
{formatAsText ? (
message
) : (
<pre style={{ whiteSpace: "pre-wrap", wordBreak: "break-all" }}>{message}</pre>
)}
</Message>
</WarningMessage>
</Grid.Column>
</Grid.Row>
)
Expand Down
36 changes: 28 additions & 8 deletions components/frontend/src/issue/IssueStatus.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,30 @@
import { Tooltip } from "@mui/material"
import { bool, string } from "prop-types"
import TimeAgo from "react-timeago"

import { Label, Popup } from "../semantic_ui_react_wrappers"
import { Label } from "../semantic_ui_react_wrappers"
import { issueStatusPropType, metricPropType, settingsPropType, stringsPropType } from "../sharedPropTypes"
import { getMetricIssueIds, ISSUE_STATUS_COLORS } from "../utils"
import { HyperLink } from "../widgets/HyperLink"
import { TimeAgoWithDate } from "../widgets/TimeAgoWithDate"

function IssueWithoutTracker({ issueId }) {
return (
<Popup
content={
"Please configure an issue tracker by expanding the report title, selecting the 'Issue tracker' tab, and configuring an issue tracker."
<Tooltip
title={
<>
<h4>No issue tracker configured</h4>
<p>
Please configure an issue tracker by expanding the report title, selecting the &lsquo;Issue
tracker&rsquo; tab, and configuring an issue tracker.
</p>
</>
}
header={"No issue tracker configured"}
trigger={<Label color="red">{issueId}</Label>}
/>
>
<span>
<Label color="red">{issueId}</Label>
</span>
</Tooltip>
)
}
IssueWithoutTracker.propTypes = {
Expand Down Expand Up @@ -160,7 +169,18 @@ function IssueWithTracker({ issueStatus, settings }) {
popupContent = issuePopupContent(issueStatus)
}
if (popupContent) {
label = <Popup header={popupHeader} content={popupContent} flowing hoverable trigger={label} />
label = (
<Tooltip
title={
<>
<h4>{popupHeader}</h4>
<p>{popupContent}</p>
</>
}
>
{label}
</Tooltip>
)
}
return label
}
Expand Down
11 changes: 6 additions & 5 deletions components/frontend/src/measurement/MeasurementTarget.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Tooltip } from "@mui/material"
import { useContext } from "react"

import { DataModel } from "../context/DataModel"
import { Label, Popup } from "../semantic_ui_react_wrappers"
import { Label } from "../semantic_ui_react_wrappers"
import { metricPropType } from "../sharedPropTypes"
import {
formatMetricDirection,
Expand Down Expand Up @@ -59,11 +60,11 @@ export function MeasurementTarget({ metric }) {
const today = new Date()
debtEndDateInThePast = endDate.toISOString().split("T")[0] < today.toISOString().split("T")[0]
}
const label = allIssuesDone || debtEndDateInThePast ? <Label color="grey">{target}</Label> : <span>{target}</span>
const label = allIssuesDone || debtEndDateInThePast ? <Label color="grey">{target}</Label> : target
return (
<Popup hoverable on={["hover", "focus"]} trigger={label}>
{popupText(metric, debtEndDateInThePast, allIssuesDone, dataModel)}
</Popup>
<Tooltip title={<span>{popupText(metric, debtEndDateInThePast, allIssuesDone, dataModel)}</span>}>
<span>{label}</span>
</Tooltip>
)
}
MeasurementTarget.propTypes = {
Expand Down
97 changes: 49 additions & 48 deletions components/frontend/src/measurement/MeasurementValue.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import "./MeasurementValue.css"

import { Alert, Tooltip, Typography } from "@mui/material"
import { bool, string } from "prop-types"
import { useContext } from "react"

import { DataModel } from "../context/DataModel"
import { Label, Message, Popup } from "../semantic_ui_react_wrappers"
import { Label } from "../semantic_ui_react_wrappers"
import { datePropType, measurementPropType, metricPropType } from "../sharedPropTypes"
import { IGNORABLE_SOURCE_ENTITY_STATUSES, SOURCE_ENTITY_STATUS_NAME } from "../source/source_entity_status"
import {
Expand All @@ -30,14 +31,20 @@ function measurementValueLabel(hasIgnoredEntities, stale, updating, value) {
value
)
if (stale) {
return <Label color="red">{measurementValue}</Label>
return (
<span>
<Label color="red">{measurementValue}</Label>
</span>
)
}
if (updating) {
return (
<Label color="yellow">
<LoadingIcon />
{measurementValue}
</Label>
<span>
<Label color="yellow">
<LoadingIcon />
{measurementValue}
</Label>
</span>
)
}
return <span>{measurementValue}</span>
Expand Down Expand Up @@ -101,49 +108,43 @@ export function MeasurementValue({ metric, reportDate }) {
const requested = isMeasurementRequested(metric)
const hasIgnoredEntities = sum(ignoredEntitiesCount(metric.latest_measurement)) > 0
return (
<Popup
trigger={measurementValueLabel(hasIgnoredEntities, stale, outdated || requested, value)}
flowing
hoverable
<Tooltip
slotProps={{ tooltip: { sx: { maxWidth: "32em" } } }}
title={
<div>
<WarningMessage showIf={stale} title="This metric was not recently measured">
This may indicate a problem with Quality-time itself. Please contact a system administrator.
</WarningMessage>
<WarningMessage showIf={outdated} title="Latest measurement out of date">
The source configuration of this metric was changed after the latest measurement.
</WarningMessage>
<WarningMessage showIf={requested} title="Measurement requested">
An update of the latest measurement was requested by a user.
</WarningMessage>
{hasIgnoredEntities && (
<Alert severity="info">
<Typography>
<IgnoreIcon /> {`Ignored ${unit}`}
</Typography>
{ignoredEntitiesMessage(metric.latest_measurement, unit)}
</Alert>
)}
{metric.latest_measurement && (
<>
<TimeAgoWithDate date={metric.latest_measurement.end}>
{metric.status ? "The metric was last measured" : "Last measurement attempt"}
</TimeAgoWithDate>
<br />
<TimeAgoWithDate date={metric.latest_measurement.start}>
{metric.status ? "The current value was first measured" : "The value is unknown since"}
</TimeAgoWithDate>
</>
)}
</div>
}
>
<WarningMessage
showIf={stale}
header="This metric was not recently measured"
content="This may indicate a problem with Quality-time itself. Please contact a system administrator."
/>
<WarningMessage
showIf={outdated}
header="Latest measurement out of date"
content="The source configuration of this metric was changed after the latest measurement."
/>
<WarningMessage
showIf={requested}
header="Measurement requested"
content="An update of the latest measurement was requested by a user."
/>
{hasIgnoredEntities && (
<Message
info
header={
<span>
<IgnoreIcon /> {`Ignored ${unit}`}
</span>
}
content={ignoredEntitiesMessage(metric.latest_measurement, unit)}
/>
)}
{metric.latest_measurement && (
<>
<TimeAgoWithDate date={metric.latest_measurement.end}>
{metric.status ? "The metric was last measured" : "Last measurement attempt"}
</TimeAgoWithDate>
<br />
<TimeAgoWithDate date={metric.latest_measurement.start}>
{metric.status ? "The current value was first measured" : "The value is unknown since"}
</TimeAgoWithDate>
</>
)}
</Popup>
{measurementValueLabel(hasIgnoredEntities, stale, outdated || requested, value)}
</Tooltip>
)
}
MeasurementValue.propTypes = {
Expand Down
115 changes: 63 additions & 52 deletions components/frontend/src/measurement/Overrun.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
import {
Paper,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Tooltip,
Typography,
} from "@mui/material"
import { string } from "prop-types"
import { useContext } from "react"

import { DataModel } from "../context/DataModel"
import { Header, Popup, Table } from "../semantic_ui_react_wrappers"
import { datesPropType, measurementsPropType, metricPropType, reportPropType } from "../sharedPropTypes"
import { getMetricResponseOverrun, pluralize } from "../utils"
import { StatusIcon } from "./StatusIcon"
Expand All @@ -23,59 +33,60 @@ export function Overrun({ metric_uuid, metric, report, measurements, dates }) {
const period = `${sortedDates.at(0).toLocaleDateString()} - ${sortedDates.at(-1).toLocaleDateString()}`
const content = (
<>
<Header>
<Header.Content>
Metric reaction time overruns
<Header.Subheader>In the period {period}</Header.Subheader>
</Header.Content>
</Header>
<Table compact size="small">
<Table.Header>
<Table.Row>
<Table.HeaderCell textAlign="center" colSpan="3">
When did the metric need action?
</Table.HeaderCell>
<Table.HeaderCell textAlign="center" colSpan="3">
How long did it take to react?
</Table.HeaderCell>
</Table.Row>
<Table.Row>
<Table.HeaderCell textAlign="center">Status</Table.HeaderCell>
<Table.HeaderCell textAlign="center">Start</Table.HeaderCell>
<Table.HeaderCell textAlign="center">End</Table.HeaderCell>
<Table.HeaderCell textAlign="right">Actual</Table.HeaderCell>
<Table.HeaderCell textAlign="right">Desired</Table.HeaderCell>
<Table.HeaderCell textAlign="right">Overrun</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
{overruns.map((overrun) => (
<Table.Row key={overrun.start}>
<Table.Cell textAlign="center">
<StatusIcon size="small" status={overrun.status} />
</Table.Cell>
<Table.Cell>{overrun.start.split("T")[0]}</Table.Cell>
<Table.Cell>{overrun.end.split("T")[0]}</Table.Cell>
<Table.Cell textAlign="right">{formatDays(overrun.actual_response_time)}</Table.Cell>
<Table.Cell textAlign="right">{formatDays(overrun.desired_response_time)}</Table.Cell>
<Table.Cell textAlign="right">{formatDays(overrun.overrun)}</Table.Cell>
</Table.Row>
))}
</Table.Body>
<Table.Footer>
<Table.Row>
<Table.HeaderCell colSpan="5">
<b>Total</b>
</Table.HeaderCell>
<Table.HeaderCell textAlign="right">
<b>{triggerText}</b>
</Table.HeaderCell>
</Table.Row>
</Table.Footer>
</Table>
<Typography>Metric reaction time overruns in the period {period}</Typography>
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow>
<TableCell align="center" colSpan="3">
When did the metric need action?
</TableCell>
<TableCell align="center" colSpan="3">
How long did it take to react?
</TableCell>
</TableRow>
<TableRow>
<TableCell align="left">Status</TableCell>
<TableCell align="left">Start</TableCell>
<TableCell align="left">End</TableCell>
<TableCell align="right">Actual</TableCell>
<TableCell align="right">Desired</TableCell>
<TableCell align="right">Overrun</TableCell>
</TableRow>
</TableHead>
<TableBody>
{overruns.map((overrun) => (
<TableRow key={overrun.start}>
<TableCell align="left">
<StatusIcon size="small" status={overrun.status} />
</TableCell>
<TableCell align="left">{overrun.start.split("T")[0]}</TableCell>
<TableCell align="left">{overrun.end.split("T")[0]}</TableCell>
<TableCell align="right">{formatDays(overrun.actual_response_time)}</TableCell>
<TableCell align="right">{formatDays(overrun.desired_response_time)}</TableCell>
<TableCell align="right">{formatDays(overrun.overrun)}</TableCell>
</TableRow>
))}
</TableBody>
<TableHead>
<TableRow>
<TableCell colSpan="5">
<b>Total</b>
</TableCell>
<TableCell align="right">
<b>{triggerText}</b>
</TableCell>
</TableRow>
</TableHead>
</Table>
</TableContainer>
</>
)
return <Popup content={content} flowing hoverable trigger={trigger} />
return (
<Tooltip slotProps={{ tooltip: { sx: { maxWidth: "40em" } } }} title={content}>
{trigger}
</Tooltip>
)
}
Overrun.propTypes = {
dates: datesPropType,
Expand Down
Loading

0 comments on commit fa74486

Please sign in to comment.