Skip to content

Commit

Permalink
Increase contrast for disabled items in the menu bar.
Browse files Browse the repository at this point in the history
Fixes #10840.
  • Loading branch information
fniessink committed Feb 19, 2025
1 parent 775b36a commit 79d9da6
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 76 deletions.
35 changes: 35 additions & 0 deletions components/frontend/src/header_footer/buttons/AppBarbutton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Button, Tooltip } from "@mui/material"
import { grey } from "@mui/material/colors"
import { bool, element, func, object, string } from "prop-types"

import { childrenPropType } from "../../sharedPropTypes"

export function AppBarButton({ children, disabled, loading, onClick, startIcon, sx, tooltip }) {
return (
<Tooltip title={tooltip}>
<span /* https://mui.com/material-ui/react-tooltip/#disabled-elements */>
<Button
aria-label={tooltip}
color="inherit"
disabled={disabled}
loading={loading}
loadingPosition="start"
onClick={() => onClick()}
startIcon={startIcon}
sx={{ ...sx, height: "100%", "&:disabled": { color: grey[400] } }}
>
{children}
</Button>
</span>
</Tooltip>
)
}
AppBarButton.propTypes = {
children: childrenPropType,
disabled: bool,
loading: bool,
onClick: func,
startIcon: element,
sx: object,
tooltip: string,
}
24 changes: 10 additions & 14 deletions components/frontend/src/header_footer/buttons/CollapseButton.jsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
import UnfoldLessIcon from "@mui/icons-material/UnfoldLess"
import { Button, Tooltip } from "@mui/material"

import { stringsURLSearchQueryPropType } from "../../sharedPropTypes"

import { AppBarButton } from "./AppBarbutton"

export function CollapseButton({ expandedItems }) {
return (
<Tooltip title={"Collapse all headers and metrics"}>
<span /* https://mui.com/material-ui/react-tooltip/#disabled-elements */>
<Button
color="inherit"
disabled={expandedItems.equals([])}
onClick={() => expandedItems.reset()}
startIcon={<UnfoldLessIcon />}
sx={{ height: "100%" }}
>
Collapse all
</Button>
</span>
</Tooltip>
<AppBarButton
disabled={expandedItems.equals([])}
onClick={() => expandedItems.reset()}
startIcon={<UnfoldLessIcon />}
tooltip={"Collapse all headers and metrics"}
>
Collapse all
</AppBarButton>
)
}
CollapseButton.propTypes = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ it("resets the expanded items", () => {
const expandedItems = renderHook(() => useExpandedItemsSearchQuery())
expect(expandedItems.result.current.value).toStrictEqual(["tab"])
renderCollapseButton({ expandedItems: expandedItems.result.current })
fireEvent.click(screen.getByRole("button", { name: "Collapse all" }))
fireEvent.click(screen.getByRole("button", { name: /Collapse all/ }))
expandedItems.rerender()
expect(expandedItems.result.current.value).toStrictEqual([])
})
Expand All @@ -28,7 +28,7 @@ it("doesn't change the expanded items if there are none", () => {
const expandedItems = renderHook(() => useExpandedItemsSearchQuery())
expect(expandedItems.result.current.value).toStrictEqual([])
renderCollapseButton({ expandedItems: expandedItems.result.current })
fireEvent.click(screen.getByRole("button", { name: "Collapse all" }))
fireEvent.click(screen.getByRole("button", { name: /Collapse all/ }))
expandedItems.rerender()
expect(expandedItems.result.current.value).toStrictEqual([])
})
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import PictureAsPdf from "@mui/icons-material/PictureAsPdf"
import { Button, Tooltip } from "@mui/material"
import { string } from "prop-types"
import { useState } from "react"

import { get_report_pdf } from "../../api/report"
import { registeredURLSearchParams } from "../../hooks/url_search_query"
import { showMessage } from "../../widgets/toast"

import { AppBarButton } from "./AppBarbutton"

