Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

In the settings panel under the "Sort column" setting, clicking the s… #3682

Merged
merged 3 commits into from
Apr 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions components/frontend/src/AppUI.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ export function AppUI({
clearVisibleDetailsTabs={clearVisibleDetailsTabs}
dateInterval={dateInterval}
dateOrder={dateOrder}
handleSort={handleSort}
hiddenColumns={hiddenColumns}
hideMetricsNotRequiringAction={hideMetricsNotRequiringAction}
nrDates={nrDates}
Expand All @@ -109,8 +110,6 @@ export function AppUI({
setShowIssueCreationDate={setShowIssueCreationDate}
setShowIssueSummary={setShowIssueSummary}
setShowIssueUpdateDate={setShowIssueUpdateDate}
setSortColumn={setSortColumn}
setSortDirection={setSortDirection}
setUIMode={setUIMode}
showIssueCreationDate={showIssueCreationDate}
showIssueSummary={showIssueSummary}
Expand Down
51 changes: 24 additions & 27 deletions components/frontend/src/header_footer/ViewPanel.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { Button, Grid, Header, Menu, Segment } from 'semantic-ui-react';
import { Popup } from '../semantic_ui_react_wrappers';
import { Icon, Popup } from '../semantic_ui_react_wrappers';
import { capitalize, pluralize } from "../utils";
import './ViewPanel.css';

Expand All @@ -11,6 +11,7 @@ export function ViewPanel({
clearVisibleDetailsTabs,
dateInterval,
dateOrder,
handleSort,
hiddenColumns,
hideMetricsNotRequiringAction,
nrDates,
Expand All @@ -21,8 +22,6 @@ export function ViewPanel({
setShowIssueCreationDate,
setShowIssueSummary,
setShowIssueUpdateDate,
setSortColumn,
setSortDirection,
setUIMode,
showIssueCreationDate,
showIssueSummary,
Expand All @@ -35,7 +34,7 @@ export function ViewPanel({
}) {
const multipleDateColumns = nrDates > 1
const oneDateColumn = nrDates === 1
const sortOrderNotChangeable = sortColumn === null || (multipleDateColumns && ["status", "measurement", "target"].includes(sortColumn))
hiddenColumns = hiddenColumns ?? [];
return (
<Segment.Group
horizontal
Expand Down Expand Up @@ -76,14 +75,13 @@ export function ViewPanel({
clearVisibleDetailsTabs();
setHideMetricsNotRequiringAction(false);
clearHiddenColumns();
handleSort(null);
setNrDates(1);
setDateInterval(7);
setDateOrder("descending");
setShowIssueCreationDate(false);
setShowIssueSummary(false);
setShowIssueUpdateDate(false);
setSortColumn(null);
setSortDirection("ascending");
setUIMode(null);
}}
inverted
Expand Down Expand Up @@ -126,22 +124,15 @@ export function ViewPanel({
<Segment inverted color="black">
<Header size="small">Sort column</Header>
<Menu vertical inverted size="small">
<SortColumnMenuItem column="name" sortColumn={sortColumn} setSortColumn={setSortColumn} />
<SortColumnMenuItem column="status" disabled={multipleDateColumns} sortColumn={sortColumn} setSortColumn={setSortColumn} />
<SortColumnMenuItem column="measurement" disabled={multipleDateColumns} sortColumn={sortColumn} setSortColumn={setSortColumn} />
<SortColumnMenuItem column="target" disabled={multipleDateColumns} sortColumn={sortColumn} setSortColumn={setSortColumn} />
<SortColumnMenuItem column="unit" sortColumn={sortColumn} setSortColumn={setSortColumn} />
<SortColumnMenuItem column="source" sortColumn={sortColumn} setSortColumn={setSortColumn} />
<SortColumnMenuItem column="comment" sortColumn={sortColumn} setSortColumn={setSortColumn} />
<SortColumnMenuItem column="issues" sortColumn={sortColumn} setSortColumn={setSortColumn} />
<SortColumnMenuItem column="tags" sortColumn={sortColumn} setSortColumn={setSortColumn} />
</Menu>
</Segment>
<Segment inverted color="black">
<Header size='small'>Sort direction</Header>
<Menu vertical inverted size="small">
<SortOrderMenuItem disabled={sortOrderNotChangeable} order="ascending" sortOrder={sortDirection} setSortOrder={setSortDirection} />
<SortOrderMenuItem disabled={sortOrderNotChangeable} order="descending" sortOrder={sortDirection} setSortOrder={setSortDirection} />
<SortColumnMenuItem column="name" sortColumn={sortColumn} sortDirection={sortDirection} handleSort={handleSort} />
<SortColumnMenuItem column="status" disabled={multipleDateColumns || hiddenColumns.includes("status")} sortColumn={sortColumn} sortDirection={sortDirection} handleSort={handleSort} />
<SortColumnMenuItem column="measurement" disabled={multipleDateColumns || hiddenColumns.includes("measurement")} sortColumn={sortColumn} sortDirection={sortDirection} handleSort={handleSort} />
<SortColumnMenuItem column="target" disabled={multipleDateColumns || hiddenColumns.includes("target")} sortColumn={sortColumn} sortDirection={sortDirection} handleSort={handleSort} />
<SortColumnMenuItem column="unit" disabled={hiddenColumns.includes("unit")} sortColumn={sortColumn} sortDirection={sortDirection} handleSort={handleSort} />
<SortColumnMenuItem column="source" disabled={hiddenColumns.includes("source")} sortColumn={sortColumn} sortDirection={sortDirection} handleSort={handleSort} />
<SortColumnMenuItem column="comment" disabled={hiddenColumns.includes("comment")} sortColumn={sortColumn} sortDirection={sortDirection} handleSort={handleSort} />
<SortColumnMenuItem column="issues" disabled={hiddenColumns.includes("issues")} sortColumn={sortColumn} sortDirection={sortDirection} handleSort={handleSort} />
<SortColumnMenuItem column="tags" disabled={hiddenColumns.includes("tags")} sortColumn={sortColumn} sortDirection={sortDirection} handleSort={handleSort} />
</Menu>
</Segment>
<Segment inverted color="black">
Expand Down Expand Up @@ -208,12 +199,18 @@ function VisibleColumnMenuItem({ column, disabled, hiddenColumns, toggleHiddenCo
)
}

function SortColumnMenuItem({ column, disabled, sortColumn, setSortColumn }) {
const newColumn = sortColumn === column ? null : column
function SortColumnMenuItem({ column, disabled, sortColumn, sortDirection, handleSort }) {
const active = disabled ? false : sortColumn === column;
let sortIndicator = null;
if (sortColumn === column && sortDirection) {
// We use a triangle because the sort down and up icons are not at the same height
const iconDirection = sortDirection === "ascending" ? "up" : "down"
sortIndicator = <Icon disabled={disabled} name={`triangle ${iconDirection}`} aria-label={`sorted ${sortDirection}`} />
}
return (
<div onKeyPress={(event) => { event.preventDefault(); setSortColumn(newColumn) }} tabIndex={0}>
<Menu.Item active={disabled ? false : sortColumn === column} color={activeColor} disabled={disabled} onClick={() => setSortColumn(newColumn)}>
{capitalize(column === "name" ? "metric" : column)}
<div onKeyPress={(event) => { event.preventDefault(); if (!disabled) { handleSort(column) } }} tabIndex={0}>
<Menu.Item active={active} color={activeColor} disabled={disabled} onClick={() => handleSort(column)}>
{capitalize(column === "name" ? "metric" : column)} <span>{sortIndicator}</span>
</Menu.Item>
</div>
)
Expand Down
41 changes: 19 additions & 22 deletions components/frontend/src/header_footer/ViewPanel.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,14 @@ function eventHandlers() {
return {
clearHiddenColumns: jest.fn(),
clearVisibleDetailsTabs: jest.fn(),
handleSort: jest.fn(),
setDateInterval: jest.fn(),
setDateOrder: jest.fn(),
setHideMetricsNotRequiringAction: jest.fn(),
setNrDates: jest.fn(),
setShowIssueCreationDate: jest.fn(),
setShowIssueSummary: jest.fn(),
setShowIssueUpdateDate: jest.fn(),
setSortColumn: jest.fn(),
setSortDirection: jest.fn(),
setUIMode: jest.fn()
}
}
Expand Down Expand Up @@ -61,15 +60,14 @@ it('resets the settings', async () => {
});
expect(props.clearVisibleDetailsTabs).toHaveBeenCalled()
expect(props.clearHiddenColumns).toHaveBeenCalled()
expect(props.handleSort).toHaveBeenCalled()
expect(props.setDateInterval).toHaveBeenCalled()
expect(props.setDateOrder).toHaveBeenCalled()
expect(props.setNrDates).toHaveBeenCalled()
expect(props.setHideMetricsNotRequiringAction).toHaveBeenCalled()
expect(props.setShowIssueCreationDate).toHaveBeenCalledWith(false)
expect(props.setShowIssueSummary).toHaveBeenCalledWith(false)
expect(props.setShowIssueUpdateDate).toHaveBeenCalledWith(false)
expect(props.setSortColumn).toHaveBeenCalledWith(null)
expect(props.setSortDirection).toHaveBeenCalledWith("ascending")
expect(props.setUIMode).toHaveBeenCalledWith(null)
})

Expand Down Expand Up @@ -97,15 +95,14 @@ it('does not reset the settings when all have the default value', async () => {
});
expect(props.clearVisibleDetailsTabs).not.toHaveBeenCalled()
expect(props.clearHiddenColumns).not.toHaveBeenCalled()
expect(props.handleSort).not.toHaveBeenCalled()
expect(props.setDateInterval).not.toHaveBeenCalled()
expect(props.setDateOrder).not.toHaveBeenCalled()
expect(props.setNrDates).not.toHaveBeenCalled()
expect(props.setHideMetricsNotRequiringAction).not.toHaveBeenCalled()
expect(props.setShowIssueCreationDate).not.toHaveBeenCalled()
expect(props.setShowIssueSummary).not.toHaveBeenCalled()
expect(props.setShowIssueUpdateDate).not.toHaveBeenCalled()
expect(props.setSortColumn).not.toHaveBeenCalled()
expect(props.setSortDirection).not.toHaveBeenCalled()
expect(props.setUIMode).not.toHaveBeenCalled()
})

Expand Down Expand Up @@ -191,39 +188,39 @@ it("shows a column", async () => {
})

it("sorts a column", async () => {
const setSortColumn = jest.fn();
const handleSort = jest.fn();
await act(async () => {
render(<ViewPanel setSortColumn={setSortColumn} />)
render(<ViewPanel handleSort={handleSort} />)
fireEvent.click(screen.getAllByText(/Comment/)[1])
});
expect(setSortColumn).toHaveBeenCalledWith("comment")
expect(handleSort).toHaveBeenCalledWith("comment")
})

it("unsorts a column", async () => {
const setSortColumn = jest.fn();
it("sorts a column descending", async () => {
const handleSort = jest.fn();
await act(async () => {
render(<ViewPanel setSortColumn={setSortColumn} sortColumn="comment" />)
render(<ViewPanel sortColumn="comment" sortDirection="ascending" handleSort={handleSort} />)
fireEvent.click(screen.getAllByText(/Comment/)[1])
});
expect(setSortColumn).toHaveBeenCalledWith(null)
expect(handleSort).toHaveBeenCalledWith("comment")
})

it("sorts a column by keypress", async () => {
const setSortColumn = jest.fn();
const handleSort = jest.fn();
await act(async () => {
render(<ViewPanel setSortColumn={setSortColumn} />)
render(<ViewPanel handleSort={handleSort} />)
await userEvent.type(screen.getAllByText(/Comment/)[1], "{Enter}")
});
expect(setSortColumn).toHaveBeenCalledWith("comment")
expect(handleSort).toHaveBeenCalledWith("comment")
})

it("unsorts a column by keypress", async () => {
const setSortColumn = jest.fn();
it("ignores a keypress if the menu item is disabled", async () => {
const handleSort = jest.fn();
await act(async () => {
render(<ViewPanel setSortColumn={setSortColumn} sortColumn="comment" />)
render(<ViewPanel hiddenColumns={["comment"]} handleSort={handleSort} />)
await userEvent.type(screen.getAllByText(/Comment/)[1], "{Enter}")
});
expect(setSortColumn).toHaveBeenCalledWith(null)
expect(handleSort).not.toHaveBeenCalledWith("comment")
})

it("sets the number of dates", async () => {
Expand Down Expand Up @@ -275,7 +272,7 @@ it("sorts the dates descending", async () => {
const setDateOrder = jest.fn();
await act(async () => {
render(<ViewPanel dateOrder="ascending" setDateOrder={setDateOrder} />)
fireEvent.click(screen.getAllByText(/Descending/)[1])
fireEvent.click(screen.getByText(/Descending/))
});
expect(setDateOrder).toHaveBeenCalledWith("descending")
})
Expand All @@ -284,7 +281,7 @@ it("sorts the dates ascending by keypress", async () => {
const setDateOrder = jest.fn();
await act(async () => {
render(<ViewPanel dateOrder="descending" setDateOrder={setDateOrder} />)
await userEvent.type(screen.getAllByText(/Ascending/)[1], "{Enter}")
await userEvent.type(screen.getByText(/Ascending/), "{Enter}")
});
expect(setDateOrder).toHaveBeenCalledWith("ascending")
})
Expand Down
6 changes: 5 additions & 1 deletion docs/src/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

<!-- The line "## <square-bracket>Unreleased</square-bracket>" is replaced by the release/release.py script with the new release version and release date. -->

## v3.35.0-rc.2 - 2022-04-06
## [Unreleased]

### Fixed

- When using Axe CVS as source for the accessibility violations metric, the "nested-interactive" violation type would be ignored by *Quality-time*. Fixes [#3628](https://github.com/ICTU/quality-time/issues/3628).
- When using Gatling as source for the source version metric, the source version would not be found, when the version number was not present on the first line of the simulation.log. Fixes [#3661](https://github.com/ICTU/quality-time/issues/3661).

### Changed

- In the settings panel under the "Sort column" setting, clicking the same column multiple times now alternates between ascending and descending sort order. This makes the setting consistent with how column headers behave. It also removes the need for a separate "Sort direction" setting in the settings panel. Closes [#3646](https://github.com/ICTU/quality-time/issues/3646).

### Removed

- The Axe CSV "violation type" parameter that could be used to select which violation types to count has been removed to help fix [#3628](https://github.com/ICTU/quality-time/issues/3628). The parameter was already not very practical to ignore certain violation types because it would require the user to select all violation types except the ones to be ignored. Also, if Axe adds new violation types, *Quality-time* would need to be updated to prevent it from ignoring the new violation types.
Expand Down