Skip to content
This repository has been archived by the owner on Jul 2, 2024. It is now read-only.

DEVPROD-1976: Migrate downstream tasks table to LeafyGreen table #2309

Merged
merged 7 commits into from
Mar 22, 2024
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
23 changes: 11 additions & 12 deletions cypress/integration/version/downstream_projects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@ describe("Downstream Projects Tab", () => {
cy.visit(DOWNSTREAM_ROUTE);
});

it("shows the number of failed patches in the Downstream tab label", () => {
it("shows number of failed patches in the Downstream tab label", () => {
cy.dataCy("downstream-tab-badge").should("exist");
cy.dataCy("downstream-tab-badge").should("contain.text", "1");
});

it("shows the child patches", () => {
it("renders child patches", () => {
cy.dataCy("project-accordion").should("have.length", 3);
cy.dataCy("project-title").should("have.length", 3);
// On CI, none of the child patches failed, so no tables should be visible.
cy.dataCy("tasks-table").should("not.be.visible");
cy.dataCy("downstream-tasks-table").should("have.length", 3);
});

it("links to base commit", () => {
Expand All @@ -28,15 +27,15 @@ describe("Downstream Projects Tab", () => {
});

it("filters by test name", () => {
cy.dataCy("accordion-toggle").first().click();
cy.get("tbody").first().children().should("have.length", 1);
cy.toggleTableFilter(1);
cy.dataCy("taskname-input-wrapper")
cy.dataCy("task-name-filter").eq(1).click();
cy.dataCy("task-name-filter-wrapper")
.find("input")
.focus()
.type("filter")
.type("{enter}");
cy.get("tbody").first().contains("No Data");
.as("testnameInputWrapper");
cy.get("@testnameInputWrapper").focus();
cy.get("@testnameInputWrapper").type("generate-lint");
cy.get("@testnameInputWrapper").type("{enter}");
cy.location("search").should("not.contain", "generate-lint"); // Should not update the URL.
cy.contains("generate-lint").should("be.visible");
});

it("does not push query params to the URL", () => {
Expand Down
10 changes: 5 additions & 5 deletions src/analytics/patch/usePatchAnalytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ type Action =
| TaskSortCategory.BaseStatus
| TaskSortCategory.Variant;
}
| {
name: "Filter Downstream Tasks Table";
filterBy: string | string[];
}
| {
name: "Sort Downstream Tasks Table";
sortBy:
| TaskSortCategory.Name
| TaskSortCategory.Status
| TaskSortCategory.BaseStatus
| TaskSortCategory.Variant;
sortBy: TaskSortCategory | TaskSortCategory[];
}
| { name: "Restart"; abort: boolean }
| { name: "Schedule" }
Expand Down
10 changes: 5 additions & 5 deletions src/analytics/version/useVersionAnalytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ type Action =
| TaskSortCategory.BaseStatus
| TaskSortCategory.Variant;
}
| {
name: "Filter Downstream Tasks Table";
filterBy: string | string[];
}
| {
name: "Sort Downstream Tasks Table";
sortBy:
| TaskSortCategory.Name
| TaskSortCategory.Status
| TaskSortCategory.BaseStatus
| TaskSortCategory.Variant;
sortBy: TaskSortCategory | TaskSortCategory[];
}
| { name: "Restart"; abort: boolean }
| { name: "Schedule" }
Expand Down
8 changes: 4 additions & 4 deletions src/components/TasksTable/Columns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const getColumnsTemplate = ({
),
meta: {
search: {
"data-cy": "task-name-filter-popover",
"data-cy": "task-name-filter",
placeholder: "Task name regex",
},
},
Expand Down Expand Up @@ -87,7 +87,7 @@ export const getColumnsTemplate = ({
},
meta: {
treeSelect: {
"data-cy": "status-filter-popover",
"data-cy": "status-filter",
options: statusOptions,
},
},
Expand All @@ -113,7 +113,7 @@ export const getColumnsTemplate = ({
),
meta: {
treeSelect: {
"data-cy": "base-status-filter-popover",
"data-cy": "base-status-filter",
options: baseStatusOptions,
},
},
Expand Down Expand Up @@ -145,7 +145,7 @@ export const getColumnsTemplate = ({
),
meta: {
search: {
"data-cy": "variant-filter-popover",
"data-cy": "variant-filter",
placeholder: "Variant name regex",
},
},
Expand Down
184 changes: 49 additions & 135 deletions src/pages/version/downstreamTasks/DownstreamProjectAccordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,41 @@ import { useReducer } from "react";
import { useQuery } from "@apollo/client";
import styled from "@emotion/styled";
import { InlineCode } from "@leafygreen-ui/typography";
import { Skeleton } from "antd";
import { TableProps } from "antd/es/table";
import { Link, useParams } from "react-router-dom";
import { useVersionAnalytics } from "analytics";
import { Link } from "react-router-dom";
import { Accordion } from "components/Accordion";
import { PatchStatusBadge } from "components/PatchStatusBadge";
import TableControl from "components/Table/TableControl";
import TableWrapper from "components/Table/TableWrapper";
import TasksTable from "components/TasksTable";
import { getVersionRoute } from "constants/routes";
import { size } from "constants/tokens";
import { useToastContext } from "context/toast";
import {
Parameter,
SortDirection,
SortOrder,
Task,
TaskSortCategory,
VersionTasksQuery,
VersionTasksQueryVariables,
} from "gql/generated/types";
import { VERSION_TASKS } from "gql/queries";
import { usePolling, useTaskStatuses } from "hooks";
import { usePolling } from "hooks";
import { PatchStatus } from "types/patch";
import { queryString, string } from "utils";
import { string } from "utils";
import { ParametersModal } from "../ParametersModal";
import { DownstreamTasksTable } from "./DownstreamTasksTable";
import { reducer } from "./reducer";

const { parseSortString, toSortString } = queryString;
const { shortenGithash } = string;

const defaultSorts: SortOrder[] = [
{
Key: TaskSortCategory.Status,
Direction: SortDirection.Asc,
},
{
Key: TaskSortCategory.BaseStatus,
Direction: SortDirection.Desc,
},
];

interface DownstreamProjectAccordionProps {
baseVersionID: string;
githash: string;
Expand All @@ -56,122 +60,59 @@ export const DownstreamProjectAccordion: React.FC<
}) => {
const dispatchToast = useToastContext();

const { id } = useParams<{ id: string }>();
const { sendEvent } = useVersionAnalytics(id);

const defaultSort: SortOrder = {
Key: TaskSortCategory.Status,
Direction: SortDirection.Asc,
};

const [state, dispatch] = useReducer(reducer, {
baseStatuses: [],
limit: 10,
page: 0,
statuses: [],
taskName: "",
variant: "",
baseStatusesInputVal: [],
currentStatusesInputVal: [],
taskNameInputVal: "",
variantInputVal: "",
sorts: [defaultSort],
sorts: defaultSorts,
});

const { baseStatuses, limit, page, sorts, statuses, taskName, variant } =
state;

const variables = {
versionId: childPatchId,
taskFilterOptions: {
limit,
page,
statuses,
taskName,
variant,
sorts,
baseStatuses,
},
};

const { baseStatusesInputVal, currentStatusesInputVal } = state;
const { baseStatuses: currentBaseStatuses, currentStatuses } =
useTaskStatuses({
versionId: childPatchId,
});

const taskNameInputProps = {
placeholder: "Task name",
value: state.taskNameInputVal,
onChange: ({ target }) =>
dispatch({ type: "onChangeTaskNameInput", task: target.value }),
onFilter: () => dispatch({ type: "onFilterTaskNameInput" }),
};

const variantInputProps = {
placeholder: "Variant name",
value: state.variantInputVal,
onChange: ({ target }) =>
dispatch({
type: "onChangeVariantInput",
variant: target.value,
}),
onFilter: () => dispatch({ type: "onFilterVariantInput" }),
};

const baseStatusSelectorProps = {
state: baseStatusesInputVal,
tData: currentBaseStatuses,
onChange: (s: string[]) =>
dispatch({ type: "setAndSubmitBaseStatusesSelector", baseStatuses: s }),
};

const statusSelectorProps = {
state: currentStatusesInputVal,
tData: currentStatuses,
onChange: (s: string[]) =>
dispatch({
type: "setAndSubmitStatusesSelector",
statuses: s,
}),
};

const { data, refetch, startPolling, stopPolling } = useQuery<
VersionTasksQuery,
VersionTasksQueryVariables
>(VERSION_TASKS, {
variables,
variables: {
versionId: childPatchId,
taskFilterOptions: {
baseStatuses,
limit,
page,
sorts,
statuses,
taskName,
variant,
},
},
fetchPolicy: "cache-and-network",
onError: (err) => {
dispatchToast.error(`Error fetching downstream tasks ${err}`);
},
});
usePolling({ startPolling, stopPolling, refetch });

const showSkeleton = !data;
const { version } = data || {};
const { isPatch, tasks } = version || {};
const { count = 0, data: tasksData = [] } = tasks || {};

const variantTitle = (
<>
<ProjectTitleWrapper>
<span data-cy="project-title">{projectName}</span>
</ProjectTitleWrapper>
<PatchStatusBadge status={status} />
</>
);

const tableChangeHandler: TableProps<Task>["onChange"] = (...[, , sorter]) =>
dispatch({
type: "onSort",
sorts: parseSortString(toSortString(sorter)),
});

return (
<Wrapper data-cy="project-accordion">
<Accordion
defaultOpen={status === PatchStatus.Failed}
title={variantTitle}
title={
<>
<ProjectTitleWrapper>
<span data-cy="project-title">{projectName}</span>
</ProjectTitleWrapper>
<PatchStatusBadge status={status} />
</>
}
titleTag={FlexContainer}
subtitle={
<DownstreamMetadata
Expand All @@ -182,50 +123,23 @@ export const DownstreamProjectAccordion: React.FC<
}
>
<AccordionContents>
<TableWrapper
controls={
<TableControl
filteredCount={count}
totalCount={taskCount}
label="tasks"
onClear={() => dispatch({ type: "clearAllFilters" })}
onPageChange={(p) => {
dispatch({ type: "onChangePagination", page: p });
}}
onPageSizeChange={(l) => {
dispatch({ type: "onChangeLimit", limit: l });
}}
limit={limit}
page={page}
/>
}
>
{showSkeleton ? (
<Skeleton active title={false} paragraph={{ rows: 8 }} />
) : (
<TasksTable
baseStatusSelectorProps={baseStatusSelectorProps}
isPatch={isPatch}
onColumnHeaderClick={(sortField) =>
sendEvent({
name: "Sort Downstream Tasks Table",
sortBy: sortField,
})
}
sorts={sorts}
statusSelectorProps={statusSelectorProps}
tableChangeHandler={tableChangeHandler}
taskNameInputProps={taskNameInputProps}
tasks={tasksData}
variantInputProps={variantInputProps}
/>
)}
</TableWrapper>
<DownstreamTasksTable
childPatchId={childPatchId}
count={count}
dispatch={dispatch}
isPatch={isPatch}
limit={limit}
loading={showSkeleton}
page={page}
taskCount={taskCount}
tasks={tasksData}
/>
</AccordionContents>
</Accordion>
</Wrapper>
);
};

interface DownstreamMetadataProps {
baseVersionID: string;
githash: string;
Expand Down
Loading
Loading