Skip to content
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
1ce2fb5
Improve Job view
timja Apr 20, 2025
220dac7
Merge branch 'main' into smaller-job-view
janfaracik Apr 22, 2025
01e8b14
Update design
janfaracik Apr 22, 2025
2ab1c47
Add timestamp
janfaracik Apr 22, 2025
7a2e321
Update status-icon.tsx
janfaracik Apr 22, 2025
8e10458
Update status-icon.tsx
janfaracik Apr 22, 2025
abbd699
Fix prettier
timja Apr 22, 2025
d5e64cb
Use ===
timja Apr 22, 2025
c6ebb88
Remove unused class
timja Apr 22, 2025
18992c9
Merge branch 'main' into pr/632
janfaracik Apr 22, 2025
6a21095
Fix status
janfaracik Apr 22, 2025
363119f
Fix overflowing
janfaracik Apr 22, 2025
2e13fda
Update single-run.scss
janfaracik Apr 22, 2025
e2d9310
Increase shown stages
timja Apr 22, 2025
df69467
Check if run is in progress before returning unknown
lewisbirks Apr 22, 2025
27b6382
Naaaaative toooltipssssss
janfaracik Apr 22, 2025
4dc0e59
Fix tooltip
janfaracik Apr 22, 2025
46b9f14
Move to Tippy
janfaracik Apr 23, 2025
25841ae
Update nodes.tsx
janfaracik Apr 23, 2025
6d305ef
Fixes
janfaracik Apr 23, 2025
6b856b0
Update tooltip.tsx
janfaracik Apr 23, 2025
084aa2c
Update tooltip to include duration
janfaracik Apr 23, 2025
f746d95
Update nodes.scss
janfaracik Apr 23, 2025
afd9727
Merge branch 'main' into pr/632
janfaracik Apr 23, 2025
f115354
Fixes
janfaracik Apr 23, 2025
4749b01
Update stage-details.tsx
janfaracik Apr 23, 2025
b6b6704
Merge branch 'main' into smaller-job-view
janfaracik Apr 23, 2025
c63d89b
Merge branch 'main' into pr/632
janfaracik Apr 23, 2025
7928b3e
Update package-lock.json
janfaracik Apr 23, 2025
2a5f46f
Add counter placeholder
janfaracik Apr 23, 2025
2a00254
Merge branch 'main' into smaller-job-view
timja Apr 24, 2025
e6ace2f
Add rough UI for counter
janfaracik Apr 24, 2025
d7b1250
Merge branch 'smaller-job-view' of https://github.com/timja/pipeline-…
janfaracik Apr 24, 2025
8d2a69d
Add provider for multi pipeline graph
lewisbirks Apr 24, 2025
2aaf54a
Only load required resource bundles
lewisbirks Apr 24, 2025
d5e4ffc
Semi working
janfaracik Apr 24, 2025
3a7afe7
Update PipelineGraphLayout.ts
janfaracik Apr 24, 2025
9e698f0
Update PipelineGraphLayout.ts
janfaracik Apr 24, 2025
483803c
Merge branch 'main' into smaller-job-view
janfaracik Apr 24, 2025
dccc20f
Merge branch 'main' into smaller-job-view
janfaracik Apr 24, 2025
586372b
Adjust height
timja Apr 24, 2025
b0e414c
Prettier
timja Apr 24, 2025
803d0fc
lift locale acquisition outside of provider
lewisbirks Apr 24, 2025
d6c6170
Swap test to playwright
timja Apr 24, 2025
9b0e64d
Wait for build to complete
timja Apr 24, 2025
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
49 changes: 30 additions & 19 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@
"@babel/helpers": "^7.20.7",
"@babel/preset-typescript": "^7.21.0",
"@babel/traverse": "^7.20.7",
"@tippyjs/react": "^4.2.6",
"babel-loader": "^9.1.2",
"babel-plugin-import": "^1.13.6",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-tippy": "^1.4.0",
"react-virtuoso": "^4.6.2"
},
"devDependencies": {
Expand Down
42 changes: 16 additions & 26 deletions src/main/frontend/common/components/tooltip.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,23 @@
import React, { useEffect, useRef } from "react";

declare global {
interface Window {
Behaviour: any;
}
}
import Tippy, { TippyProps } from "@tippyjs/react";
import React from "react";

/**
* Provides a bridge between React and the Jenkins' tooltip component
* A customized (and customizable) implementation of Tippy tooltips
*/
export default function Tooltip({ text, children }: TooltipProps) {
const ref = useRef<HTMLButtonElement>(null);

useEffect(() => {
if (!ref.current) {
return;
}

window.Behaviour?.applySubtree(ref.current.parentNode, true);
}, []);
export default function Tooltip(props: TippyProps) {
if (props.content === undefined) {
return props.children;
}

return (
<span {...{ tooltip: text }} ref={ref}>
{children}
</span>
<Tippy
theme="tooltip"
animation="tooltip"
duration={250}
touch={false}
{...props}
>
{props.children}
</Tippy>
);
}

interface TooltipProps {
text: string;
children: React.ReactNode;
}
11 changes: 10 additions & 1 deletion src/main/frontend/common/utils/timings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,20 @@ export function paused(since: number): string {
}

export function started(since: number): string {
return since == 0
return since === 0
? ""
: `Started ${getTimeSpanString(Math.abs(since - Date.now()))} ago`;
}

export function time(since: number): string {
return since === 0
? ""
: new Date(since).toLocaleTimeString("en-GB", {
hour: "2-digit",
minute: "2-digit",
});
}

export function exact(since: number): string {
if (since === 0) return "";

Expand Down
4 changes: 0 additions & 4 deletions src/main/frontend/multi-pipeline-graph-view/app.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
.app-page-body--one-column {
max-width: 95vw;
}

.pgw-user-specified-text {
overflow-wrap: break-word;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,35 @@ export const MultiPipelineGraph = () => {
});
}
}, [runs, poll]);

