This is an automated email from the ASF dual-hosted git repository.
spetz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iggy.git
The following commit(s) were added to refs/heads/master by this push:
new 9b0540038 fix(bench): fix mobile layout, compare URL, and shared
branded loader (#3148)
9b0540038 is described below
commit 9b0540038533acbfc2eea4d4f4d06dca4f37dd5b
Author: Piotr Gankiewicz <[email protected]>
AuthorDate: Tue Apr 21 14:17:40 2026 +0200
fix(bench): fix mobile layout, compare URL, and shared branded loader
(#3148)
Mobile detail view went blank because a desktop
`.sidebar-collapsed` rule left the grid with two columns but only
one area; Compare URL reverted to `/benchmarks/:uuid` because
`SingleChart` force-pushed history on prop change; loading states
were inconsistent and the pre-WASM splash jumped when the app
mounted.
Mobile rules moved to end-of-file so they win the cascade, both
`.detail-layout` and `.sidebar-collapsed` share one mobile grid,
and below 768px html/body/app-shell drop their 100vh locks so the
page scrolls naturally. `SingleChart` no longer writes history. A
shared `IggyLoader` replaces the legacy spinner, and the boot
splash is a position-fixed overlay centered the same way the hero
loading is. PNG logos (870 KB) swapped for SVG (21 KB). Row
select + compare are now sibling buttons, so clicking compare
never triggers the row's select handler.
---
core/bench/dashboard/frontend/assets/iggy-dark.png | Bin 869788 -> 0 bytes
core/bench/dashboard/frontend/assets/iggy-dark.svg | 112 +++++
.../bench/dashboard/frontend/assets/iggy-light.png | Bin 863513 -> 0 bytes
.../bench/dashboard/frontend/assets/iggy-light.svg | 112 +++++
core/bench/dashboard/frontend/assets/style.css | 474 +++++++++++++++------
core/bench/dashboard/frontend/index.dev.html | 59 ++-
core/bench/dashboard/frontend/index.html | 59 ++-
core/bench/dashboard/frontend/index.prod.html | 59 ++-
.../frontend/src/components/chart/single_chart.rs | 15 +-
.../dashboard/frontend/src/components/footer.rs | 6 +
.../frontend/src/components/layout/hero.rs | 76 ++--
.../frontend/src/components/layout/main_content.rs | 11 +-
.../frontend/src/components/layout/top_app_bar.rs | 12 +-
.../dashboard/frontend/src/components/loader.rs | 64 +++
.../bench/dashboard/frontend/src/components/mod.rs | 1 +
.../components/selectors/dense_benchmark_row.rs | 71 ++-
core/bench/dashboard/frontend/src/main.rs | 5 +
17 files changed, 913 insertions(+), 223 deletions(-)
diff --git a/core/bench/dashboard/frontend/assets/iggy-dark.png
b/core/bench/dashboard/frontend/assets/iggy-dark.png
deleted file mode 100644
index 63e67aa00..000000000
Binary files a/core/bench/dashboard/frontend/assets/iggy-dark.png and /dev/null
differ
diff --git a/core/bench/dashboard/frontend/assets/iggy-dark.svg
b/core/bench/dashboard/frontend/assets/iggy-dark.svg
new file mode 100644
index 000000000..d04b36a02
--- /dev/null
+++ b/core/bench/dashboard/frontend/assets/iggy-dark.svg
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg id="Warstwa_2" data-name="Warstwa 2" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 3902.16 1302.71">
+ <defs>
+ <style>
+ .cls-1 {
+ fill: #8e8e8e;
+ }
+
+ .cls-2 {
+ fill: #efefef;
+ }
+
+ .cls-3 {
+ stroke-width: 25px;
+ }
+
+ .cls-3, .cls-4 {
+ stroke: #000;
+ stroke-miterlimit: 10;
+ }
+
+ .cls-3, .cls-4, .cls-5 {
+ fill: #fff;
+ }
+
+ .cls-4 {
+ stroke-width: 20px;
+ }
+
+ .cls-6 {
+ fill: #a57449;
+ }
+
+ .cls-7 {
+ fill: #e5bf7f;
+ }
+
+ .cls-8 {
+ fill: #afafaf;
+ }
+
+ .cls-9 {
+ fill: url(#Gradient_bez_nazwy_206);
+ }
+
+ .cls-10 {
+ fill: #7b7b7b;
+ }
+ </style>
+ <linearGradient id="Gradient_bez_nazwy_206" data-name="Gradient bez nazwy
206" x1="1207.62" y1="562.3" x2="1123.01" y2="856.09"
gradientUnits="userSpaceOnUse">
+ <stop offset=".17" stop-color="#a72b00"/>
+ <stop offset=".26" stop-color="#b63800"/>
+ <stop offset=".52" stop-color="#dd5c00"/>
+ <stop offset=".73" stop-color="#f67100"/>
+ <stop offset=".86" stop-color="#ff7a01"/>
+ </linearGradient>
+ </defs>
+ <g id="Warstwa_1-2" data-name="Warstwa 1">
+ <path
d="M1015.91,255.31c-.18-.21-.36-.43-.54-.64.2.44.41.86.59,1.3-.02-.23-.04-.44-.06-.66Z"/>
+ <path d="M847.1,360.04h-.02c-.01.08-.03.16-.04.24.02-.08.04-.16.06-.24Z"/>
+ <path
d="M843.88,386.78c.31-8.84,1.69-17.67,3.16-26.51-2.27,8.37-4.21,17.85-3.16,26.51Z"/>
+ <path
d="M1305.08,297.4c.79.53,1.58.81,2.37.23-.58-.08-1.14-.13-1.72-.23-.25,0-.46,0-.65,0Z"/>
+ <path
d="M1303.81,296.79c.12.49.43.59,1.27.61-.27-.18-.54-.39-.82-.61h-.45Z"/>
+ <path
d="M1508.93,293.63c-.15-.72-.31-1.47-.48-2.23h-.76c.46.73.85,1.48,1.24,2.23Z"/>
+ <path class="cls-6"
d="M772.27,134.7c-56.11,22.38-64.01,35.68-70.67,56.86-20.41,64.84.57,80.27-47.5,117.52-33.02,19.99-57.54,23.46-96.86,13.04,13.17-11.62,28.81-26.03,39.65-39.65,18.9-23.75,23.21-44.66,35.25-61.68,23.7-33.51,96.01-89.86,140.13-86.09Z"/>
+ <path class="cls-7"
d="M1238.92,101.54c1.27.53,3.24-.57,4.41,0,.49.24-.47,6.42.06,8.84l4.35-4.43c.9.72,3.54-.72,4.41,0l13.22,35.25c-5.56.31-14.96-5.02-24.09-4.55-34.5,1.78-30.85,40.81-24.37,66.23-21.39-4.35-27.74-35.51-35.25-52.87-1.4-3.24-3.85-7.27-4.41-8.81-.52-1.43-3.91-2.92-4.41-4.41l-4.41-4.41c-.67-3.3-.71-14.41,0-17.62,7.49-34.07,44.89-24,70.49-13.22Z"/>
+ <path class="cls-6"
d="M1397.53,387.92c3.98,4.51,6.39,7.5,8.81,13.22-10.67-23.84-43.32,7.61-50.96,8.88-14.81,2.46-29.9-8.53-47.18-3.55-14.06,4.05-42.36,60.56-29.63,7.89,35.8-23.84,75.07-40.46,118.96-26.43Z"/>
+ <path class="cls-4"
d="M1375.89,443.74c-7.7-4.84-51.43-32.02-57.21-33.16-4.05-.79-15.41-1.17-19.73-.51-29.63,4.48-43.76,34.09-30.94,57.07,5.51,9.88,78.14,48.11,94.42,59.46,99.72,69.53,240.67,233.74,258.23,344.27,18.51,116.56-57.31,194.65-179.93,220.87,8.44,30.21,16.74,60.89,23.34,93.28,22.89-6.42,44.95-13.91,65.97-22.63,86.77-36.01,160.85-104.84,180.25-188.96,47.07-204.06-158.13-418.83-334.4-529.69Z"/>
+ <polygon class="cls-1" points="986.09 501.4 1022.09 564.72 1049.41 592.71
1089.4 626.03 1116.06 643.36 1136.73 650.7 1126.06 620.04 1082.07 568.71
1041.42 526.06 1028.75 495.4 1012.41 450.74 986.09 448.55 973.86 480.25 986.09
501.4"/>
+ <polygon class="cls-2" points="1421.43 398.09 1407.33 381.72 1379.34 358.1
1354.25 334.1 1307.93 291.99 1288.13 264.97 1338.47 264.78 1400.67 256.4
1376.67 233.98 1346.01 184.66 1322.02 116.82 1290.69 56.83 1261.88 24.9 1227.37
12.84 1168.72 12.84 1121.72 35.5 1086.07 35.5 979.43 46.17 890.12 88.82 835.46
72.83 790.35 60.83 676.22 77.53 630.17 151.48 586.18 256.4 532.86 320.77 551.53
336.77 608.85 339.43 666.21 311.44 702.16 271.83 719.49 291.99 750.15 291.99
790.35 307.44 804.86 362 [...]
+ <polygon class="cls-9" points="1047.41 530.33 1099.4 587.38 1140.73 652.7
1167.39 712.68 1198.62 772.72 1233.38 810.48 1261.88 822.96 1288.13 822.76
1314.58 810.48 1329.89 795.2 1338.47 772.72 1338.47 750.01 1329.89 720.28
1314.58 686.02 1296.69 643.36 1245.18 581.53 1180.14 550.08 1067.35 514.06
1032.75 504.73 1047.41 530.33"/>
+ <path
d="M1054.29,238.68l3.43,36.38c30.83-54.23-20.81-122.7-79.88-91.06-61.64,33-17.9,136.23,51.19,100.62l-15.91-1.54c25.3-13.61,30.85-44.23,17.28-68.35-4.85-8.63-16.16-10.85-18.86-19.43,22.19,4.01,38.27,21.65,42.76,43.38ZM1002.66,232.77c-12.94,14.18-40.02-.59-27.52-19.51,13.77-20.84,41.67,4,27.52,19.51ZM818.63,1018.99s-.36-.05-.92-.11c.54.31.88.38.92.11ZM1313,286.24c41.18,3.97,91.09,4.04,118.02-31.85-39.42-22.42-64.17-55.19-82.93-95.77-18.11-39.16-21.82-77.7-50.99-111.72-36.29-42.34
[...]
+ <path class="cls-8"
d="M821.7,373.99s2.81,3.33,4.04,5.27c13.77,21.72,11.03,23.02,17.84,32.61.5.71,1.11,1.39,1.73,2.15,28.08,34.53,46.53,31.77,46.53,31.77h0c-30.47,4.49-31.85,23.65-32.32,31.8-8.97,154.66,17.52,372.58-33.09,522.64-10.69-53.6-59.62-61.97-59.62-61.97,0,0,20.73-103.9,24.51-136.77,18.35-159.4,23.48-296.76,30.38-427.5Z"/>
+ <path class="cls-8"
d="M930.17,589.29c59.76,65.17,98.85,100.18,141.32,239.21l56.37,249.67c-20.51-.07-30.61-6.88-51.13-6.91-42-154.54-21.45-218.92-80.08-350.99l-66.49-130.98Z"/>
+ <path class="cls-10"
d="M1127.87,1078.18c12.12,30.1-2.63,1.84-5.54-24.54.57-72.51-36.72-227.99-19.94-299.98,5.93,44.02,18.9,87.28,32.06,130.25,10.75,35.11,77.67,176.36,78.52,186.38.85,9.89-40.35,13.02-48.47,13.28-16.16.52-29.03-5.36-36.64-5.39h0Z"/>
+ <path class="cls-3"
d="M1464.07,1185.02c-6.6-32.39-14.91-63.06-23.34-93.28-5.06,1.08-10.2,2.09-15.42,2.99-255.7,44.33-598.21-70.36-852.46-167.05-15.39,58.87-36.54,111.87-48.56,170.44,267.13,74.89,662.6,164.62,939.78,86.9Z"/>
+ <polygon class="cls-5" points="380.12 936.86 428 852.65 456.81 862.43
597.11 936.86 551.53 1100.59 363.31 1027.81 346.24 1014.39 380.12 936.86"/>
+ <g>
+ <path class="cls-5"
d="M548.9,939.03l-9,28.13-16.3,76.29,3.45,11.3c8.95-41.2,18.63-82.43,29.4-123.82l-7.56,8.11Z"/>
+ <path class="cls-5"
d="M850.98,982.35l-24.11-52.28-30.06-33.6-32.23-4.92-34.02-18.93-21.45-8.72-37.44-11.55-38.16,36.84-36.49,17.63-25.08,7.51-15.47,16.6c-10.77,41.39-23.9,54.15-32.85,95.35l21.51,87.6,24.4,14.05,22.66,47.32,26.66,18,14.43,8.17,39.16,4.31,31.06,17.51,30.93-16.42,25.33-51.65,31.22-3.19,45.29-33.93,17.75-67.05-3.03-68.64Z"/>
+ <path
d="M515.34,964.58c-7.81,29.43-9.26,35.54-12.17,57.77l-.25,30.71c1.33,25.66-.46,29.14,12.32,57.81,14.83-72.8,31.32-145.52,51.63-218.87,2-4,10-8,12-12,.48-.96.72-1.91.82-2.87-26.97,11.92-53.23,59.94-64.35,87.44"/>
+ <path
d="M877.06,1025.74c-.5-.09-.97-.19-1.47-.27-4.22-.7-2.83-9.14-2.13-13.37-.7,4.22-2.09,12.67,2.13,13.37.5.08.97.19,1.47.27-.02-.27-.03-.54-.04-.81-.96-.38-1.93-.8-2.92-1.29,2.82-42.6-9.95-114.17-55.11-131.49-11.9-4.56-44.97-5.81-49.39-9.85-2.03-1.86-.15-11.99-3.66-17.01-20.37-29.05-81.82-37.3-111.66-19.02-12.18,7.46-25.22,29.93-27.12,30.7-5.2,2.11-22.31-4.12-32.11-3.61-5.33.27-10.46,1.61-15.36,3.78-.1.96-.34,1.91-.82,2.87-2,4-10,8-12,12-20.31,73.36-36.8,146.07-51.63,218.87.74,
[...]
+ </g>
+ <g>
+ <polygon class="cls-5" points="1499.89 977.59 1445.81 950.99 1406.74
917.87 1356.01 905.53 1328.19 921.89 1302.83 947.96 1271.02 939.24 1214.8
962.14 1197.8 1034.42 1196.5 1100.27 1199.51 1159.13 1224.08 1195.91 1263.7
1213.5 1286.69 1219.41 1301.6 1250.01 1325.76 1278.81 1363.4 1270.88 1376.31
1260.21 1411.05 1263.1 1447.84 1251.6 1456.87 1219.38 1487.08 1209.82 1514.19
1191.75 1538.53 1149.94 1533 1041.96 1499.89 977.59"/>
+ <path
d="M1177.26,1075.35l-1.15.06c.04.17.07.33.11.5,2.35,18.16,5.7,39.18,9.64,56.33.73,8.44,1.04,16.89.63,25.39.41-8.5.1-16.95-.63-25.39-.14,2.03-.37,4.04-.67,6.03h.12c-1.84,31.84,11.63,70.26,41.86,84.77,12.46,5.98,43.02,8.13,49.14,12.32,7.64,5.22,13.7,49.94,42.18,62.93,35.13,16.02,47.9-16.4,62.43-20,6.51-1.61,30.16,13.06,56.32,3.45,23.92-8.79,30.82-46.46,34.19-48.74,4.1-2.78,18.22-.94,26.48-4.09,25.39-9.69,37.47-22.79,46.42-48.51,4.38-12.6,6.25-44.67,11.88-53.76l.99-1.37c.16-.17.
[...]
+ </g>
+ <g>
+ <path d="M1925.84,1049.64V430.42h116.96v619.22h-116.96Z"/>
+ <path
d="M2429.8,1062.54c-38.99,0-76.11-6.95-111.37-20.86-35.26-13.9-66.44-34.47-93.53-61.71-27.09-27.23-48.45-60.91-64.07-101.05-15.63-40.13-23.44-86.43-23.44-138.89,0-68.51,13.12-126.78,39.35-174.8,26.23-48.01,61.49-84.64,105.78-109.87,44.29-25.22,93.38-37.84,147.28-37.84,79.69,0,142.33,18.49,187.91,55.47,45.58,36.98,76.11,89.3,91.59,156.95l-119.54,17.2c-11.18-36.12-29.46-65-54.83-86.65-25.37-21.64-57.84-32.61-97.4-32.9-39.28-.57-71.96,7.89-98.04,25.37-26.09,17.49-45.66,42.29-58.
[...]
+ <path
d="M3067.08,1062.54c-38.99,0-76.11-6.95-111.37-20.86-35.26-13.9-66.44-34.47-93.53-61.71-27.09-27.23-48.45-60.91-64.07-101.05-15.63-40.13-23.44-86.43-23.44-138.89,0-68.51,13.12-126.78,39.35-174.8,26.23-48.01,61.49-84.64,105.78-109.87,44.29-25.22,93.38-37.84,147.28-37.84,79.69,0,142.33,18.49,187.91,55.47,45.58,36.98,76.11,89.3,91.59,156.95l-119.54,17.2c-11.18-36.12-29.46-65-54.83-86.65-25.37-21.64-57.84-32.61-97.4-32.9-39.28-.57-71.96,7.89-98.04,25.37-26.09,17.49-45.66,42.29-58
[...]
+ <path
d="M3571.91,1049.64v-251.99l-211.57-367.23h136.74l134.16,233.07,134.16-233.07h136.74l-211.57,367.23v251.99h-118.68Z"/>
+ </g>
+ <path
d="M432.28,867.25l-73.35,150.05,187.26,74.87c6.64,3.25-16.24,23.7-37.16,16.42-53.57-24.99-108.28-36.8-159.74-69.93-6.97-4.49-15.98-13.87-14.57-22.86l77.96-162.06c6.45-11.53,19.65-11.08,30.53-7.25,18.97,6.67,117.06,55.86,131.42,66.67,12.45,9.38-4.68,21.38-12.03,17.78l-130.32-63.7Z"/>
+ <path
d="M75.65,769.84l279.31,138.59c2.02,6.5,1.11,11.48-6.27,12.76l-279.98-135.16c-43.29,47.19-101.06-31.64-46.48-58.56,28.42-14.02,60.69,12.27,53.42,42.37ZM19.17,758.55c-5.67,21.92,28.59,33.66,38.04,11.78,10.87-25.15-30.17-42.2-38.04-11.78Z"/>
+ <path
d="M90.03,923.17c-2.48,1.87,2.52,33.61-27.75,42.7-56.65,17.02-67.74-73.62-12.57-74.66,22.76-.43,23.66,12.65,32.84,15.55,4.01,1.27,69.48-6.74,83.95-6.41,37.02.86,80.65,6.75,115.92,18.04,8.88,2.84,75.96,23.16,52.02,37.28-8.32,4.91-28.04-9.74-37.16-13.02-52.23-18.79-108.22-26.2-163.44-23.25-5.52.29-42.07,2.44-43.82,3.76ZM57.15,949.03c24.19-7.24,14.72-44.98-11.46-39.08-25.19,5.67-14.72,46.92,11.46,39.08Z"/>
+ <path
d="M373.45,875.3c1.84,4.87-4.32,11.73-9.08,11.61-12.2-.32-57.7-32.33-69.56-41.42-34.07-26.11-62.86-59.39-87.98-93.89-5.81-7.98-21.82-38.61-26.04-42.1-11.34-9.36-30.37-1.98-39.1-29.59-15.11-47.78,60.18-71.03,73.79-21.42,7.14,26.01-17.38,41.94-17.34,45.05.03,2.56,22.32,35.95,25.82,40.87,26.44,37.15,61.37,73.15,98.89,99.29,7.62,5.31,49.17,27.79,50.61,31.6ZM158.94,663.48c-7.18,24.96,33.19,37,39.67,8.64,4.94-21.63-32.17-34.71-39.67-8.64Z"/>
+ <path
d="M169.23,974.85c1.83-.01,26.38-12.13,33.67-14.12,30.88-8.43,76.67-7.99,106.31,5.29,7,3.13,22.99,11.57,10.68,19.45-6.25,4-37.09-8.47-48.07-10.44-17.8-3.19-41.81-2.25-59.39,2.03-4.35,1.06-28.06,8.52-28.03,11.47.01,1.1,7.27,10.87,6.93,20.5-1.67,47.44-66.49,50.76-75.46,8.93-5.71-26.65,13.58-47.15,39.59-47.01,5.53.03,10.52,3.93,13.77,3.91ZM133.09,1006.83c-3.61,16.45,20.94,30.4,32.89,17.57,25.23-27.1-25.08-53.18-32.89-17.57Z"/>
+ <path
d="M289.52,725.1c-1.62-1.9-18.59-.36-29.14-16.72-30.8-47.8,57.3-88.71,65.78-30.42,4.25,29.22-18.21,35.37-19.93,43.43-.59,2.76,6.35,26.83,8.03,31.2,10.27,26.73,28.21,48.28,50.21,66.36,7.54,6.2,28.26,14.09,26.64,23.62-2.59,15.28-21.04,2.11-28.02-2.25-26.47-16.53-49.33-44.59-61.84-72.82-3.75-8.46-10.3-40.73-11.73-42.41ZM294.89,705.51c18.88-7.37,18.24-39.89-4.7-38.43-23.87,1.52-21.72,48.74,4.7,38.43Z"/>
+ <path
d="M464.94,1031.37c2.21,5.31-2.06,10.93-8.75,9.53-22.84-4.78-53.95-25.99-77.81-32.32-4.57-3.36-2.56-10.3,2.51-11.8,4.39-1.3,82.28,30.38,84.04,34.6Z"/>
+ <path
d="M472.62,1044.71c2.76-12.14,28.9-.8,25.85,8.36-3.22,9.68-27.75.01-25.85-8.36Z"/>
+ <path class="cls-8"
d="M1050.65,54.76c13.05.31,14.11,17.66,14.28,26.92.22,1.19.22,3.22,0,4.41-1.63,8.98-2.26,13.12-13.22,13.22-45.44-15.13-106.28,17.82-123.34,61.66,41.36-31.48,97.83-76.57,145.37-26.41,40.15,42.36,38.03,223.48-26.32,240.22-24.34,6.33-37.93-2.63-57.39-2.3-45.85.76-64.4,31.24-61.68,74.9-6.52-7.17-21.69-13-32.66-26.82-22.57-28.45-37.68-71.86-55.46-94.3-5.14-6.48-8.85,11-11.71,12.04-8.61-17.62-14.71-48.43-35.1-57.8-19.72-9.06-32.97-1.97-50.11-4.96,1.94-12.7-13.34-9.63-16
[...]
+ <g>
+ <path
d="M2016.11,298.37h-65.61l-14.89,40.6h-12.8l54.69-144.52h11.61l54.69,144.52h-12.71l-14.99-40.6ZM1954.27,288.05h57.97l-28.98-78.71-28.98,78.71Z"/>
+ <path
d="M2077.25,280.11v58.86h-12.21v-144.52h49.23c15.02,0,26.88,3.84,35.58,11.51,8.7,7.68,13.05,18.23,13.05,31.66s-4.19,24.04-12.56,31.42c-8.37,7.38-20.5,11.07-36.38,11.07h-36.73ZM2077.25,269.79h37.02c11.84,0,20.88-2.82,27.1-8.45,6.22-5.63,9.33-13.49,9.33-23.56s-3.09-17.98-9.28-23.91c-6.19-5.93-14.97-8.96-26.35-9.1h-37.82v65.01Z"/>
+ <path
d="M2254.53,298.37h-65.61l-14.89,40.6h-12.8l54.69-144.52h11.61l54.69,144.52h-12.71l-14.99-40.6ZM2192.69,288.05h57.97l-28.98-78.71-28.98,78.71Z"/>
+ <path
d="M2405.8,293.91c-1.65,15.22-7.1,26.87-16.33,34.94-9.23,8.07-21.52,12.11-36.87,12.11-10.72,0-20.2-2.68-28.44-8.04s-14.61-12.95-19.11-22.78c-4.5-9.83-6.78-21.06-6.85-33.7v-18.76c0-12.84,2.25-24.22,6.75-34.15,4.5-9.93,10.97-17.58,19.41-22.98,8.44-5.39,18.15-8.09,29.13-8.09,15.48,0,27.71,4.17,36.68,12.51,8.97,8.34,14.18,19.89,15.63,34.64h-12.31c-3.04-24.55-16.38-36.83-40-36.83-13.1,0-23.54,4.9-31.32,14.7-7.78,9.8-11.66,23.34-11.66,40.63v17.68c0,16.69,3.79,30,11.37,39.93,7.58,9.
[...]
+ <path
d="M2542.58,338.97h-12.31v-69.28h-82.58v69.28h-12.21v-144.52h12.21v64.92h82.58v-64.92h12.31v144.52Z"/>
+ <path
d="M2659.11,269.69h-67.6v58.96h77.72v10.32h-89.93v-144.52h89.43v10.32h-77.22v54.59h67.6v10.32Z"/>
+ </g>
+ </g>
+</svg>
diff --git a/core/bench/dashboard/frontend/assets/iggy-light.png
b/core/bench/dashboard/frontend/assets/iggy-light.png
deleted file mode 100644
index adc45a899..000000000
Binary files a/core/bench/dashboard/frontend/assets/iggy-light.png and
/dev/null differ
diff --git a/core/bench/dashboard/frontend/assets/iggy-light.svg
b/core/bench/dashboard/frontend/assets/iggy-light.svg
new file mode 100644
index 000000000..a03645fb3
--- /dev/null
+++ b/core/bench/dashboard/frontend/assets/iggy-light.svg
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg id="Warstwa_2" data-name="Warstwa 2" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 3902.16 1302.71">
+ <defs>
+ <style>
+ .cls-1 {
+ fill: #8e8e8e;
+ }
+
+ .cls-2 {
+ fill: #efefef;
+ }
+
+ .cls-3 {
+ stroke-width: 25px;
+ }
+
+ .cls-3, .cls-4 {
+ stroke: #000;
+ stroke-miterlimit: 10;
+ }
+
+ .cls-3, .cls-4, .cls-5 {
+ fill: #fff;
+ }
+
+ .cls-4 {
+ stroke-width: 20px;
+ }
+
+ .cls-6 {
+ fill: #a57449;
+ }
+
+ .cls-7 {
+ fill: #e5bf7f;
+ }
+
+ .cls-8 {
+ fill: #afafaf;
+ }
+
+ .cls-9 {
+ fill: url(#Gradient_bez_nazwy_206);
+ }
+
+ .cls-10 {
+ fill: #7b7b7b;
+ }
+ </style>
+ <linearGradient id="Gradient_bez_nazwy_206" data-name="Gradient bez nazwy
206" x1="1207.62" y1="562.3" x2="1123.01" y2="856.09"
gradientUnits="userSpaceOnUse">
+ <stop offset=".17" stop-color="#a72b00"/>
+ <stop offset=".26" stop-color="#b63800"/>
+ <stop offset=".52" stop-color="#dd5c00"/>
+ <stop offset=".73" stop-color="#f67100"/>
+ <stop offset=".86" stop-color="#ff7a01"/>
+ </linearGradient>
+ </defs>
+ <g id="Warstwa_1-2" data-name="Warstwa 1">
+ <path
d="M1015.91,255.31c-.18-.21-.36-.43-.54-.64.2.44.41.86.59,1.3-.02-.23-.04-.44-.06-.66Z"/>
+ <path d="M847.1,360.04h-.02c-.01.08-.03.16-.04.24.02-.08.04-.16.06-.24Z"/>
+ <path
d="M843.88,386.78c.31-8.84,1.69-17.67,3.16-26.51-2.27,8.37-4.21,17.85-3.16,26.51Z"/>
+ <path
d="M1305.08,297.4c.79.53,1.58.81,2.37.23-.58-.08-1.14-.13-1.72-.23-.25,0-.46,0-.65,0Z"/>
+ <path
d="M1303.81,296.79c.12.49.43.59,1.27.61-.27-.18-.54-.39-.82-.61h-.45Z"/>
+ <path
d="M1508.93,293.63c-.15-.72-.31-1.47-.48-2.23h-.76c.46.73.85,1.48,1.24,2.23Z"/>
+ <path class="cls-6"
d="M772.27,134.7c-56.11,22.38-64.01,35.68-70.67,56.86-20.41,64.84.57,80.27-47.5,117.52-33.02,19.99-57.54,23.46-96.86,13.04,13.17-11.62,28.81-26.03,39.65-39.65,18.9-23.75,23.21-44.66,35.25-61.68,23.7-33.51,96.01-89.86,140.13-86.09Z"/>
+ <path class="cls-7"
d="M1238.92,101.54c1.27.53,3.24-.57,4.41,0,.49.24-.47,6.42.06,8.84l4.35-4.43c.9.72,3.54-.72,4.41,0l13.22,35.25c-5.56.31-14.96-5.02-24.09-4.55-34.5,1.78-30.85,40.81-24.37,66.23-21.39-4.35-27.74-35.51-35.25-52.87-1.4-3.24-3.85-7.27-4.41-8.81-.52-1.43-3.91-2.92-4.41-4.41l-4.41-4.41c-.67-3.3-.71-14.41,0-17.62,7.49-34.07,44.89-24,70.49-13.22Z"/>
+ <path class="cls-6"
d="M1397.53,387.92c3.98,4.51,6.39,7.5,8.81,13.22-10.67-23.84-43.32,7.61-50.96,8.88-14.81,2.46-29.9-8.53-47.18-3.55-14.06,4.05-42.36,60.56-29.63,7.89,35.8-23.84,75.07-40.46,118.96-26.43Z"/>
+ <path class="cls-4"
d="M1375.89,443.74c-7.7-4.84-51.43-32.02-57.21-33.16-4.05-.79-15.41-1.17-19.73-.51-29.63,4.48-43.76,34.09-30.94,57.07,5.51,9.88,78.14,48.11,94.42,59.46,99.72,69.53,240.67,233.74,258.23,344.27,18.51,116.56-57.31,194.65-179.93,220.87,8.44,30.21,16.74,60.89,23.34,93.28,22.89-6.42,44.95-13.91,65.97-22.63,86.77-36.01,160.85-104.84,180.25-188.96,47.07-204.06-158.13-418.83-334.4-529.69Z"/>
+ <polygon class="cls-1" points="986.09 501.4 1022.09 564.72 1049.41 592.71
1089.4 626.03 1116.06 643.36 1136.73 650.7 1126.06 620.04 1082.07 568.71
1041.42 526.06 1028.75 495.4 1012.41 450.74 986.09 448.55 973.86 480.25 986.09
501.4"/>
+ <polygon class="cls-2" points="1421.43 398.09 1407.33 381.72 1379.34 358.1
1354.25 334.1 1307.93 291.99 1288.13 264.97 1338.47 264.78 1400.67 256.4
1376.67 233.98 1346.01 184.66 1322.02 116.82 1290.69 56.83 1261.88 24.9 1227.37
12.84 1168.72 12.84 1121.72 35.5 1086.07 35.5 979.43 46.17 890.12 88.82 835.46
72.83 790.35 60.83 676.22 77.53 630.17 151.48 586.18 256.4 532.86 320.77 551.53
336.77 608.85 339.43 666.21 311.44 702.16 271.83 719.49 291.99 750.15 291.99
790.35 307.44 804.86 362 [...]
+ <polygon class="cls-9" points="1047.41 530.33 1099.4 587.38 1140.73 652.7
1167.39 712.68 1198.62 772.72 1233.38 810.48 1261.88 822.96 1288.13 822.76
1314.58 810.48 1329.89 795.2 1338.47 772.72 1338.47 750.01 1329.89 720.28
1314.58 686.02 1296.69 643.36 1245.18 581.53 1180.14 550.08 1067.35 514.06
1032.75 504.73 1047.41 530.33"/>
+ <path
d="M1054.29,238.68l3.43,36.38c30.83-54.23-20.81-122.7-79.88-91.06-61.64,33-17.9,136.23,51.19,100.62l-15.91-1.54c25.3-13.61,30.85-44.23,17.28-68.35-4.85-8.63-16.16-10.85-18.86-19.43,22.19,4.01,38.27,21.65,42.76,43.38ZM1002.66,232.77c-12.94,14.18-40.02-.59-27.52-19.51,13.77-20.84,41.67,4,27.52,19.51ZM818.63,1018.99s-.36-.05-.92-.11c.54.31.88.38.92.11ZM1313,286.24c41.18,3.97,91.09,4.04,118.02-31.85-39.42-22.42-64.17-55.19-82.93-95.77-18.11-39.16-21.82-77.7-50.99-111.72-36.29-42.34
[...]
+ <path class="cls-8"
d="M821.7,373.99s2.81,3.33,4.04,5.27c13.77,21.72,11.03,23.02,17.84,32.61.5.71,1.11,1.39,1.73,2.15,28.08,34.53,46.53,31.77,46.53,31.77h0c-30.47,4.49-31.85,23.65-32.32,31.8-8.97,154.66,17.52,372.58-33.09,522.64-10.69-53.6-59.62-61.97-59.62-61.97,0,0,20.73-103.9,24.51-136.77,18.35-159.4,23.48-296.76,30.38-427.5Z"/>
+ <path class="cls-8"
d="M930.17,589.29c59.76,65.17,98.85,100.18,141.32,239.21l56.37,249.67c-20.51-.07-30.61-6.88-51.13-6.91-42-154.54-21.45-218.92-80.08-350.99l-66.49-130.98Z"/>
+ <path class="cls-10"
d="M1127.87,1078.18c12.12,30.1-2.63,1.84-5.54-24.54.57-72.51-36.72-227.99-19.94-299.98,5.93,44.02,18.9,87.28,32.06,130.25,10.75,35.11,77.67,176.36,78.52,186.38.85,9.89-40.35,13.02-48.47,13.28-16.16.52-29.03-5.36-36.64-5.39h0Z"/>
+ <path class="cls-3"
d="M1464.07,1185.02c-6.6-32.39-14.91-63.06-23.34-93.28-5.06,1.08-10.2,2.09-15.42,2.99-255.7,44.33-598.21-70.36-852.46-167.05-15.39,58.87-36.54,111.87-48.56,170.44,267.13,74.89,662.6,164.62,939.78,86.9Z"/>
+ <polygon class="cls-5" points="380.12 936.86 428 852.65 456.81 862.43
597.11 936.86 551.53 1100.59 363.31 1027.81 346.24 1014.39 380.12 936.86"/>
+ <g>
+ <path class="cls-5"
d="M548.9,939.03l-9,28.13-16.3,76.29,3.45,11.3c8.95-41.2,18.63-82.43,29.4-123.82l-7.56,8.11Z"/>
+ <path class="cls-5"
d="M850.98,982.35l-24.11-52.28-30.06-33.6-32.23-4.92-34.02-18.93-21.45-8.72-37.44-11.55-38.16,36.84-36.49,17.63-25.08,7.51-15.47,16.6c-10.77,41.39-23.9,54.15-32.85,95.35l21.51,87.6,24.4,14.05,22.66,47.32,26.66,18,14.43,8.17,39.16,4.31,31.06,17.51,30.93-16.42,25.33-51.65,31.22-3.19,45.29-33.93,17.75-67.05-3.03-68.64Z"/>
+ <path
d="M515.34,964.58c-7.81,29.43-9.26,35.54-12.17,57.77l-.25,30.71c1.33,25.66-.46,29.14,12.32,57.81,14.83-72.8,31.32-145.52,51.63-218.87,2-4,10-8,12-12,.48-.96.72-1.91.82-2.87-26.97,11.92-53.23,59.94-64.35,87.44"/>
+ <path
d="M877.06,1025.74c-.5-.09-.97-.19-1.47-.27-4.22-.7-2.83-9.14-2.13-13.37-.7,4.22-2.09,12.67,2.13,13.37.5.08.97.19,1.47.27-.02-.27-.03-.54-.04-.81-.96-.38-1.93-.8-2.92-1.29,2.82-42.6-9.95-114.17-55.11-131.49-11.9-4.56-44.97-5.81-49.39-9.85-2.03-1.86-.15-11.99-3.66-17.01-20.37-29.05-81.82-37.3-111.66-19.02-12.18,7.46-25.22,29.93-27.12,30.7-5.2,2.11-22.31-4.12-32.11-3.61-5.33.27-10.46,1.61-15.36,3.78-.1.96-.34,1.91-.82,2.87-2,4-10,8-12,12-20.31,73.36-36.8,146.07-51.63,218.87.74,
[...]
+ </g>
+ <g>
+ <polygon class="cls-5" points="1499.89 977.59 1445.81 950.99 1406.74
917.87 1356.01 905.53 1328.19 921.89 1302.83 947.96 1271.02 939.24 1214.8
962.14 1197.8 1034.42 1196.5 1100.27 1199.51 1159.13 1224.08 1195.91 1263.7
1213.5 1286.69 1219.41 1301.6 1250.01 1325.76 1278.81 1363.4 1270.88 1376.31
1260.21 1411.05 1263.1 1447.84 1251.6 1456.87 1219.38 1487.08 1209.82 1514.19
1191.75 1538.53 1149.94 1533 1041.96 1499.89 977.59"/>
+ <path
d="M1177.26,1075.35l-1.15.06c.04.17.07.33.11.5,2.35,18.16,5.7,39.18,9.64,56.33.73,8.44,1.04,16.89.63,25.39.41-8.5.1-16.95-.63-25.39-.14,2.03-.37,4.04-.67,6.03h.12c-1.84,31.84,11.63,70.26,41.86,84.77,12.46,5.98,43.02,8.13,49.14,12.32,7.64,5.22,13.7,49.94,42.18,62.93,35.13,16.02,47.9-16.4,62.43-20,6.51-1.61,30.16,13.06,56.32,3.45,23.92-8.79,30.82-46.46,34.19-48.74,4.1-2.78,18.22-.94,26.48-4.09,25.39-9.69,37.47-22.79,46.42-48.51,4.38-12.6,6.25-44.67,11.88-53.76l.99-1.37c.16-.17.
[...]
+ </g>
+ <g>
+ <path class="cls-5" d="M1925.84,1049.64V430.42h116.96v619.22h-116.96Z"/>
+ <path class="cls-5"
d="M2429.8,1062.54c-38.99,0-76.11-6.95-111.37-20.86-35.26-13.9-66.44-34.47-93.53-61.71-27.09-27.23-48.45-60.91-64.07-101.05-15.63-40.13-23.44-86.43-23.44-138.89,0-68.51,13.12-126.78,39.35-174.8,26.23-48.01,61.49-84.64,105.78-109.87,44.29-25.22,93.38-37.84,147.28-37.84,79.69,0,142.33,18.49,187.91,55.47,45.58,36.98,76.11,89.3,91.59,156.95l-119.54,17.2c-11.18-36.12-29.46-65-54.83-86.65-25.37-21.64-57.84-32.61-97.4-32.9-39.28-.57-71.96,7.89-98.04,25.37-26.09,17.49-4
[...]
+ <path class="cls-5"
d="M3067.08,1062.54c-38.99,0-76.11-6.95-111.37-20.86-35.26-13.9-66.44-34.47-93.53-61.71-27.09-27.23-48.45-60.91-64.07-101.05-15.63-40.13-23.44-86.43-23.44-138.89,0-68.51,13.12-126.78,39.35-174.8,26.23-48.01,61.49-84.64,105.78-109.87,44.29-25.22,93.38-37.84,147.28-37.84,79.69,0,142.33,18.49,187.91,55.47,45.58,36.98,76.11,89.3,91.59,156.95l-119.54,17.2c-11.18-36.12-29.46-65-54.83-86.65-25.37-21.64-57.84-32.61-97.4-32.9-39.28-.57-71.96,7.89-98.04,25.37-26.09,17.49-
[...]
+ <path class="cls-5"
d="M3571.91,1049.64v-251.99l-211.57-367.23h136.74l134.16,233.07,134.16-233.07h136.74l-211.57,367.23v251.99h-118.68Z"/>
+ </g>
+ <path
d="M432.28,867.25l-73.35,150.05,187.26,74.87c6.64,3.25-16.24,23.7-37.16,16.42-53.57-24.99-108.28-36.8-159.74-69.93-6.97-4.49-15.98-13.87-14.57-22.86l77.96-162.06c6.45-11.53,19.65-11.08,30.53-7.25,18.97,6.67,117.06,55.86,131.42,66.67,12.45,9.38-4.68,21.38-12.03,17.78l-130.32-63.7Z"/>
+ <path class="cls-5"
d="M75.65,769.84l279.31,138.59c2.02,6.5,1.11,11.48-6.27,12.76l-279.98-135.16c-43.29,47.19-101.06-31.64-46.48-58.56,28.42-14.02,60.69,12.27,53.42,42.37ZM19.17,758.55c-5.67,21.92,28.59,33.66,38.04,11.78,10.87-25.15-30.17-42.2-38.04-11.78Z"/>
+ <path class="cls-5"
d="M90.03,923.17c-2.48,1.87,2.52,33.61-27.75,42.7-56.65,17.02-67.74-73.62-12.57-74.66,22.76-.43,23.66,12.65,32.84,15.55,4.01,1.27,69.48-6.74,83.95-6.41,37.02.86,80.65,6.75,115.92,18.04,8.88,2.84,75.96,23.16,52.02,37.28-8.32,4.91-28.04-9.74-37.16-13.02-52.23-18.79-108.22-26.2-163.44-23.25-5.52.29-42.07,2.44-43.82,3.76ZM57.15,949.03c24.19-7.24,14.72-44.98-11.46-39.08-25.19,5.67-14.72,46.92,11.46,39.08Z"/>
+ <path class="cls-5"
d="M373.45,875.3c1.84,4.87-4.32,11.73-9.08,11.61-12.2-.32-57.7-32.33-69.56-41.42-34.07-26.11-62.86-59.39-87.98-93.89-5.81-7.98-21.82-38.61-26.04-42.1-11.34-9.36-30.37-1.98-39.1-29.59-15.11-47.78,60.18-71.03,73.79-21.42,7.14,26.01-17.38,41.94-17.34,45.05.03,2.56,22.32,35.95,25.82,40.87,26.44,37.15,61.37,73.15,98.89,99.29,7.62,5.31,49.17,27.79,50.61,31.6ZM158.94,663.48c-7.18,24.96,33.19,37,39.67,8.64,4.94-21.63-32.17-34.71-39.67-8.64Z"/>
+ <path class="cls-5"
d="M169.23,974.85c1.83-.01,26.38-12.13,33.67-14.12,30.88-8.43,76.67-7.99,106.31,5.29,7,3.13,22.99,11.57,10.68,19.45-6.25,4-37.09-8.47-48.07-10.44-17.8-3.19-41.81-2.25-59.39,2.03-4.35,1.06-28.06,8.52-28.03,11.47.01,1.1,7.27,10.87,6.93,20.5-1.67,47.44-66.49,50.76-75.46,8.93-5.71-26.65,13.58-47.15,39.59-47.01,5.53.03,10.52,3.93,13.77,3.91ZM133.09,1006.83c-3.61,16.45,20.94,30.4,32.89,17.57,25.23-27.1-25.08-53.18-32.89-17.57Z"/>
+ <path class="cls-5"
d="M289.52,725.1c-1.62-1.9-18.59-.36-29.14-16.72-30.8-47.8,57.3-88.71,65.78-30.42,4.25,29.22-18.21,35.37-19.93,43.43-.59,2.76,6.35,26.83,8.03,31.2,10.27,26.73,28.21,48.28,50.21,66.36,7.54,6.2,28.26,14.09,26.64,23.62-2.59,15.28-21.04,2.11-28.02-2.25-26.47-16.53-49.33-44.59-61.84-72.82-3.75-8.46-10.3-40.73-11.73-42.41ZM294.89,705.51c18.88-7.37,18.24-39.89-4.7-38.43-23.87,1.52-21.72,48.74,4.7,38.43Z"/>
+ <path
d="M464.94,1031.37c2.21,5.31-2.06,10.93-8.75,9.53-22.84-4.78-53.95-25.99-77.81-32.32-4.57-3.36-2.56-10.3,2.51-11.8,4.39-1.3,82.28,30.38,84.04,34.6Z"/>
+ <path
d="M472.62,1044.71c2.76-12.14,28.9-.8,25.85,8.36-3.22,9.68-27.75.01-25.85-8.36Z"/>
+ <path class="cls-8"
d="M1050.65,54.76c13.05.31,14.11,17.66,14.28,26.92.22,1.19.22,3.22,0,4.41-1.63,8.98-2.26,13.12-13.22,13.22-45.44-15.13-106.28,17.82-123.34,61.66,41.36-31.48,97.83-76.57,145.37-26.41,40.15,42.36,38.03,223.48-26.32,240.22-24.34,6.33-37.93-2.63-57.39-2.3-45.85.76-64.4,31.24-61.68,74.9-6.52-7.17-21.69-13-32.66-26.82-22.57-28.45-37.68-71.86-55.46-94.3-5.14-6.48-8.85,11-11.71,12.04-8.61-17.62-14.71-48.43-35.1-57.8-19.72-9.06-32.97-1.97-50.11-4.96,1.94-12.7-13.34-9.63-16
[...]
+ <g>
+ <path class="cls-5"
d="M2016.11,298.37h-65.61l-14.89,40.6h-12.8l54.69-144.52h11.61l54.69,144.52h-12.71l-14.99-40.6ZM1954.27,288.05h57.97l-28.98-78.71-28.98,78.71Z"/>
+ <path class="cls-5"
d="M2077.25,280.11v58.86h-12.21v-144.52h49.23c15.02,0,26.88,3.84,35.58,11.51,8.7,7.68,13.05,18.23,13.05,31.66s-4.19,24.04-12.56,31.42c-8.37,7.38-20.5,11.07-36.38,11.07h-36.73ZM2077.25,269.79h37.02c11.84,0,20.88-2.82,27.1-8.45,6.22-5.63,9.33-13.49,9.33-23.56s-3.09-17.98-9.28-23.91c-6.19-5.93-14.97-8.96-26.35-9.1h-37.82v65.01Z"/>
+ <path class="cls-5"
d="M2254.53,298.37h-65.61l-14.89,40.6h-12.8l54.69-144.52h11.61l54.69,144.52h-12.71l-14.99-40.6ZM2192.69,288.05h57.97l-28.98-78.71-28.98,78.71Z"/>
+ <path class="cls-5"
d="M2405.8,293.91c-1.65,15.22-7.1,26.87-16.33,34.94-9.23,8.07-21.52,12.11-36.87,12.11-10.72,0-20.2-2.68-28.44-8.04s-14.61-12.95-19.11-22.78c-4.5-9.83-6.78-21.06-6.85-33.7v-18.76c0-12.84,2.25-24.22,6.75-34.15,4.5-9.93,10.97-17.58,19.41-22.98,8.44-5.39,18.15-8.09,29.13-8.09,15.48,0,27.71,4.17,36.68,12.51,8.97,8.34,14.18,19.89,15.63,34.64h-12.31c-3.04-24.55-16.38-36.83-40-36.83-13.1,0-23.54,4.9-31.32,14.7-7.78,9.8-11.66,23.34-11.66,40.63v17.68c0,16.69,3.79,30,11.37
[...]
+ <path class="cls-5"
d="M2542.58,338.97h-12.31v-69.28h-82.58v69.28h-12.21v-144.52h12.21v64.92h82.58v-64.92h12.31v144.52Z"/>
+ <path class="cls-5"
d="M2659.11,269.69h-67.6v58.96h77.72v10.32h-89.93v-144.52h89.43v10.32h-77.22v54.59h67.6v10.32Z"/>
+ </g>
+ </g>
+</svg>
diff --git a/core/bench/dashboard/frontend/assets/style.css
b/core/bench/dashboard/frontend/assets/style.css
index 077bbd14f..287a880db 100644
--- a/core/bench/dashboard/frontend/assets/style.css
+++ b/core/bench/dashboard/frontend/assets/style.css
@@ -142,93 +142,6 @@ body {
to { opacity: 1; transform: translateY(0); }
}
-/* Mobile: sidebar becomes slide-in drawer, content spans full width. */
-@media (max-width: 768px) {
- .app-shell.detail-layout {
- grid-template-columns: 1fr;
- grid-template-areas:
- "bar"
- "main";
- }
-
- .app-shell.detail-layout .sidebar {
- position: fixed;
- top: 56px;
- left: 0;
- width: min(88vw, 380px);
- height: calc(100vh - 56px);
- z-index: 40;
- box-shadow: 4px 0 20px rgba(0, 0, 0, 0.15);
- transform: translateX(0);
- transition: transform 240ms cubic-bezier(0.2, 0.8, 0.2, 1);
- }
-
- .app-shell.detail-layout.sidebar-collapsed .sidebar {
- transform: translateX(-100%);
- pointer-events: none;
- }
-
- .app-shell.detail-layout:not(.sidebar-collapsed)::after {
- content: '';
- position: fixed;
- top: 56px;
- left: 0;
- right: 0;
- bottom: 0;
- background: rgba(0, 0, 0, 0.35);
- z-index: 35;
- backdrop-filter: blur(2px);
- }
-
- .app-bar {
- padding: 0 10px;
- }
-
- .app-bar-brand-text { display: none; }
- .app-bar-tab { padding: 6px 10px; font-size: 12px; }
- .app-bar-text-btn { padding: 6px 10px; font-size: 12px; }
-
- .hero-v2 { padding: 32px 16px 24px; }
- .hero-v2-inner { gap: 20px; }
- .hero-v2-title { font-size: clamp(40px, 14vw, 72px); }
- .hero-v2-cards { grid-template-columns: repeat(2, 1fr); gap: 10px; }
- .hero-v2-card { padding: 12px; }
- .hero-v2-card-value { font-size: 22px; }
-
- .compare-banner {
- flex-wrap: wrap;
- gap: 8px;
- padding: 8px 10px;
- }
- .compare-banner-names {
- flex: 1 1 100%;
- order: 2;
- flex-wrap: wrap;
- gap: 8px;
- }
- .compare-banner-unpin { order: 1; margin-left: auto; }
- .compare-grid { grid-template-columns: 1fr; }
-
- .tail-chart-wrap { padding: 12px; }
- .tail-chart-header { flex-wrap: wrap; gap: 8px; }
- .tail-chart-subject { max-width: 180px; }
-
- .footer-inner {
- grid-template-columns: 1fr;
- text-align: center;
- gap: 10px;
- }
- .footer-links { justify-content: center; }
- .footer-meta { justify-content: center; }
-}
-
-@media (max-width: 520px) {
- .app-bar-tabs { gap: 0; }
- .app-bar-tab { padding: 6px 8px; font-size: 11px; }
- .app-bar-icon-btn { width: 30px; height: 30px; }
- .hero-v2-cards { grid-template-columns: 1fr; }
-}
-
.app-bar { grid-area: bar; }
.sidebar { grid-area: side; }
.main-content { grid-area: main; }
@@ -640,8 +553,9 @@ body.dark .app-bar-toast {
}
.app-bar-brand img {
- width: 28px;
- height: 28px;
+ width: auto;
+ height: 40px;
+ max-width: 180px;
object-fit: contain;
}
@@ -1180,6 +1094,28 @@ body.dark .footer-version {
.footer-sep { opacity: 0.4; }
+.footer-tagline {
+ font-size: 11px;
+ color: var(--color-text-secondary);
+ letter-spacing: 0.02em;
+}
+
+.footer-heart {
+ color: #ef4444;
+ font-size: 12px;
+ margin: 0 2px;
+ display: inline-block;
+ animation: footer-heart-beat 2s ease-in-out infinite;
+}
+
+@keyframes footer-heart-beat {
+ 0%, 100% { transform: scale(1); }
+ 14% { transform: scale(1.15); }
+ 28% { transform: scale(1); }
+ 42% { transform: scale(1.15); }
+ 70% { transform: scale(1); }
+}
+
body.dark .footer {
background-color: var(--color-dark-background);
border-top-color: var(--color-dark-border);
@@ -1223,26 +1159,6 @@ body.dark .footer {
background: rgba(0, 0, 0, 0.8);
}
-.loading-spinner {
- width: var(--button-size);
- height: var(--button-size);
- border: var(--spacing-xs) solid var(--color-background);
- border-top: var(--spacing-xs) solid var(--color-text);
- border-radius: 50%;
- animation: spin var(--transition-speed-slow) linear infinite;
- transform: scale(0.5);
- transition: transform var(--transition-speed-slow);
-}
-
-.loading-overlay.visible .loading-spinner {
- transform: scale(1);
-}
-
-.dark .loading-spinner {
- border-color: var(--color-dark-background);
- border-top-color: var(--color-dark-text);
-}
-
@keyframes spin {
0% {
transform: rotate(0deg);
@@ -1944,18 +1860,14 @@ body.dark .skeleton-dot {
}
.dense-row {
- display: grid;
- grid-template-columns: 10px 1fr auto;
- align-items: center;
- gap: 10px;
- padding: 10px 12px;
+ display: flex;
+ align-items: stretch;
+ gap: 4px;
+ padding: 2px 4px;
background: transparent;
border: 1px solid transparent;
border-radius: 8px;
color: var(--color-text);
- cursor: pointer;
- text-align: left;
- font-family: inherit;
transition: background-color 120ms, border-color 120ms;
}
@@ -1981,6 +1893,28 @@ body.dark .dense-row.active {
box-shadow: inset 3px 0 0 #ff9103;
}
+.dense-row-select {
+ flex: 1 1 auto;
+ min-width: 0;
+ display: grid;
+ grid-template-columns: 10px 1fr;
+ align-items: center;
+ gap: 10px;
+ padding: 8px 8px;
+ background: transparent;
+ border: none;
+ border-radius: 6px;
+ color: inherit;
+ cursor: pointer;
+ text-align: left;
+ font-family: inherit;
+}
+
+.dense-row-select:focus-visible {
+ outline: 2px solid #ff9103;
+ outline-offset: 1px;
+}
+
.dense-row-dot {
width: 8px;
height: 8px;
@@ -2295,9 +2229,17 @@ body.dark .hero-v2 {
}
.hero-v2-loading {
+ position: fixed;
+ inset: 0;
+ padding: 0;
justify-content: center;
align-items: center;
- min-height: 520px;
+ z-index: 9998;
+ background: var(--color-background);
+}
+
+body.dark .hero-v2-loading {
+ background: var(--color-dark-background);
}
.hero-v2-loading-inner {
@@ -2314,8 +2256,9 @@ body.dark .hero-v2 {
}
.hero-v2-loading-mark {
- width: 112px;
- height: 112px;
+ width: auto;
+ height: 128px;
+ max-width: 440px;
object-fit: contain;
filter: drop-shadow(0 0 24px rgba(255, 145, 3, 0.35));
animation: hero-loading-pulse 1800ms ease-in-out infinite;
@@ -2370,6 +2313,36 @@ body.dark .hero-v2 {
border: 0;
}
+.iggy-loader {
+ display: inline-flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 14px;
+}
+
+.iggy-loader-mark {
+ object-fit: contain;
+ width: auto;
+ filter: drop-shadow(0 0 16px rgba(255, 145, 3, 0.3));
+ animation: hero-loading-pulse 1800ms ease-in-out infinite;
+}
+
+.iggy-loader-md .iggy-loader-mark { height: 72px; max-width: 260px; }
+.iggy-loader-lg .iggy-loader-mark { height: 128px; max-width: 440px; }
+
+.iggy-loader-label {
+ margin: 0;
+ color: var(--color-text-secondary);
+ font-size: 14px;
+ font-weight: 500;
+ letter-spacing: 0.02em;
+}
+
+body.dark .iggy-loader-label {
+ color: var(--color-dark-text-secondary);
+}
+
.hero-v2-headline {
display: flex;
flex-direction: column;
@@ -3270,3 +3243,264 @@ body.dark .sweep-view {
background: var(--color-dark-sidebar, #1a2234);
border-color: var(--color-dark-border);
}
+
+/* Mobile overrides kept at end of file so they win the cascade over
+ later desktop rules declared with the same specificity. */
+@media (max-width: 768px) {
+ .app-bar {
+ display: grid !important;
+ grid-template-columns: auto 1fr auto;
+ grid-template-areas:
+ "left right right"
+ "center center center";
+ row-gap: 2px;
+ column-gap: 6px;
+ align-items: center;
+ padding: 4px 8px;
+ height: auto;
+ min-height: 52px;
+ }
+ .app-bar-left {
+ grid-area: left;
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ min-width: 0;
+ }
+ .app-bar-right {
+ grid-area: right;
+ justify-self: end;
+ display: flex;
+ align-items: center;
+ gap: 2px;
+ }
+ .app-bar-center {
+ grid-area: center;
+ min-width: 0;
+ max-width: 100%;
+ overflow-x: auto;
+ overflow-y: hidden;
+ -webkit-overflow-scrolling: touch;
+ padding-bottom: 2px;
+ scrollbar-width: none;
+ }
+ .app-bar-center:empty { display: none; }
+ .app-bar-center::-webkit-scrollbar { display: none; }
+ .app-bar-tabs {
+ flex-wrap: nowrap;
+ justify-content: flex-start;
+ width: max-content;
+ }
+ .app-bar-brand img { width: 40px; height: 40px; }
+ .app-bar-brand-text { display: none; }
+ .app-bar-icon-btn { width: 36px; height: 36px; flex-shrink: 0; }
+ .app-bar-icon-btn svg { width: 16px; height: 16px; }
+ .app-bar-icon-wrap { flex-shrink: 0; }
+ .mobile-hide { display: none !important; }
+
+ .app-shell.detail-layout,
+ .app-shell.detail-layout.sidebar-collapsed {
+ grid-template-columns: 1fr;
+ grid-template-rows: auto 1fr;
+ grid-template-areas:
+ "bar"
+ "main";
+ }
+ .app-shell.detail-layout .sidebar {
+ position: fixed;
+ top: 56px;
+ left: 0;
+ width: min(92vw, 380px);
+ height: calc(100vh - 56px);
+ z-index: 40;
+ box-shadow: 4px 0 20px rgba(0, 0, 0, 0.15);
+ transform: translateX(0);
+ transition: transform 240ms cubic-bezier(0.2, 0.8, 0.2, 1);
+ }
+ .app-shell.detail-layout.sidebar-collapsed .sidebar {
+ transform: translateX(-100%);
+ pointer-events: none;
+ }
+ .app-shell.detail-layout:not(.sidebar-collapsed)::after {
+ content: '';
+ position: fixed;
+ top: 56px;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: rgba(0, 0, 0, 0.35);
+ z-index: 35;
+ backdrop-filter: blur(2px);
+ }
+
+ .hero-v2 { padding: 32px 16px 24px; }
+ .hero-v2-inner { gap: 20px; }
+ .hero-v2-title { font-size: clamp(40px, 14vw, 72px); }
+ .hero-v2-cards { grid-template-columns: repeat(2, 1fr); gap: 10px; }
+ .hero-v2-card { padding: 12px; }
+ .hero-v2-card-value { font-size: 22px; }
+
+ .compare-banner {
+ flex-wrap: wrap;
+ gap: 8px;
+ padding: 8px 10px;
+ }
+ .compare-banner-names {
+ flex: 1 1 100%;
+ order: 2;
+ flex-wrap: wrap;
+ gap: 8px;
+ }
+ .compare-banner-unpin { order: 1; margin-left: auto; }
+ .compare-grid { grid-template-columns: 1fr; }
+
+ .tail-chart-wrap { padding: 12px; }
+ .tail-chart-header { flex-wrap: wrap; gap: 8px; }
+ .tail-chart-subject { max-width: 180px; }
+
+ .footer-inner {
+ grid-template-columns: 1fr;
+ text-align: center;
+ gap: 10px;
+ }
+ .footer-links { justify-content: center; }
+ .footer-meta { justify-content: center; }
+
+ html, body {
+ height: auto !important;
+ min-height: 100vh;
+ max-height: none !important;
+ overflow: auto !important;
+ }
+ #app {
+ display: block;
+ height: auto !important;
+ min-height: 100vh;
+ max-height: none !important;
+ overflow: visible !important;
+ }
+ .app-container {
+ min-height: auto;
+ }
+ .app-shell {
+ flex: initial;
+ height: auto !important;
+ min-height: calc(100vh - 40px);
+ max-height: none !important;
+ overflow: visible !important;
+ }
+ .app-shell.detail-layout,
+ .app-shell.detail-layout.sidebar-collapsed {
+ height: auto;
+ min-height: 100vh;
+ }
+ .main-content {
+ padding-top: 8px;
+ overflow: visible !important;
+ min-height: 0;
+ height: auto;
+ }
+ .content-wrapper {
+ padding: 0;
+ overflow: visible !important;
+ min-height: 0;
+ height: auto;
+ }
+
+ .chart-title {
+ margin: 0 8px 8px;
+ padding: 6px 4px 8px;
+ gap: 2px;
+ }
+ .chart-title-primary {
+ font-size: 14px;
+ line-height: 1.3;
+ word-break: break-word;
+ }
+ .chart-title-identifier {
+ font-size: 11px;
+ gap: 6px;
+ margin-top: 4px;
+ padding: 0;
+ }
+ .chart-title-gitref { padding: 1px 7px; font-size: 11px; }
+
+ .single-view {
+ padding: 0 4px;
+ min-height: 320px;
+ height: 55vh;
+ max-height: 480px;
+ }
+ .single-view > div { min-height: 0; }
+
+ .benchmark-meta { margin: 0 8px; }
+ .benchmark-meta-toggle { padding: 8px 10px; }
+ .benchmark-meta-body { padding: 8px 10px 10px; }
+ .benchmark-meta-row {
+ grid-template-columns: 1fr;
+ gap: 4px;
+ align-items: start;
+ }
+ .benchmark-meta-label {
+ border-right: none;
+ padding-right: 0;
+ font-size: 9.5px;
+ }
+ .benchmark-meta-chip {
+ font-size: 10.5px;
+ padding: 2px 6px;
+ gap: 5px;
+ }
+ .benchmark-meta-chip-label { font-size: 9.5px; }
+
+ .compare-wrapper { gap: 10px; }
+ .compare-pane { padding: 8px; }
+ .compare-pane-label { font-size: 10px; }
+ .compare-banner-badge { font-size: 10px; padding: 3px 6px; }
+ .compare-banner-name { max-width: 42vw; }
+
+ .app-bar-toast {
+ right: auto;
+ left: 50%;
+ transform: translateX(-50%);
+ max-width: calc(100vw - 24px);
+ }
+
+ .benchmark-info-tooltip,
+ .embed-modal {
+ min-width: 0;
+ width: min(340px, calc(100vw - 24px));
+ position: fixed;
+ right: 8px;
+ top: 104px;
+ }
+}
+
+@media (max-width: 520px) {
+ .app-bar-tabs { gap: 0; }
+ .app-bar-tab { padding: 6px 8px; font-size: 11px; }
+ .hero-v2-cards { grid-template-columns: 1fr; }
+ .chart-title-primary { font-size: 13px; }
+ .chart-title-identifier { font-size: 10.5px; }
+ .benchmark-meta-toggle-hint { display: none; }
+ .benchmark-meta-chip { font-size: 10px; }
+ .sweep-view { padding: 8px; margin: 8px; }
+ .sweep-view-title { font-size: 12px; flex-wrap: wrap; }
+ .sweep-view-hint { display: none; }
+ .sweep-chart { height: 200px; }
+ .compare-banner {
+ flex-direction: column;
+ align-items: stretch;
+ }
+ .compare-banner-names { justify-content: center; }
+ .compare-banner-unpin { align-self: center; }
+}
+
+@media (max-width: 400px) {
+ .app-bar { padding: 4px 6px; column-gap: 2px; }
+ .app-bar-left { gap: 2px; }
+ .app-bar-right { gap: 0; }
+ .app-bar-icon-btn { width: 34px; height: 34px; }
+ .app-bar-brand img { width: 36px; height: 36px; }
+ .app-bar-brand { padding: 2px; }
+}
diff --git a/core/bench/dashboard/frontend/index.dev.html
b/core/bench/dashboard/frontend/index.dev.html
index ff968b22e..4d7316857 100644
--- a/core/bench/dashboard/frontend/index.dev.html
+++ b/core/bench/dashboard/frontend/index.dev.html
@@ -40,7 +40,64 @@
</head>
<body>
- <div id="app"></div>
+ <div id="app">
+ <div class="boot-splash" role="status" aria-live="polite">
+ <div class="boot-splash-body">
+ <img class="boot-splash-mark" src="/assets/iggy-dark.svg"
alt="Apache Iggy" />
+ <div class="boot-splash-sub">Benchmarks</div>
+ </div>
+ </div>
+ </div>
+ <style>
+ .boot-splash {
+ position: fixed;
+ inset: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: #f5f5f5;
+ color: #0b1220;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI",
Roboto, sans-serif;
+ z-index: 9999;
+ }
+ .boot-splash-body {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 14px;
+ padding: 0 24px;
+ }
+ @media (prefers-color-scheme: dark) {
+ .boot-splash { background: #0b1220; color: #f5f5f5; }
+ .boot-splash-mark { content: url("/assets/iggy-light.svg"); }
+ }
+ .boot-splash-mark {
+ width: auto;
+ height: 128px;
+ max-width: 440px;
+ object-fit: contain;
+ filter: drop-shadow(0 0 24px rgba(255, 145, 3, 0.35));
+ animation: boot-splash-pulse 1800ms ease-in-out infinite;
+ }
+ .boot-splash-brand {
+ margin-top: 4px;
+ font-size: 11px;
+ font-weight: 600;
+ letter-spacing: 0.22em;
+ text-transform: uppercase;
+ color: #ff9103;
+ }
+ .boot-splash-sub {
+ font-size: clamp(28px, 4vw, 44px);
+ font-weight: 800;
+ letter-spacing: -0.02em;
+ line-height: 1;
+ }
+ @keyframes boot-splash-pulse {
+ 0%, 100% { opacity: 0.4; transform: scale(0.96); }
+ 50% { opacity: 1; transform: scale(1); }
+ }
+ </style>
</body>
</html>
diff --git a/core/bench/dashboard/frontend/index.html
b/core/bench/dashboard/frontend/index.html
index ff968b22e..4d7316857 100644
--- a/core/bench/dashboard/frontend/index.html
+++ b/core/bench/dashboard/frontend/index.html
@@ -40,7 +40,64 @@
</head>
<body>
- <div id="app"></div>
+ <div id="app">
+ <div class="boot-splash" role="status" aria-live="polite">
+ <div class="boot-splash-body">
+ <img class="boot-splash-mark" src="/assets/iggy-dark.svg"
alt="Apache Iggy" />
+ <div class="boot-splash-sub">Benchmarks</div>
+ </div>
+ </div>
+ </div>
+ <style>
+ .boot-splash {
+ position: fixed;
+ inset: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: #f5f5f5;
+ color: #0b1220;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI",
Roboto, sans-serif;
+ z-index: 9999;
+ }
+ .boot-splash-body {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 14px;
+ padding: 0 24px;
+ }
+ @media (prefers-color-scheme: dark) {
+ .boot-splash { background: #0b1220; color: #f5f5f5; }
+ .boot-splash-mark { content: url("/assets/iggy-light.svg"); }
+ }
+ .boot-splash-mark {
+ width: auto;
+ height: 128px;
+ max-width: 440px;
+ object-fit: contain;
+ filter: drop-shadow(0 0 24px rgba(255, 145, 3, 0.35));
+ animation: boot-splash-pulse 1800ms ease-in-out infinite;
+ }
+ .boot-splash-brand {
+ margin-top: 4px;
+ font-size: 11px;
+ font-weight: 600;
+ letter-spacing: 0.22em;
+ text-transform: uppercase;
+ color: #ff9103;
+ }
+ .boot-splash-sub {
+ font-size: clamp(28px, 4vw, 44px);
+ font-weight: 800;
+ letter-spacing: -0.02em;
+ line-height: 1;
+ }
+ @keyframes boot-splash-pulse {
+ 0%, 100% { opacity: 0.4; transform: scale(0.96); }
+ 50% { opacity: 1; transform: scale(1); }
+ }
+ </style>
</body>
</html>
diff --git a/core/bench/dashboard/frontend/index.prod.html
b/core/bench/dashboard/frontend/index.prod.html
index de430f330..f86b5ed0a 100644
--- a/core/bench/dashboard/frontend/index.prod.html
+++ b/core/bench/dashboard/frontend/index.prod.html
@@ -55,6 +55,63 @@
</head>
<body>
- <div id="app"></div>
+ <div id="app">
+ <div class="boot-splash" role="status" aria-live="polite">
+ <div class="boot-splash-body">
+ <img class="boot-splash-mark" src="/assets/iggy-dark.svg"
alt="Apache Iggy" />
+ <div class="boot-splash-sub">Benchmarks</div>
+ </div>
+ </div>
+ </div>
+ <style>
+ .boot-splash {
+ position: fixed;
+ inset: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: #f5f5f5;
+ color: #0b1220;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI",
Roboto, sans-serif;
+ z-index: 9999;
+ }
+ .boot-splash-body {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 14px;
+ padding: 0 24px;
+ }
+ @media (prefers-color-scheme: dark) {
+ .boot-splash { background: #0b1220; color: #f5f5f5; }
+ .boot-splash-mark { content: url("/assets/iggy-light.svg"); }
+ }
+ .boot-splash-mark {
+ width: auto;
+ height: 128px;
+ max-width: 440px;
+ object-fit: contain;
+ filter: drop-shadow(0 0 24px rgba(255, 145, 3, 0.35));
+ animation: boot-splash-pulse 1800ms ease-in-out infinite;
+ }
+ .boot-splash-brand {
+ margin-top: 4px;
+ font-size: 11px;
+ font-weight: 600;
+ letter-spacing: 0.22em;
+ text-transform: uppercase;
+ color: #ff9103;
+ }
+ .boot-splash-sub {
+ font-size: clamp(28px, 4vw, 44px);
+ font-weight: 800;
+ letter-spacing: -0.02em;
+ line-height: 1;
+ }
+ @keyframes boot-splash-pulse {
+ 0%, 100% { opacity: 0.4; transform: scale(0.96); }
+ 50% { opacity: 1; transform: scale(1); }
+ }
+ </style>
</body>
</html>
diff --git a/core/bench/dashboard/frontend/src/components/chart/single_chart.rs
b/core/bench/dashboard/frontend/src/components/chart/single_chart.rs
index d4e3c491d..e89151c14 100644
--- a/core/bench/dashboard/frontend/src/components/chart/single_chart.rs
+++ b/core/bench/dashboard/frontend/src/components/chart/single_chart.rs
@@ -17,6 +17,7 @@
use crate::api::fetch_benchmark_report_full;
use crate::components::chart::{PlotConfig, dispose_chart};
+use crate::components::loader::{IggyLoader, LoaderSize};
use crate::components::selectors::measurement_type_selector::MeasurementType;
use crate::hooks::use_size;
use bench_report::report::BenchmarkReport;
@@ -26,7 +27,6 @@ use bench_report::{
use charming::theme::Theme;
use charming::{Echarts, WasmRenderer};
use gloo::console::log;
-use gloo::history::{BrowserHistory, History};
use uuid::Uuid;
use yew::platform::spawn_local;
use yew::prelude::*;
@@ -57,17 +57,6 @@ pub fn single_chart(props: &SingleChartProps) -> Html {
let benchmark_uuid = *benchmark_uuid;
is_loading.set(true);
- let current_location = web_sys::window()
- .and_then(|w| w.location().pathname().ok())
- .unwrap_or_default();
-
- let expected_path = format!("/benchmarks/{benchmark_uuid}");
-
- if current_location != expected_path {
- let history = BrowserHistory::new();
- history.push(expected_path);
- }
-
spawn_local(async move {
match fetch_benchmark_report_full(&benchmark_uuid).await {
Ok(data) => {
@@ -152,7 +141,7 @@ pub fn single_chart(props: &SingleChartProps) -> Html {
<div id={canvas_id} style="width: 100%; height: 100%;"></div>
</div>
<div class={classes!("loading-overlay", loading_class)}>
- <div class="loading-spinner"></div>
+ <IggyLoader size={LoaderSize::Medium} />
</div>
</div>
}
diff --git a/core/bench/dashboard/frontend/src/components/footer.rs
b/core/bench/dashboard/frontend/src/components/footer.rs
index 58cfd6f0f..573d00f29 100644
--- a/core/bench/dashboard/frontend/src/components/footer.rs
+++ b/core/bench/dashboard/frontend/src/components/footer.rs
@@ -44,6 +44,12 @@ pub fn footer() -> Html {
<a href="https://www.apache.org/" target="_blank"
rel="noopener noreferrer">
{"Apache Software Foundation"}
</a>
+ <span class="footer-sep">{"•"}</span>
+ <span class="footer-tagline">
+ {"Built with "}
+ <span class="footer-heart"
aria-label="love">{"❤"}</span>
+ {" for the message streaming community"}
+ </span>
</div>
</div>
</footer>
diff --git a/core/bench/dashboard/frontend/src/components/layout/hero.rs
b/core/bench/dashboard/frontend/src/components/layout/hero.rs
index 899ccfc85..dcc0b9bda 100644
--- a/core/bench/dashboard/frontend/src/components/layout/hero.rs
+++ b/core/bench/dashboard/frontend/src/components/layout/hero.rs
@@ -21,7 +21,6 @@ use crate::format::format_ms;
use crate::router::AppRoute;
use crate::state::benchmark::{latest_sweep, pick_best_from_recent_batch};
use bench_dashboard_shared::BenchmarkReportLight;
-use chrono::DateTime;
use gloo::console::log;
use gloo::timers::callback::Timeout;
use std::cell::Cell;
@@ -166,7 +165,6 @@ struct HeroStats {
peak_msg_s: Option<(f64, String)>,
max_scale: Option<MaxScale>,
total: usize,
- latest_ts: Option<String>,
showcase: Option<BenchmarkReportLight>,
}
@@ -226,13 +224,6 @@ fn compute_stats<'a>(benchmarks: impl Iterator<Item = &'a
BenchmarkReportLight>)
pretty_name: pretty_name.clone(),
});
}
- if stats
- .latest_ts
- .as_ref()
- .is_none_or(|current| &benchmark.timestamp > current)
- {
- stats.latest_ts = Some(benchmark.timestamp.clone());
- }
}
stats
}
@@ -339,7 +330,7 @@ fn render_stat_cards(stats: &HeroStats) -> Html {
}
{ render_scale_card(1, stats.max_scale.as_ref()) }
{ render_showcase_card(2, stats.showcase.as_ref()) }
- { render_summary_card(3, stats.total, stats.latest_ts.as_deref()) }
+ { render_volume_card(3, stats.showcase.as_ref()) }
</div>
}
}
@@ -413,23 +404,58 @@ fn render_showcase_card(stagger: usize, showcase:
Option<&BenchmarkReportLight>)
}
}
-fn render_summary_card(stagger: usize, total: usize, latest_ts: Option<&str>)
-> Html {
- let sub = match latest_ts {
- Some(ts) => format!("Latest: {}", format_date(ts)),
- None => String::new(),
+fn render_volume_card(stagger: usize, showcase: Option<&BenchmarkReportLight>)
-> Html {
+ let Some(benchmark) = showcase else {
+ return html! {};
+ };
+ let total_bytes = benchmark.total_bytes();
+ if total_bytes == 0 {
+ return html! {};
+ }
+ let (value, unit) = format_volume(total_bytes);
+ let messages = benchmark.total_messages_sent() +
benchmark.total_messages_received();
+ let sub = if messages > 0 {
+ format!("{} messages moved", format_count(messages))
+ } else {
+ String::new()
};
html! {
<div class="hero-v2-card" style={format!("--stagger: {stagger}")}>
<div class="hero-v2-card-value-row">
- <span class="hero-v2-card-value">{total}</span>
- <span class="hero-v2-card-unit">{"runs"}</span>
+ <span class="hero-v2-card-value">{value}</span>
+ <span class="hero-v2-card-unit">{unit}</span>
</div>
- <div class="hero-v2-card-label">{"Benchmarks loaded"}</div>
+ <div class="hero-v2-card-label">{"Volume pushed in run"}</div>
<div class="hero-v2-card-sub">{sub}</div>
</div>
}
}
+fn format_volume(bytes: u64) -> (String, &'static str) {
+ let bytes = bytes as f64;
+ if bytes >= 1_000_000_000_000.0 {
+ (format_significant(bytes / 1_000_000_000_000.0), "TB")
+ } else if bytes >= 1_000_000_000.0 {
+ (format_significant(bytes / 1_000_000_000.0), "GB")
+ } else if bytes >= 1_000_000.0 {
+ (format_significant(bytes / 1_000_000.0), "MB")
+ } else {
+ (format_significant(bytes / 1_000.0), "kB")
+ }
+}
+
+fn format_count(value: u64) -> String {
+ if value >= 1_000_000_000 {
+ format!("{:.2}B", value as f64 / 1_000_000_000.0)
+ } else if value >= 1_000_000 {
+ format!("{:.1}M", value as f64 / 1_000_000.0)
+ } else if value >= 1_000 {
+ format!("{:.1}k", value as f64 / 1_000.0)
+ } else {
+ value.to_string()
+ }
+}
+
fn format_throughput_bytes(mb_per_s: f64) -> (String, &'static str) {
if mb_per_s >= 1_000_000.0 {
(format_significant(mb_per_s / 1_000_000.0), "TB/s")
@@ -462,18 +488,11 @@ fn format_significant(v: f64) -> String {
}
}
-fn format_date(timestamp_str: &str) -> String {
- match DateTime::parse_from_rfc3339(timestamp_str) {
- Ok(t) => t.format("%Y-%m-%d").to_string(),
- Err(_) => "unknown".to_string(),
- }
-}
-
fn render_hero_loading(is_dark: bool, is_slow: bool) -> Html {
let logo_src = if is_dark {
- "/assets/iggy-light.png"
+ "/assets/iggy-light.svg"
} else {
- "/assets/iggy-dark.png"
+ "/assets/iggy-dark.svg"
};
html! {
<div class="hero-v2 hero-v2-loading" aria-busy="true"
aria-live="polite">
@@ -485,7 +504,6 @@ fn render_hero_loading(is_dark: bool, is_slow: bool) ->
Html {
alt=""
aria-hidden="true"
/>
- <div class="hero-v2-loading-brand">{"Apache Iggy"}</div>
<div class="hero-v2-loading-sub">{"Benchmarks"}</div>
if is_slow {
<p class="hero-v2-loading-slow">
@@ -498,10 +516,6 @@ fn render_hero_loading(is_dark: bool, is_slow: bool) ->
Html {
}
}
-/// Every headline field comes from the SAME benchmark that powers the
-/// tail chart and "View details" link. Built through this single helper
-/// so the big number, subject name, CPU, and gitref can never drift to
-/// different benchmarks.
#[derive(Default, Debug, PartialEq)]
pub struct ShowcaseDisplay {
pub formatted_value: String,
diff --git
a/core/bench/dashboard/frontend/src/components/layout/main_content.rs
b/core/bench/dashboard/frontend/src/components/layout/main_content.rs
index 4125b053e..6dc8c2fe2 100644
--- a/core/bench/dashboard/frontend/src/components/layout/main_content.rs
+++ b/core/bench/dashboard/frontend/src/components/layout/main_content.rs
@@ -19,6 +19,7 @@ use crate::components::chart::single_chart::SingleChart;
use crate::components::chart::tail_chart::TailChart;
use crate::components::layout::benchmark_meta::BenchmarkMeta;
use crate::components::layout::sweep_view::SweepView;
+use crate::components::loader::{IggyLoader, LoaderSize};
use crate::components::selectors::measurement_type_selector::MeasurementType;
use crate::router::AppRoute;
use crate::state::benchmark::use_benchmark;
@@ -224,17 +225,15 @@ fn render_loading() -> Html {
html! {
<div class="content-wrapper">
<div class="empty-state">
- <div class="empty-state-content">
- <h2>{"Loading benchmark..."}</h2>
- </div>
+ <IggyLoader
+ size={LoaderSize::Large}
+ label={AttrValue::from("Loading the benchmark...")}
+ />
</div>
</div>
}
}
-/// Map a benchmark gitref to the matching apache/iggy URL.
-/// Tagged releases (`X.Y.Z`, `X.Y.Z-edge.N`) are prefixed `server-` to
-/// match the repo's tag scheme. Plain commit hashes link directly.
fn iggy_gitref_url(gitref: &str) -> String {
if crate::version::parse_semver_recency(gitref).is_some() {
format!("https://github.com/apache/iggy/tree/server-{gitref}")
diff --git a/core/bench/dashboard/frontend/src/components/layout/top_app_bar.rs
b/core/bench/dashboard/frontend/src/components/layout/top_app_bar.rs
index 6b1f28e1e..76c81513d 100644
--- a/core/bench/dashboard/frontend/src/components/layout/top_app_bar.rs
+++ b/core/bench/dashboard/frontend/src/components/layout/top_app_bar.rs
@@ -172,9 +172,9 @@ pub fn top_app_bar(props: &TopAppBarProps) -> Html {
"Switch to dark theme"
};
let logo_src = if is_dark {
- "/assets/iggy-light.png"
+ "/assets/iggy-light.svg"
} else {
- "/assets/iggy-dark.png"
+ "/assets/iggy-dark.svg"
};
html! {
@@ -241,14 +241,14 @@ pub fn top_app_bar(props: &TopAppBarProps) -> Html {
</div>
<button
type="button"
- class="app-bar-icon-btn"
+ class="app-bar-icon-btn mobile-hide"
onclick={on_download_artifacts}
title="Download test artifacts"
aria-label="Download test artifacts"
>
{ render_download_icon() }
</button>
- <div class="app-bar-icon-wrap">
+ <div class="app-bar-icon-wrap mobile-hide">
<button
type="button"
class={classes!("app-bar-icon-btn",
ui.is_embed_modal_visible.then_some("active"))}
@@ -268,7 +268,7 @@ pub fn top_app_bar(props: &TopAppBarProps) -> Html {
/>
}
</div>
- <div class="app-bar-icon-wrap">
+ <div class="app-bar-icon-wrap mobile-hide">
<ServerStatsToggle
is_visible={ui.is_server_stats_tooltip_visible}
on_toggle={on_server_stats_toggle}
@@ -282,7 +282,7 @@ pub fn top_app_bar(props: &TopAppBarProps) -> Html {
/>
}
</div>
- <div class="app-bar-icon-wrap">
+ <div class="app-bar-icon-wrap mobile-hide">
<BenchmarkInfoToggle
is_visible={ui.is_benchmark_tooltip_visible}
on_toggle={on_benchmark_tooltip_toggle}
diff --git a/core/bench/dashboard/frontend/src/components/loader.rs
b/core/bench/dashboard/frontend/src/components/loader.rs
new file mode 100644
index 000000000..d2a7bd1f8
--- /dev/null
+++ b/core/bench/dashboard/frontend/src/components/loader.rs
@@ -0,0 +1,64 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use yew::prelude::*;
+
+#[derive(Clone, Copy, PartialEq)]
+pub enum LoaderSize {
+ Medium,
+ Large,
+}
+
+impl LoaderSize {
+ fn css_class(self) -> &'static str {
+ match self {
+ Self::Medium => "iggy-loader-md",
+ Self::Large => "iggy-loader-lg",
+ }
+ }
+}
+
+#[derive(Properties, PartialEq)]
+pub struct IggyLoaderProps {
+ #[prop_or(LoaderSize::Medium)]
+ pub size: LoaderSize,
+ #[prop_or_default]
+ pub label: Option<AttrValue>,
+}
+
+#[function_component(IggyLoader)]
+pub fn iggy_loader(props: &IggyLoaderProps) -> Html {
+ let (is_dark, _) = use_context::<(bool, Callback<()>)>().expect("Theme
context not found");
+ let logo_src = if is_dark {
+ "/assets/iggy-light.svg"
+ } else {
+ "/assets/iggy-dark.svg"
+ };
+ let class = classes!("iggy-loader", props.size.css_class());
+
+ html! {
+ <div class={class} role="status" aria-live="polite">
+ <img class="iggy-loader-mark" src={logo_src} alt=""
aria-hidden="true" />
+ if let Some(label) = props.label.as_ref() {
+ <p class="iggy-loader-label">{label.clone()}</p>
+ }
+ <span class="visually-hidden">
+ { props.label.clone().unwrap_or_else(||
AttrValue::from("Loading")) }
+ </span>
+ </div>
+ }
+}
diff --git a/core/bench/dashboard/frontend/src/components/mod.rs
b/core/bench/dashboard/frontend/src/components/mod.rs
index 0781daaf9..cf9eece08 100644
--- a/core/bench/dashboard/frontend/src/components/mod.rs
+++ b/core/bench/dashboard/frontend/src/components/mod.rs
@@ -20,6 +20,7 @@ pub mod chart;
pub mod embed_modal;
pub mod footer;
pub mod layout;
+pub mod loader;
pub mod selectors;
pub mod theme;
pub mod tooltips;
diff --git
a/core/bench/dashboard/frontend/src/components/selectors/dense_benchmark_row.rs
b/core/bench/dashboard/frontend/src/components/selectors/dense_benchmark_row.rs
index bd96d97bb..e94bca615 100644
---
a/core/bench/dashboard/frontend/src/components/selectors/dense_benchmark_row.rs
+++
b/core/bench/dashboard/frontend/src/components/selectors/dense_benchmark_row.rs
@@ -50,20 +50,16 @@ pub fn dense_benchmark_row(props: &DenseBenchmarkRowProps)
-> Html {
.to_lowercase()
.replace(' ', "-");
- let on_click = {
+ let on_select_click = {
let on_select = props.on_select.clone();
let benchmark = benchmark.clone();
- Callback::from(move |_| on_select.emit(benchmark.clone()))
+ Callback::from(move |_: MouseEvent| on_select.emit(benchmark.clone()))
};
let on_pin_click = {
let on_toggle_pin = props.on_toggle_pin.clone();
let benchmark = benchmark.clone();
- Callback::from(move |event: MouseEvent| {
- event.stop_propagation();
- event.prevent_default();
- on_toggle_pin.emit(benchmark.clone());
- })
+ Callback::from(move |_: MouseEvent|
on_toggle_pin.emit(benchmark.clone()))
};
let pin_title = if is_pinned {
@@ -71,46 +67,33 @@ pub fn dense_benchmark_row(props: &DenseBenchmarkRowProps)
-> Html {
} else {
"Compare with this"
};
+ let select_aria = format!("Select benchmark {display_name}");
- let on_key_down = {
- let on_click = on_click.clone();
- Callback::from(move |event: KeyboardEvent| {
- if event.target() != event.current_target() {
- return;
- }
- if event.key() == "Enter" || event.key() == " " {
- event.prevent_default();
- on_click.emit(MouseEvent::new("click").unwrap());
- }
- })
- };
-
- let row_aria = format!("Select benchmark {display_name}");
html! {
- <div
- role="button"
- tabindex="0"
- aria-label={row_aria}
- aria-pressed={is_selected.to_string()}
- class={classes!(
- "dense-row",
- is_selected.then_some("active"),
- is_pinned.then_some("pinned"),
- )}
- onclick={on_click}
- onkeydown={on_key_down}
- >
- <span class={classes!("dense-row-dot", kind_class)} />
- <div class="dense-row-body">
- <div class="dense-row-title">{display_name}</div>
- <div class="dense-row-meta">
- { render_metrics(benchmark) }
- if props.show_timestamp {
- <span class="dense-row-meta-sep">{"·"}</span>
- <span class="dense-row-time">{
relative_time(&benchmark.timestamp) }</span>
- }
+ <div class={classes!(
+ "dense-row",
+ is_selected.then_some("active"),
+ is_pinned.then_some("pinned"),
+ )}>
+ <button
+ type="button"
+ class="dense-row-select"
+ onclick={on_select_click}
+ aria-label={select_aria}
+ aria-pressed={is_selected.to_string()}
+ >
+ <span class={classes!("dense-row-dot", kind_class)} />
+ <div class="dense-row-body">
+ <div class="dense-row-title">{display_name}</div>
+ <div class="dense-row-meta">
+ { render_metrics(benchmark) }
+ if props.show_timestamp {
+ <span class="dense-row-meta-sep">{"·"}</span>
+ <span class="dense-row-time">{
relative_time(&benchmark.timestamp) }</span>
+ }
+ </div>
</div>
- </div>
+ </button>
<button
type="button"
class={classes!("dense-row-compare-btn",
is_pinned.then_some("active"))}
diff --git a/core/bench/dashboard/frontend/src/main.rs
b/core/bench/dashboard/frontend/src/main.rs
index f36373842..78b13f54d 100644
--- a/core/bench/dashboard/frontend/src/main.rs
+++ b/core/bench/dashboard/frontend/src/main.rs
@@ -67,5 +67,10 @@ fn switch(routes: AppRoute) -> Html {
}
fn main() {
+ if let Some(document) = web_sys::window().and_then(|w| w.document())
+ && let Ok(Some(splash)) = document.query_selector(".boot-splash")
+ {
+ splash.remove();
+ }
yew::Renderer::<App>::new().render();
}