function downloadPDF(report_uuid, queryString, callback) {
const reportId = report_uuid ? `report-${report_uuid}` : "reports-overview"
return get_report_pdf(report_uuid, queryString)
Expand Down Expand Up @@ -39,25 +40,20 @@ export function DownloadAsPDFButton({ report_uuid }) {
const queryString = query.toString() ? "?" + query.toString() : ""
query.set("report_url", window.location.origin + window.location.pathname + queryString + window.location.hash)
const itemType = report_uuid ? "report" : "reports overview"
const label = `Download ${itemType} as PDF`
return (
<Tooltip title={`Generate a PDF version of the ${itemType} as currently displayed. This may take some time.`}>
<Button
aria-label={label}
color="inherit"
loading={loading}
loadingPosition="start"
onClick={() => {
setLoading(true)
downloadPDF(report_uuid, `?${query.toString()}`, () => {
setLoading(false)
})
}}
startIcon={<PictureAsPdf />}
>
Download as PDF
</Button>
</Tooltip>
<AppBarButton
loading={loading}
onClick={() => {
setLoading(true)
downloadPDF(report_uuid, `?${query.toString()}`, () => {
setLoading(false)
})
}}
startIcon={<PictureAsPdf />}
tooltip={`Generate a PDF version of the ${itemType} as currently displayed. This may take some time.`}
>
Download as PDF
</AppBarButton>
)
}
DownloadAsPDFButton.propTypes = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ beforeEach(() => {

test("DownloadAsPDFButton has the correct label for reports overview", () => {
render(<DownloadAsPDFButton />)
expect(screen.getAllByLabelText(/reports overview as PDF/).length).toBe(1)
// toBe(2) due to 10840-menubar-color-contrast-for-disabled-items
expect(screen.getAllByLabelText(/Generate a PDF version/).length).toBe(2)
})

test("DownloadAsPDFButton has the correct label for a report", () => {
render(<DownloadAsPDFButton report_uuid={"report_uuid"} />)
expect(screen.getAllByLabelText(/report as PDF/).length).toBe(1)
// toBe(2) due to 10840-menubar-color-contrast-for-disabled-items
expect(screen.getAllByLabelText(/Generate a PDF version/).length).toBe(2)
})

async function clickDownload(nrClicks = 1) {
Expand Down
32 changes: 15 additions & 17 deletions components/frontend/src/header_footer/buttons/HomeButton.jsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
import { Button, Tooltip, Typography } from "@mui/material"
import { Typography } from "@mui/material"
import { bool, func } from "prop-types"

import { AppBarButton } from "./AppBarbutton"

export function HomeButton({ atReportsOverview, openReportsOverview, setSettingsPanelVisible }) {
const label = "Go to reports overview"
return (
<Tooltip title={label}>
<span /* https://mui.com/material-ui/react-tooltip/#disabled-elements */>
<Button
color="inherit"
disabled={atReportsOverview}
onClick={() => {
setSettingsPanelVisible(false)
openReportsOverview()
}}
startIcon={<img height="28px" width="28px" src="/favicon.ico" alt={label} />}
sx={{ textTransform: "none" }}
>
<Typography variant="h3">Quality-time</Typography>
</Button>
</span>
</Tooltip>
<AppBarButton
disabled={atReportsOverview}
onClick={() => {
setSettingsPanelVisible(false)
openReportsOverview()
}}
startIcon={<img height="28px" width="28px" src="/favicon.ico" alt={label} />}
sx={{ textTransform: "none" }}
tooltip={label}
>
<Typography variant="h3">Quality-time</Typography>
</AppBarButton>
)
}
HomeButton.propTypes = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,23 @@
import SettingsBackupRestoreIcon from "@mui/icons-material/SettingsBackupRestore"
import { Button, Tooltip } from "@mui/material"
import { bool, func } from "prop-types"

import { optionalDatePropType, settingsPropType } from "../../sharedPropTypes"

import { AppBarButton } from "./AppBarbutton"

export function ResetSettingsButton({ atReportsOverview, handleDateChange, reportDate, settings }) {
const label = `Reset ${atReportsOverview ? "reports overview" : "this report's"} settings`
return (
<Tooltip title={label}>
<span /* https://mui.com/material-ui/react-tooltip/#disabled-elements */>
<Button
color="inherit"
disabled={settings.allDefault() && reportDate === null}
startIcon={<SettingsBackupRestoreIcon />}
onClick={() => {
handleDateChange(null)
settings.reset()
}}
sx={{ height: "100%" }}
>
Reset settings
</Button>
</span>
</Tooltip>
<AppBarButton
disabled={settings.allDefault() && reportDate === null}
onClick={() => {
handleDateChange(null)
settings.reset()
}}
startIcon={<SettingsBackupRestoreIcon />}
tooltip={`Reset ${atReportsOverview ? "reports overview" : "this report's"} settings`}
>
Reset settings
</AppBarButton>
)
}
ResetSettingsButton.propTypes = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown"
import ArrowRightIcon from "@mui/icons-material/ArrowRight"
import { Button } from "@mui/material"
import { bool, func } from "prop-types"

import { AppBarButton } from "./AppBarbutton"

export function SettingsButton({ settingsPanelVisible, setSettingsPanelVisible }) {
return (
<Button
color="inherit"
<AppBarButton
startIcon={settingsPanelVisible ? <ArrowDropDownIcon /> : <ArrowRightIcon />}
onClick={() => setSettingsPanelVisible(!settingsPanelVisible)}
>
Settings
</Button>
</AppBarButton>
)
}
SettingsButton.propTypes = {
Expand Down
1 change: 1 addition & 0 deletions docs/src/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ If your currently installed *Quality-time* version is not the latest version, pl

### Fixed

- Increase contrast for disabled items in the menu bar. Fixes [#10840](https://github.com/ICTU/quality-time/issues/10840).
- Links to documentation on Read the Docs for subjects, metrics, or sources with hyphens in their name wouldn't scroll to the right location. Fixes [#10843](https://github.com/ICTU/quality-time/issues/10843).
- The software documentation was outdated (among other things the API-server health check endpoint). Fixes [#10858](https://github.com/ICTU/quality-time/issues/10858).

Expand Down

0 comments on commit 79d9da6

Please sign in to comment.