Skip to content

Commit

Permalink
DEVPROD-828: Add multisort to TaskDurationTable (#395)
Browse files Browse the repository at this point in the history
  • Loading branch information
SupaJoon authored Sep 25, 2024
1 parent 7a69eca commit 420f22c
Show file tree
Hide file tree
Showing 13 changed files with 353 additions and 115 deletions.
2 changes: 1 addition & 1 deletion apps/spruce/cypress/integration/page_tabs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe("Tabs", () => {
.should("have.attr", "aria-selected")
.and("eq", "true");
locationPathEquals(patches.duration.route);
cy.location("search").should("contain", "duration=DESC");
cy.location("search").should("contain", "sorts=DURATION%3ADESC");
});

it("Applies default sorts on task tab when switching from another tab without any filters", () => {
Expand Down
33 changes: 25 additions & 8 deletions apps/spruce/cypress/integration/version/task_duration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe("Task Duration Tab", () => {
cy.dataCy("task-duration-table-row").should("have.length", 1);
cy.location("search").should(
"include",
`duration=DESC&page=0&taskName=${filterText}`,
`page=0&sorts=DURATION%3ADESC&taskName=${filterText}`,
);
// Clear text filter.
cy.dataCy("task-name-filter-popover").click();
Expand All @@ -31,14 +31,14 @@ describe("Task Duration Tab", () => {
cy.dataCy("task-duration-table-row").should("have.length", 3);
cy.location("search").should(
"include",
"duration=DESC&page=0&statuses=running-umbrella%2Cstarted%2Cdispatched",
"page=0&sorts=DURATION%3ADESC&statuses=running-umbrella%2Cstarted%2Cdispatched",
);
// Clear status filter.
cy.dataCy("status-filter-popover").click();
cy.dataCy("tree-select-options").within(() =>
cy.contains("Succeeded").click({ force: true }),
);
cy.location("search").should("include", `duration=DESC&page=0`);
cy.location("search").should("include", "page=0&sorts=DURATION%3ADESC");
});

it("updates URL appropriately when build variant filter is applied", () => {
Expand All @@ -51,7 +51,7 @@ describe("Task Duration Tab", () => {
cy.dataCy("task-duration-table-row").should("have.length", 2);
cy.location("search").should(
"include",
`duration=DESC&page=0&variant=${filterText}`,
`page=0&sorts=DURATION%3ADESC&variant=${filterText}`,
);
// Clear text filter.
cy.dataCy("build-variant-filter-popover").click();
Expand All @@ -62,8 +62,10 @@ describe("Task Duration Tab", () => {

it("updates URL appropriately when sort is changing", () => {
const durationSortControl = "button[aria-label='Sort by Task Duration']";
const statusSortControl = "button[aria-label='Sort by Status']";
const variantSortControl = "button[aria-label='Sort by Build Variant']";
// The default sort (DURATION DESC) should be applied
cy.location("search").should("include", "duration=DESC");
cy.location("search").should("include", "sorts=DURATION%3ADESC");
const longestTask = "test-thirdparty";
cy.contains(longestTask).should("be.visible");
cy.dataCy("task-duration-table-row")
Expand All @@ -72,22 +74,37 @@ describe("Task Duration Tab", () => {
cy.get(durationSortControl).click();
cy.location("search").should("not.include", "duration");
cy.get(durationSortControl).click();
cy.location("search").should("include", "duration=ASC");
cy.location("search").should("include", "sorts=DURATION%3AASC");
const shortestTask = "test-auth";
cy.contains(shortestTask).should("be.visible");
cy.dataCy("task-duration-table-row")
.first()
.should("contain", shortestTask);
cy.get(statusSortControl).click();
cy.location("search").should(
"include",
"page=0&sorts=DURATION%3AASC%3BSTATUS%3AASC",
);
cy.get(statusSortControl).click();
cy.location("search").should(
"include",
"page=0&sorts=DURATION%3AASC%3BSTATUS%3ADESC",
);
cy.get(variantSortControl).click();
cy.location("search").should(
"include",
"page=0&sorts=DURATION%3AASC%3BSTATUS%3ADESC",
);
});

it("clearing all filters resets to the default sort", () => {
const durationSortControl = "button[aria-label='Sort by Task Duration']";
cy.get(durationSortControl).click();
cy.location("search").should("not.include", "duration");
cy.get(durationSortControl).click();
cy.location("search").should("include", "duration=ASC");
cy.location("search").should("include", "sorts=DURATION%3AASC");
cy.contains("Clear all filters").click();
cy.location("search").should("include", "duration=DESC");
cy.location("search").should("include", "sorts=DURATION%3ADESC");
});

it("shows message when no test results are found", () => {
Expand Down
1 change: 1 addition & 0 deletions apps/spruce/src/analytics/version/useVersionAnalytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type Action =
| { name: "Filtered downstream tasks table"; "filter.by": string | string[] }
| { name: "Filtered tasks table"; "filter.by": string | string[] }
| { name: "Filtered task duration table"; "filter.by": string | string[] }
| { name: "Sorted task duration table"; "sort.by": string | string[] }
| { name: "Viewed notification modal" }
| { name: "Viewed schedule tasks modal" }
| { name: "Clicked restart tasks button"; abort: boolean }
Expand Down
6 changes: 4 additions & 2 deletions apps/spruce/src/hooks/useTableSort/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import { queryString } from "utils";
const { getSortString } = queryString;

interface Props {
sendAnalyticsEvents?: (sorter?: SortingState) => void;
sendAnalyticsEvents?: (sorter: SortingState) => void;
// TODO: DEVPROD-11539 - Remove this prop and make the default behavior to use a single query param.
singleQueryParam?: boolean;
}

type CallbackType = (sorter: SortingState) => void;
Expand All @@ -32,7 +34,7 @@ export const useTableSort = (props?: Props): CallbackType => {
[TableQueryParams.SortBy]: undefined,
};

if (sorter.length === 1) {
if (sorter.length === 1 && !props?.singleQueryParam) {
const { desc, id } = sorter[0];
// @ts-expect-error: FIXME. This comment was added by an automated script.
nextQueryParams[TableQueryParams.SortDir] = desc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ export const ExecutionTasksTable: React.FC<Props> = ({
);

const tableSortHandler = useTableSort({
// @ts-expect-error: FIXME. This comment was added by an automated script.
sendAnalyticsEvents: (sorter: SortingState) =>
sendEvent({
name: "Sorted execution tasks table",
Expand Down
1 change: 0 additions & 1 deletion apps/spruce/src/pages/task/taskTabs/TestsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ export const TestsTable: React.FC<TestsTableProps> = ({ task }) => {
};

const tableSortHandler = useTableSort({
// @ts-expect-error: FIXME. This comment was added by an automated script.
sendAnalyticsEvents: (sorter: SortingState) =>
sendEvent({
name: "Sorted tests table",
Expand Down
37 changes: 22 additions & 15 deletions apps/spruce/src/pages/version/TaskDuration.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { useEffect } from "react";
import { useEffect, useState } from "react";
import { useQuery } from "@apollo/client";
import styled from "@emotion/styled";
import { useParams, useLocation } from "react-router-dom";
import { useVersionAnalytics } from "analytics";
import TableControl from "components/Table/TableControl";
import { DEFAULT_POLL_INTERVAL } from "constants/index";
import { PaginationQueryParams } from "constants/queryParams";
import { PaginationQueryParams, TableQueryParams } from "constants/queryParams";
import { slugs } from "constants/routes";
import { size } from "constants/tokens";
import { useToastContext } from "context/toast";
import {
SortDirection,
TaskSortCategory,
VersionTaskDurationsQuery,
VersionTaskDurationsQueryVariables,
} from "gql/generated/types";
Expand All @@ -26,7 +28,6 @@ const { parseQueryString } = queryString;
interface Props {
taskCount: number;
}

const TaskDuration: React.FC<Props> = ({ taskCount }) => {
const dispatchToast = useToastContext();
const { [slugs.versionId]: versionId } = useParams();
Expand All @@ -39,13 +40,13 @@ const TaskDuration: React.FC<Props> = ({ taskCount }) => {
const queryVariables = useQueryVariables(search, versionId);
const hasQueryVariables = Object.keys(parseQueryString(search)).length > 0;
const { limit, page } = queryVariables.taskFilterOptions;
const [hasInitialized, setHasInitialized] = useState(false);

useEffect(() => {
updateQueryParams({
[PatchTasksQueryParams.Duration]: "DESC",
// @ts-expect-error: FIXME. This comment was added by an automated script.
[PatchTasksQueryParams.Sorts]: undefined,
[TableQueryParams.Sorts]: defaultSort,
});
setHasInitialized(true);
}, []); // eslint-disable-line react-hooks/exhaustive-deps

const clearQueryParams = () => {
Expand All @@ -60,9 +61,7 @@ const TaskDuration: React.FC<Props> = ({ taskCount }) => {
[PatchTasksQueryParams.BaseStatuses]: undefined,
// @ts-expect-error: FIXME. This comment was added by an automated script.
[PaginationQueryParams.Page]: undefined,
[PatchTasksQueryParams.Duration]: "DESC",
// @ts-expect-error: FIXME. This comment was added by an automated script.
[PatchTasksQueryParams.Sorts]: undefined,
[TableQueryParams.Sorts]: defaultSort,
});
};

Expand Down Expand Up @@ -101,12 +100,18 @@ const TaskDuration: React.FC<Props> = ({ taskCount }) => {
page={page}
totalCount={taskCount}
/>
<TaskDurationTable
loading={loading}
// @ts-expect-error: FIXME. This comment was added by an automated script.
numLoadingRows={limit}
tasks={tasksData}
/>
{
// Ensures that the TaskDurationTable initial sort
// button states intialize with the correct default values.
hasInitialized && (
<TaskDurationTable
loading={loading}
// @ts-expect-error: FIXME. This comment was added by an automated script.
numLoadingRows={limit}
tasks={tasksData}
/>
)
}
{shouldShowBottomTableControl && (
<TableControlWrapper>
<TableControl
Expand Down Expand Up @@ -136,3 +141,5 @@ const TableControlWrapper = styled.div`
`;

export default TaskDuration;

const defaultSort = `${TaskSortCategory.Duration}:${SortDirection.Desc}`;
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@ import {
userEvent,
within,
} from "@evg-ui/lib/test_utils";
import { VersionTaskDurationsQuery } from "gql/generated/types";
import { TaskDurationTable } from "./TaskDurationTable";
import {
SortDirection,
TaskSortCategory,
VersionTaskDurationsQuery,
} from "gql/generated/types";
import { PatchTasksQueryParams } from "types/task";
import { getInitialParams, TaskDurationTable } from "./TaskDurationTable";

describe("taskDurationTable", () => {
describe("TaskDurationTable", () => {
it("renders all rows", () => {
render(
<MockedProvider>
Expand Down Expand Up @@ -37,6 +42,31 @@ describe("taskDurationTable", () => {
});
});

describe("getInitialParams", () => {
it("should get the correct initialSort when passed in sorts key", () => {
const { initialSort } = getInitialParams({
sorts: `${TaskSortCategory.Duration}:${SortDirection.Desc};${TaskSortCategory.Variant}:${SortDirection.Asc};${TaskSortCategory.Status}:${SortDirection.Asc};${TaskSortCategory.Name}:${SortDirection.Desc}`,
});
expect(initialSort).toEqual([
{
desc: true,
id: PatchTasksQueryParams.Duration,
},
{
desc: false,
id: PatchTasksQueryParams.Variant,
},
{
desc: false,
id: PatchTasksQueryParams.Statuses,
},
{
desc: true,
id: PatchTasksQueryParams.TaskName,
},
]);
});
});
const tasks: VersionTaskDurationsQuery["version"]["tasks"]["data"] = [
{
id: "spruce_ubuntu1604_check_codegen_patch_345da020487255d1b9fb87bed4ceb98397a0c5a5_624af28fa4cf4714c7a6c19a_22_04_04_13_28_48",
Expand Down
Loading

0 comments on commit 420f22c

Please sign in to comment.