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

[BE][HUD] Introduce Label to GroupHudTable #5876

Open
wants to merge 29 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 13 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
6 changes: 4 additions & 2 deletions torchci/components/CommitStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import useScrollTo from "lib/useScrollTo";
import _ from "lodash";
import { useState } from "react";
import { linkIt, UrlComponent, urlRegex } from "react-linkify-it";
import { getConclusionSeverityForSorting } from "../lib/JobClassifierUtil";
import {
getConclusionSeverityForSorting,
JobStatus,
} from "../lib/JobClassifierUtil";
import FilteredJobList from "./FilteredJobList";
import { JobStatus } from "./GroupJobConclusion";
import VersionControlLinks from "./VersionControlLinks";
import WorkflowBox from "./WorkflowBox";
import WorkflowDispatcher from "./WorkflowDispatcher";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,108 @@
import hudStyles from "components/hud.module.css";
import styles from "components/JobConclusion.module.css";
import TooltipTarget from "components/TooltipTarget";
import { getGroupConclusionChar } from "lib/JobClassifierUtil";
import { GroupedJobStatus, JobStatus } from "lib/JobClassifierUtil";
import {
isFailedJob,
isRerunDisabledTestsJob,
isUnstableJob,
} from "lib/jobUtils";
import { GroupData, IssueData, JobData } from "lib/types";
import { cloneDeep } from "lodash";
import { PinnedTooltipContext } from "pages/hud/[repoOwner]/[repoName]/[branch]/[[...page]]";
import { useContext } from "react";
import hudStyles from "./hud.module.css";
import styles from "./JobConclusion.module.css";
import { SingleWorkflowDispatcher } from "./WorkflowDispatcher";
import { ImCross } from "react-icons/im";
import { IoMdCheckmark } from "react-icons/io";
import { MdFlaky } from "react-icons/md";
import { RiErrorWarningFill, RiProgress5Fill } from "react-icons/ri";
import { SlClock } from "react-icons/sl";
import { SingleWorkflowDispatcher } from "../WorkflowDispatcher";