const groupedRuns: Record<string, RunInfo[]> = runs.reduce(
(acc: Record<string, RunInfo[]>, run) => {
const date = new Date(run.timestamp).toLocaleDateString("en-US", {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want this based on the users locale?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

year: "numeric",
month: "long",
day: "numeric",
});

if (!acc[date]) {
acc[date] = [];
}
acc[date].push(run);

return acc;
},
{},
);

return (
<>
{runs.length > 0 && (
<table className="jenkins-table sortable">
<thead>
<tr>
<th className="jenkins-table__cell--tight">id</th>
<th data-sort-disable="true">pipeline</th>
</tr>
</thead>
<tbody>
{runs.map((run) => (
<SingleRun
key={run.id}
run={run}
currentJobPath={currentJobPath}
/>
))}
</tbody>
</table>
)}
{Object.entries(groupedRuns).map(([date, runsOnDate]) => (
<div className={"pgv-stages__group"} key={date}>
<p className="pgv-stages__heading">{date}</p>
{runsOnDate.map((run) => (
<SingleRun key={run.id} run={run} currentJobPath={currentJobPath} />
))}
</div>
))}
</>
);
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { Result } from "../../../pipeline-graph-view/pipeline-graph/main";

export interface RunInfo {
id: string;
displayName: string;
timestamp: number;
duration: number;
result: Result;
}
Original file line number Diff line number Diff line change
@@ -1,32 +1,42 @@
import React, { useState } from "react";
import { RunInfo } from "./MultiPipelineGraphModel";
import {
LayoutInfo,
PipelineGraph,
StageInfo,
} from "../../../pipeline-graph-view/pipeline-graph/main";
import { defaultLayout } from "../../../pipeline-graph-view/pipeline-graph/main/PipelineGraphModel";
import { time, total } from "../../../common/utils/timings";
import "./single-run.scss";
import StatusIcon from "../../../common/components/status-icon";

export default function SingleRun({ run, currentJobPath }: SingleRunProps) {
const [stages, setStages] = useState<Array<StageInfo>>([]);

const layout: LayoutInfo = {
...defaultLayout,
nodeSpacingH: 45,
};

return (
<tr>
<td>
<a
href={currentJobPath + run.id}
className="jenkins-table__link pgw-user-specified-text"
>
<div className="pgv-single-run">
<div>
<a href={currentJobPath + run.id} className="pgw-user-specified-text">
<StatusIcon status={run.result} />
{run.displayName}
<span>
{time(run.timestamp)} - {total(run.duration)}
</span>
</a>
</td>
<td>
<PipelineGraph
stages={stages}
setStages={setStages}
currentRunPath={currentJobPath + run.id + "/"}
collapsed={true}
/>
</td>
</tr>
</div>
<PipelineGraph
stages={stages}
setStages={setStages}
currentRunPath={currentJobPath + run.id + "/"}
layout={layout}
collapsed={true}
/>
</div>
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
.pgv-single-run {
display: grid;
grid-template-columns: 200px 1fr;
align-items: center;

// This is hacky - the pipeline graph is too tall and isn't centered
.PWGx-PipelineGraph-container {
height: 36px;

& > div {
margin-top: -36px;
}
}

&:last-of-type {
border-bottom: none;
}

.pgw-user-specified-text {
display: grid;
grid-template-columns: auto 1fr;
align-items: start;
gap: 0.125rem 0.625rem;
color: var(--text-color);
text-decoration: none;
transition: opacity var(--standard-transition);
word-break: normal;
overflow-wrap: anywhere;

span {
grid-area: 2 / 2;
color: var(--text-color-secondary);
font-size: var(--font-size-xs);
}

&:hover {
opacity: 0.75;
}

&:active {
opacity: 0.5;
}

svg {
width: 1.375rem;
height: 1.375rem;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.pgv-stages__group {
display: flex;
flex-direction: column;
gap: 0.5rem;
margin-top: 1rem;

.pgv-stages__heading {
display: flex;
font-size: var(--font-size-xs);
color: var(--text-color-secondary);
font-weight: var(--font-bold-weight);
margin-bottom: 0.25rem;
margin-top: 0;
}

&:first-of-type {
margin-top: 0;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
/** * @jest-environment jsdom */

(global as any).TextEncoder = require("util").TextEncoder;

import "@testing-library/jest-dom";
import React from "react";
import ConsoleLogCard, { ConsoleLogCardProps } from "./ConsoleLogCard";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export default function ConsoleLogCard(props: ConsoleLogCardProps) {
</div>
</a>

<Tooltip text={"View step as plain text"}>
<Tooltip content={"View step as plain text"}>
<a
href={`log?nodeId=${props.step.id}`}
className={"jenkins-button jenkins-button--tertiary"}
Expand Down
Loading