This is an automated email from the ASF dual-hosted git repository. spetz pushed a commit to branch bench_loader_mobile in repository https://gitbox.apache.org/repos/asf/iggy.git
commit e38dbb2209939a45e3cff06d342596be842490c0 Author: spetz <[email protected]> AuthorDate: Tue Apr 21 14:04:31 2026 +0200 fix(bench): fix mobile layout, compare URL, and shared branded loader --- 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..664f135d9 --- /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> \ No newline at end of file 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..34286b86e --- /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> \ No newline at end of file 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(); }
