|
1 | 1 | <script setup lang="tsx"> |
2 | 2 | import {h, ref, Ref} from "vue"; |
3 | | -import {parseISO, differenceInHours} from "date-fns"; |
4 | | -import {formatISODate} from "../../utils/formatting"; |
| 3 | +import { |
| 4 | + parseISO, |
| 5 | + differenceInHours, |
| 6 | + differenceInSeconds, |
| 7 | + format, |
| 8 | +} from "date-fns"; |
| 9 | +import { |
| 10 | + formatISODate, |
| 11 | + formatSecondsAsDuration, |
| 12 | + parseDateIsoStringOrNull, |
| 13 | +} from "../../utils/formatting"; |
5 | 14 | import { |
6 | 15 | CollectorConfig, |
7 | 16 | BenchmarkJobStatus, |
8 | 17 | isJobComplete, |
9 | 18 | BenchmarkJob, |
| 19 | + BenchmarkJobKind, |
10 | 20 | } from "./data"; |
11 | 21 | import CommitSha from "./commit-sha.vue"; |
12 | 22 |
|
@@ -45,6 +55,12 @@ function formatJobStatus(status: BenchmarkJobStatus): string { |
45 | 55 | return "Unknown"; |
46 | 56 | } |
47 | 57 | } |
| 58 | +function formatJobKind(kind: BenchmarkJobKind): string { |
| 59 | + if (kind === "compiletime") { |
| 60 | + return "compile"; |
| 61 | + } |
| 62 | + return kind; |
| 63 | +} |
48 | 64 |
|
49 | 65 | function ActiveStatus({collector}: {collector: CollectorConfig}) { |
50 | 66 | const now = new Date(); |
@@ -101,6 +117,35 @@ function formatProfile(job: BenchmarkJob): string { |
101 | 117 | return ""; |
102 | 118 | } |
103 | 119 | } |
| 120 | +function timeSince(timestamp: string): string { |
| 121 | + const date = parseDateIsoStringOrNull(timestamp); |
| 122 | + if (date === null) { |
| 123 | + return ""; |
| 124 | + } |
| 125 | + const now = new Date(); |
| 126 | + const diffSeconds = differenceInSeconds(now, date); |
| 127 | + return formatSecondsAsDuration(diffSeconds); |
| 128 | +} |
| 129 | +
|
| 130 | +// Takes a date like `2025-09-10T08:22:47.161348Z` and shows just the time |
| 131 | +// portion (`08:22:47`). |
| 132 | +function formatTime(dateString: string | null): string { |
| 133 | + const date = parseDateIsoStringOrNull(dateString); |
| 134 | + if (date === null) { |
| 135 | + return ""; |
| 136 | + } |
| 137 | + return format(date, "HH:mm:ss"); |
| 138 | +} |
| 139 | +
|
| 140 | +function jobDuration(job: BenchmarkJob): string { |
| 141 | + if (!isJobComplete(job)) { |
| 142 | + return ""; |
| 143 | + } |
| 144 | + const start = parseDateIsoStringOrNull(job.startedAt); |
| 145 | + const end = parseDateIsoStringOrNull(job.completedAt); |
| 146 | + const diff = differenceInSeconds(end, start); |
| 147 | + return `Job took ${formatSecondsAsDuration(diff)}`; |
| 148 | +} |
104 | 149 | </script> |
105 | 150 |
|
106 | 151 | <template> |
@@ -182,18 +227,18 @@ function formatProfile(job: BenchmarkJob): string { |
182 | 227 | <template v-for="job in collector.jobs"> |
183 | 228 | <tr v-if="ACTIVE_FILTERS[job.status]"> |
184 | 229 | <td> |
185 | | - <CommitSha :tag="job.requestTag"></CommitSha> |
| 230 | + <CommitSha :tag="job.requestTag" :truncate="true"></CommitSha> |
186 | 231 | </td> |
187 | 232 | <td> |
188 | 233 | {{ formatJobStatus(job.status) }} |
189 | 234 | </td> |
190 | | - <td> |
191 | | - {{ formatISODate(job.startedAt) }} |
| 235 | + <td :title="`Started ${timeSince(job.startedAt)} ago`"> |
| 236 | + {{ formatTime(job.startedAt) }} |
192 | 237 | </td> |
193 | | - <td> |
194 | | - {{ formatISODate(job.completedAt) }} |
| 238 | + <td :title="jobDuration(job)"> |
| 239 | + {{ formatTime(job.completedAt) }} |
195 | 240 | </td> |
196 | | - <td>{{ job.kind }}</td> |
| 241 | + <td>{{ formatJobKind(job.kind) }}</td> |
197 | 242 | <td>{{ formatBackend(job) }}</td> |
198 | 243 | <td> |
199 | 244 | {{ formatProfile(job) }} |
|
0 commit comments