diff options
| author | Danilo M. <danix@danix.xyz> | 2026-10-19 21:28:54 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-10-19 21:28:54 +0200 |
| commit | 993950b7733ba9300915955ec6e51e1f21dad806 (patch) | |
| tree | d8800305748d96581f3bea06eeb9b1a1da979a49 /sb_builder/dashboard.py | |
| parent | 5609a744ef5e89c4d57a5239199a6afe5497590e (diff) | |
| download | sb-builder-993950b7733ba9300915955ec6e51e1f21dad806.tar.gz sb-builder-993950b7733ba9300915955ec6e51e1f21dad806.zip | |
Results tab with build logs; count only real packages
sbb-remote 0.4.0: results lists slackrepo's last attempt per package
(newest first, with built version and whether a log dir exists), and
build-log returns the end of a package's build.log (512 KB) plus its
resource.log, accepting only category/pkg paths. Result counts skip
the legacy buildresults rows keyed by package file name: the 213
"bad" on the Dashboard matched no package.
GUI: a Results tab (chips per result, table sorted by attempt time,
detail pane, log viewer window that keeps the failure at the end),
opened from the ribbon or by clicking a result in the Dashboard bar or
legend, filtered to it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'sb_builder/dashboard.py')
| -rw-r--r-- | sb_builder/dashboard.py | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/sb_builder/dashboard.py b/sb_builder/dashboard.py index 8c98040..a8de823 100644 --- a/sb_builder/dashboard.py +++ b/sb_builder/dashboard.py @@ -104,7 +104,9 @@ class Tile(Card): class StackedBar(QWidget): - """Horizontal part-to-whole bar; hover a segment for its label and count.""" + """Horizontal part-to-whole bar; hover a segment for its count, click to open it.""" + + clicked = pyqtSignal(str) def __init__(self): super().__init__() @@ -135,6 +137,14 @@ class StackedBar(QWidget): p.setBrush(color) p.drawRoundedRect(rect, 4, 4) + def label_at(self, pos): + return next((label for rect, label, _c, _col in self.rects() if rect.contains(pos)), None) + + def mouseReleaseEvent(self, e): + label = self.label_at(e.position()) + if label and e.button() == Qt.MouseButton.LeftButton: + self.clicked.emit(label) + def event(self, e): if e.type() == QEvent.Type.ToolTip: hit = next((f"{label}: {count:,}" for rect, label, count, _ in self.rects() @@ -239,6 +249,8 @@ class Meter(QWidget): class Dashboard(QWidget): + result_clicked = pyqtSignal(str) # a slackrepo result kind, from the bar or legend + def __init__(self, parent=None): super().__init__(parent) self.setStyleSheet("QFrame#card { background: palette(base);" @@ -258,6 +270,9 @@ class Dashboard(QWidget): self.legend = QLabel(NA) self.legend.setTextFormat(Qt.TextFormat.RichText) self.legend.setWordWrap(True) + self.legend.linkActivated.connect(self.result_clicked) + self.bar.clicked.connect(self.result_clicked) + self.bar.setCursor(Qt.CursorShape.PointingHandCursor) self.results.body.addWidget(self.bar) self.results.body.addWidget(self.legend) self.results.body.addStretch() @@ -341,11 +356,14 @@ class Dashboard(QWidget): self.legend.setText(NA) return gray = self.palette().color(QPalette.ColorRole.PlaceholderText) # Mid can match the background + ink = self.palette().color(QPalette.ColorRole.WindowText).name() # links in text color order = sorted(sr["results"].items(), key=lambda kv: (list(STATUS).index(kv[0]) if kv[0] in STATUS else 99, kv[0])) self.bar.set_parts([(k, v, QColor(STATUS.get(k)) if k in STATUS else gray) for k, v in order]) self.legend.setText(" ".join( - f'<span style="color:{STATUS.get(k, gray.name())}">■</span> {html.escape(k)} {num(v)}' + f'<span style="color:{STATUS.get(k, gray.name())}">■</span> ' + f'<a href="{html.escape(k)}" style="color:{ink}; text-decoration:none">' + f'{html.escape(k)} {num(v)}</a>' for k, v in order)) def show_jobs(self, jobs): |
