Skip to content

Commit 9daba5e

Browse files
authored
Merge pull request #5 from posit-dev/update-otel-dash
fix(champion-dashboard): clean up and fix title
2 parents c3b4c6d + 12efa23 commit 9daba5e

File tree

2 files changed

+114
-27
lines changed

2 files changed

+114
-27
lines changed

extensions/champion-dashboard/app.py

Lines changed: 112 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,42 @@
223223
.integration-table th:not(:first-child) {
224224
text-align: center;
225225
}
226+
.content-table {
227+
width: 100%;
228+
border-collapse: collapse;
229+
font-size: 14px;
230+
}
231+
.content-table thead {
232+
border-bottom: 2px solid rgba(55, 53, 47, 0.09);
233+
}
234+
.content-table th {
235+
color: #787774;
236+
font-weight: 600;
237+
padding: 12px 8px;
238+
text-align: left;
239+
font-size: 12px;
240+
text-transform: uppercase;
241+
letter-spacing: 0.5px;
242+
}
243+
.content-table th:last-child {
244+
text-align: right;
245+
}
246+
.content-table td {
247+
padding: 10px 8px;
248+
color: #37352f;
249+
border-bottom: 1px solid rgba(55, 53, 47, 0.06);
250+
}
251+
.content-table td:first-child {
252+
font-weight: 500;
253+
}
254+
.content-table td:last-child {
255+
text-align: right;
256+
font-weight: 600;
257+
color: #2383e2;
258+
}
259+
.content-table tbody tr:hover {
260+
background-color: #f7f6f3;
261+
}
226262
"""
227263

228264
def fetch_all_prometheus_metrics(url: str) -> Dict[str, List[Tuple[Dict[str, str], float]]]:
@@ -534,45 +570,96 @@ def content_stats_grid():
534570
class_="content-card"
535571
)
536572

537-
type_items = []
538573
sorted_types = sorted(stats["by_type"].items(), key=lambda x: x[1], reverse=True)
539-
for content_type, count in sorted_types:
540-
type_items.append(
541-
ui.div(
542-
ui.span(f"{content_type} :: ", style="color: #787774;"),
543-
ui.span(str(count), style="font-weight: 500;"),
544-
class_="content-type-item"
545-
)
574+
type_rows = [
575+
ui.tags.tr(
576+
ui.tags.td(content_type),
577+
ui.tags.td(str(count))
546578
)
579+
for content_type, count in sorted_types
580+
]
547581

548582
col2 = ui.div(
549-
ui.div("Content by Type", class_="card-title"),
550-
ui.div(*type_items, class_="section-content"),
583+
ui.div(
584+
ui.tags.table(
585+
ui.tags.thead(
586+
ui.tags.tr(
587+
ui.tags.th("Type"),
588+
ui.tags.th("Count")
589+
)
590+
),
591+
ui.tags.tbody(*type_rows),
592+
class_="content-table"
593+
),
594+
class_="section-content"
595+
),
551596
class_="content-card"
552597
)
553598

554-
runtime_items = []
555-
sorted_runtimes = sorted(stats["runtime_versions"].items(), key=lambda x: x[1], reverse=True)
556-
for runtime, count in sorted_runtimes:
557-
runtime_items.append(
558-
ui.div(
559-
ui.span(f"{runtime} :: ", style="color: #787774;"),
560-
ui.span(str(count), style="font-weight: 500;"),
561-
class_="content-type-item"
562-
)
599+
# Define runtime priority order
600+
runtime_order = {"R": 0, "Python": 1, "Quarto": 2}
601+
602+
# Custom sorting: first by runtime type, then by count (descending) within each type
603+
def sort_key(item):
604+
runtime, count = item
605+
# Extract the runtime language (first word)
606+
runtime_lang = runtime.split()[0] if runtime else ""
607+
# Get priority (default to 999 for unknown runtimes)
608+
priority = runtime_order.get(runtime_lang, 999)
609+
# Return tuple: (priority, -count) to sort by priority first, then count descending
610+
return (priority, -count)
611+
612+
sorted_runtimes = sorted(stats["runtime_versions"].items(), key=sort_key)
613+
runtime_rows = [
614+
ui.tags.tr(
615+
ui.tags.td(runtime),
616+
ui.tags.td(str(count))
563617
)
618+
for runtime, count in sorted_runtimes
619+
]
564620

565621
col3 = ui.div(
566-
ui.div("Content by Runtime Version", class_="card-title"),
567-
ui.div(*runtime_items, class_="section-content"),
622+
ui.div(
623+
ui.tags.table(
624+
ui.tags.thead(
625+
ui.tags.tr(
626+
ui.tags.th("Runtime Version"),
627+
ui.tags.th("Count")
628+
)
629+
),
630+
ui.tags.tbody(*runtime_rows),
631+
class_="content-table"
632+
),
633+
class_="section-content"
634+
),
568635
class_="content-card"
569636
)
570637

571638
access_stats = get_access_control_stats(metrics)
572-
sorted_access_stats = dict(sorted(access_stats.items(), key=lambda x: x[1], reverse=True))
573-
col4 = create_content_card(
574-
"Content by Access Control",
575-
ui.div(*create_key_value_list(sorted_access_stats), class_="section-content")
639+
sorted_access_stats = sorted(access_stats.items(), key=lambda x: x[1], reverse=True)
640+
access_rows = [
641+
ui.tags.tr(
642+
ui.tags.td(access_type),
643+
ui.tags.td(str(count))
644+
)
645+
for access_type, count in sorted_access_stats
646+
]
647+
648+
col4 = ui.div(
649+
ui.div(
650+
ui.tags.table(
651+
ui.tags.thead(
652+
ui.tags.tr(
653+
ui.tags.th("Access Type"),
654+
ui.tags.th("Count")
655+
)
656+
),
657+
ui.tags.tbody(*access_rows),
658+
class_="content-table"
659+
),
660+
class_="section-content"
661+
),
662+
class_="content-card"
576663
)
577664

578665
return [col1, col2, col3, col4]

extensions/champion-dashboard/manifest.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
},
2121
"extension": {
2222
"name": "champion-dashboard",
23-
"title": "OTEL Metrics Dashboard",
23+
"title": "Champion Dashboard",
2424
"description": "A dashboard containing various OTEL metrics from your Connect server.",
2525
"homepage": "https://github.com/posit-dev/connect-staging-extensions/tree/main/extensions/champion-dashboard",
2626
"category": "example",
@@ -29,7 +29,7 @@
2929
"OpenTelemetry"
3030
],
3131
"minimumConnectVersion": "connect-preview",
32-
"version": "1.0.1"
32+
"version": "1.0.2"
3333
},
3434
"files": {
3535
"requirements.txt": {

0 commit comments

Comments
 (0)