export enum JobStatus {
Success = "success",
Failure = "failure",
Neutral = "neutral",
Cancelled = "cancelled",
Timed_out = "timed_out",
Skipped = "skipped",
Queued = "queued",
Pending = "pending",
// Conclusion Group Element used to render the conclusion group.
const conclusionGroupElements: Map<
string | undefined,
{ name: string; type: string; render: (className?: string) => JSX.Element }
> = new Map([
[
GroupedJobStatus.AllNull,

{
name: "all null",
type: GroupedJobStatus.AllNull,
render: (className) => <span className={className ?? ""}>~</span>,
},
],
[
GroupedJobStatus.Success,
{
name: "success",
type: GroupedJobStatus.Success,
render: (className) => <IoMdCheckmark className={className} />,
},
],
[
GroupedJobStatus.Failure,
{
name: "failure",
type: GroupedJobStatus.Failure,
render: (className) => <ImCross className={className ?? ""} />,
},
],
[
GroupedJobStatus.Queued,
{
name: "in queue",
type: GroupedJobStatus.Queued,
render: (className) => <RiProgress5Fill className={className ?? ""} />,
},
],
[
GroupedJobStatus.Pending,
{
name: "pending",
type: GroupedJobStatus.Pending,
render: (className) => <SlClock className={className ?? ""} />,
},
],
[
GroupedJobStatus.Classified,
{
name: "classified",
type: GroupedJobStatus.Classified,
render: (className) => <span className={className ?? ""}>X</span>,
},
],
[
GroupedJobStatus.Flaky,
{
name: "flaky",
type: GroupedJobStatus.Flaky,
render: (className) => <MdFlaky className={className ?? ""} />,
},
],
[
GroupedJobStatus.WarningOnly,
{
name: "warning only",
type: GroupedJobStatus.WarningOnly,
render: (className) => <RiErrorWarningFill className={className ?? ""} />,
},
],
]);

export function getGroupConclusionElementList() {
return cloneDeep(Array.from(conclusionGroupElements.values()));
}

export enum GroupedJobStatus {
Failure = "failure",
AllNull = "all_null",
Queued = "queued",
Success = "success",
Classified = "classified",
Flaky = "flaky",
WarningOnly = "warning",
Pending = "pending",
export function getGroupConclusionIcon(
conclusion?: GroupedJobStatus,
style?: string
) {
return conclusionGroupElements.has(conclusion) ? (
conclusionGroupElements.get(conclusion)?.render(style)
) : (
<span className={style ?? ""}>U</span>
);
}

export default function HudGroupedCell({
Expand All @@ -50,7 +121,7 @@ export default function HudGroupedCell({
unstableIssues: IssueData[];
}) {
const [pinnedId, setPinnedId] = useContext(PinnedTooltipContext);
const style = pinnedId.name == groupData.groupName ? hudStyles.highlight : "";
let style = pinnedId.name == groupData.groupName ? hudStyles.highlight : "";

const erroredJobs = [];
const warningOnlyJobs = [];
Expand Down Expand Up @@ -112,16 +183,13 @@ export default function HudGroupedCell({
}
>
<span className={styles.conclusion}>
<span
className={
<span onDoubleClick={toggleExpanded}>
{getGroupConclusionIcon(
conclusion,
isClassified
? styles["classified"]
: styles[conclusion ?? "none"]
}
onDoubleClick={toggleExpanded}
style={{ border: "1px solid gainsboro", padding: "0 1px" }}
>
{getGroupConclusionChar(conclusion)}
)}
</span>
</span>
</TooltipTarget>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { JobData } from "../lib/types";
import JobLinks from "./JobLinks";
import LogViewer from "./LogViewer";
import { SingleWorkflowDispatcher } from "./WorkflowDispatcher";
import { JobData } from "../../lib/types";
import JobLinks from "../JobLinks";
import LogViewer from "../LogViewer";
import { SingleWorkflowDispatcher } from "../WorkflowDispatcher";

export default function JobTooltip({
job,
Expand Down
6 changes: 4 additions & 2 deletions torchci/components/JobConclusion.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,11 @@
}

.flaky {
color: lightgreen;
font-size: 1.3em;
color: rgba(13, 169, 13, 0.797);
yangw-dev marked this conversation as resolved.
Show resolved Hide resolved
}

.warning {
color: #f8b88b;
font-size: 1.3em;
color: lightpink;
}
133 changes: 128 additions & 5 deletions torchci/components/JobConclusion.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,135 @@
import { getConclusionChar } from "lib/JobClassifierUtil";
import { JobStatus } from "lib/JobClassifierUtil";
import { cloneDeep } from "lodash";
import { useContext } from "react";
import { ImCross } from "react-icons/im";
import { IoBanOutline, IoCheckmarkSharp } from "react-icons/io5";
import { MdOutlineTimerOff } from "react-icons/md";
import { RiProgress5Fill } from "react-icons/ri";
import { SlClock } from "react-icons/sl";
import { JobData } from "../lib/types";
import { MonsterFailuresContext } from "../pages/hud/[repoOwner]/[repoName]/[branch]/[[...page]]";
import { JobStatus } from "./GroupJobConclusion";
import styles from "./JobConclusion.module.css";

// Conclustion Element used to render the conclusion of a job
const jobConclusionElementMap: Map<
string | undefined,
{ name: string; type: string; render: (className?: string) => JSX.Element }
> = new Map([
[
JobStatus.Cancelled,
{
name: "cancelled",
type: JobStatus.Cancelled,
render: (className?: string) => (
<IoBanOutline className={className ?? ""}></IoBanOutline>
),
},
],
[
JobStatus.Neutral,
{
name: "neutral",
type: JobStatus.Neutral,
render: (className?: string) => (
<span className={className ?? ""}>N</span>
),
},
],
[
undefined,
{
name: "not exist",
type: JobStatus.Success,
render: (className?: string) => (
<span className={className ?? ""}>~</span>
),
},
],
[
JobStatus.Failure,
{
name: "failure",
type: JobStatus.Failure,
render: (className?: string) => (
<ImCross className={className ?? ""}></ImCross>
),
},
],
[
JobStatus.Pending,
{
name: "pending",
type: JobStatus.Pending,
render: (className?: string) => (
<SlClock className={className ?? ""}></SlClock>
),
},
],
[
JobStatus.Queued,
{
name: "in queue",
type: JobStatus.Queued,
render: (className?: string) => (
<RiProgress5Fill className={className}></RiProgress5Fill>
),
},
],
[
JobStatus.Timed_out,
{
name: "time_out",
type: JobStatus.Timed_out,
render: (className?: string) => (
<MdOutlineTimerOff className={className ?? ""}></MdOutlineTimerOff>
),
},
],
[
JobStatus.Skipped,
{
name: "skipped",
type: JobStatus.Skipped,
render: (className?: string) => (
<span className={className ?? ""}>S</span>
),
},
],
[
JobStatus.Success,
{
name: "success",
type: JobStatus.Success,
render: (className?: string) => (
<IoCheckmarkSharp className={className}></IoCheckmarkSharp>
),
},
],
]);

export function getJobConclusionElementList() {
return cloneDeep(Array.from(jobConclusionElementMap.values()));
}

export function getConclusionIcon(
conclusion?: string,
className?: string,
failedPreviousRun?: boolean
) {
className = className ?? styles[conclusion ?? "undefined"];
if (conclusion === JobStatus.Success) {
if (failedPreviousRun) {
return jobConclusionElementMap.get(JobStatus.Failure)?.render(className);
}
return jobConclusionElementMap.get(conclusion)?.render(className);
}
return jobConclusionElementMap.has(conclusion) ? (
jobConclusionElementMap.get(conclusion)?.render(className)
) : (
<span className={className}>U</span>
);
}

/**
* `getFailureEl` generates a div with a monster sprite element based on the first line of `failureLines` in `jobData`.
*
Expand Down Expand Up @@ -86,9 +211,7 @@ export default function JobConclusion({
return (
<span className={styles.conclusion}>
{(failureEl && failureEl) || (
<span className={style}>
{getConclusionChar(conclusion, failedPreviousRun)}
</span>
<div>{getConclusionIcon(conclusion, style, failedPreviousRun)}</div>
)}
</span>
);
Expand Down
Loading
Loading