[Perl] DAQ system for the FAPG.
feat collapse graph controls on mobile
- wrap shared graph controls in an accessible mobile disclosure - add a directional chevron that reflects the expanded state - group timeframe and smoothing controls on one uniform menu surface - preserve always-visible controls on desktop clients - cover the disclosure contract in the probe page test
Changed files
roles/dashboard/public/css/app.css
@@ -679,6 +679,16 @@
679
679
margin: 0;
680
680
}
681
681
682
Added:
.graph-controls-disclosure,
683
Added:
.graph-controls-panel {
684
Added:
display: flex;
685
Added:
align-items: center;
686
Added:
}
687
Added:
688
Added:
.graph-controls-toggle {
689
Added:
display: none;
690
Added:
}
691
Added:
682
692
.graph-control .timeframe-option {
683
693
display: flex;
684
694
min-width: 4.75rem;
@@ -975,6 +985,67 @@
975
985
.toolbar-items {
976
986
width: 100%;
977
987
margin-left: 0;
988
Added:
}
989
Added:
990
Added:
.graph-controls-disclosure {
991
Added:
display: block;
992
Added:
width: 100%;
993
Added:
}
994
Added:
995
Added:
.graph-controls-toggle {
996
Added:
display: flex;
997
Added:
align-items: center;
998
Added:
justify-content: space-between;
999
Added:
width: 100%;
1000
Added:
min-height: var(--toolbar-item-height);
1001
Added:
border: 1px solid var(--border);
1002
Added:
border-radius: 0.5rem;
1003
Added:
padding: 0.5rem 0.75rem;
1004
Added:
background: white;
1005
Added:
color: var(--text);
1006
Added:
cursor: pointer;
1007
Added:
font: inherit;
1008
Added:
font-weight: 700;
1009
Added:
}
1010
Added:
1011
Added:
.graph-controls-toggle::after {
1012
Added:
width: 0.55rem;
1013
Added:
height: 0.55rem;
1014
Added:
margin: 0 0.2rem 0.25rem 0.75rem;
1015
Added:
border-right: 2px solid currentColor;
1016
Added:
border-bottom: 2px solid currentColor;
1017
Added:
content: "";
1018
Added:
transform: rotate(45deg);
1019
Added:
transition: transform 0.15s ease;
1020
Added:
}
1021
Added:
1022
Added:
.graph-controls-toggle[aria-expanded="true"]::after {
1023
Added:
margin-top: 0.25rem;
1024
Added:
margin-bottom: 0;
1025
Added:
transform: rotate(225deg);
1026
Added:
}
1027
Added:
1028
Added:
.graph-controls-toggle:hover {
1029
Added:
border-color: var(--accent);
1030
Added:
background: var(--accent-soft);
1031
Added:
}
1032
Added:
1033
Added:
.graph-controls-toggle:focus-visible {
1034
Added:
outline: 2px solid var(--accent);
1035
Added:
outline-offset: 2px;
1036
Added:
}
1037
Added:
1038
Added:
.graph-controls-panel {
1039
Added:
display: none;
1040
Added:
margin-top: 0.5rem;
1041
Added:
border: 1px solid var(--border);
1042
Added:
border-radius: 0.5rem;
1043
Added:
padding: 0.75rem;
1044
Added:
background: var(--card);
1045
Added:
}
1046
Added:
1047
Added:
.graph-controls-toggle[aria-expanded="true"] + .graph-controls-panel {
1048
Added:
display: block;
978
1049
}
979
1050
980
1051
.toolbar-items .graph-control {
roles/dashboard/public/js/dashboard.js
@@ -130,6 +130,10 @@
130
130
return Array.from(document.querySelectorAll("[data-raw-download]"));
131
131
}
132
132
133
Added:
function graphControlsToggles() {
134
Added:
return Array.from(document.querySelectorAll("[data-graph-controls-toggle]"));
135
Added:
}
136
Added:
133
137
function labelForRow(row) {
134
138
return formatChartTime(row.timestamp);
135
139
}
@@ -938,6 +942,13 @@
938
942
smoothingToggles().forEach(toggle => {
939
943
toggle.addEventListener("change", () => {
940
944
setSmoothing(toggle.checked);
945
Added:
});
946
Added:
});
947
Added:
948
Added:
graphControlsToggles().forEach(toggle => {
949
Added:
toggle.addEventListener("click", () => {
950
Added:
const expanded = toggle.getAttribute("aria-expanded") === "true";
951
Added:
toggle.setAttribute("aria-expanded", expanded ? "false" : "true");
941
952
});
942
953
});
943
954
roles/dashboard/t/01-graph-page.t
@@ -22,6 +22,10 @@
22
22
->element_exists(
23
23
'div.toolbar-items div.graph-control > div.timeframe-control[role="group"]'
24
24
)
25
Added:
->text_is(
26
Added:
'button[data-graph-controls-toggle][aria-expanded="false"][aria-controls="graph-controls-panel"]',
27
Added:
'Graph controls'
28
Added:
)
25
29
->element_exists('input[data-smoothing-toggle][checked]')
26
30
->text_is( 'a[data-raw-download][data-probe="ph"]', 'Download raw data' )
27
31
->element_exists('tbody[data-reading-messages="ph"]')
roles/dashboard/templates/dashboard/graph-control.html.ep
@@ -1,31 +1,41 @@
1
1
<!-- -*- mode: web; -*- -->
2
2
3
Removed:
<div class="graph-control">
4
Removed:
<div class="timeframe-control" role="group" aria-label="<%= $aria_label %>">
5
Removed:
% for my $timeframe ( [ hour => 'Hourly' ], [ day => 'Daily' ], [ week => 'Weekly' ], [ month => 'Monthly' ], [ year => 'Yearly' ] ) {
6
Removed:
<div class="timeframe-option" data-timeframe-option="<%= $timeframe->[0] %>">
7
Removed:
<button
8
Removed:
class="timeframe-adjustment"
9
Removed:
type="button"
10
Removed:
data-timeframe-adjustment="decrease"
11
Removed:
data-timeframe="<%= $timeframe->[0] %>"
12
Removed:
aria-label="Decrease <%= $timeframe->[0] %> range">−</button>
13
Removed:
<button
14
Removed:
class="timeframe-button<%= $timeframe->[0] eq 'day' ? ' is-active' : '' %>"
15
Removed:
type="button"
16
Removed:
data-timeframe="<%= $timeframe->[0] %>"
17
Removed:
data-timeframe-label="<%= $timeframe->[1] %>"><%= $timeframe->[1] %></button>
18
Removed:
<button
19
Removed:
class="timeframe-adjustment"
20
Removed:
type="button"
21
Removed:
data-timeframe-adjustment="increase"
22
Removed:
data-timeframe="<%= $timeframe->[0] %>"
23
Removed:
aria-label="Increase <%= $timeframe->[0] %> range">+</button>
3
Added:
<div class="graph-controls-disclosure">
4
Added:
<button
5
Added:
class="graph-controls-toggle"
6
Added:
type="button"
7
Added:
aria-expanded="false"
8
Added:
aria-controls="graph-controls-panel"
9
Added:
data-graph-controls-toggle>Graph controls</button>
10
Added:
<div class="graph-controls-panel" id="graph-controls-panel">
11
Added:
<div class="graph-control">
12
Added:
<div class="timeframe-control" role="group" aria-label="<%= $aria_label %>">
13
Added:
% for my $timeframe ( [ hour => 'Hourly' ], [ day => 'Daily' ], [ week => 'Weekly' ], [ month => 'Monthly' ], [ year => 'Yearly' ] ) {
14
Added:
<div class="timeframe-option" data-timeframe-option="<%= $timeframe->[0] %>">
15
Added:
<button
16
Added:
class="timeframe-adjustment"
17
Added:
type="button"
18
Added:
data-timeframe-adjustment="decrease"
19
Added:
data-timeframe="<%= $timeframe->[0] %>"
20
Added:
aria-label="Decrease <%= $timeframe->[0] %> range">−</button>
21
Added:
<button
22
Added:
class="timeframe-button<%= $timeframe->[0] eq 'day' ? ' is-active' : '' %>"
23
Added:
type="button"
24
Added:
data-timeframe="<%= $timeframe->[0] %>"
25
Added:
data-timeframe-label="<%= $timeframe->[1] %>"><%= $timeframe->[1] %></button>
26
Added:
<button
27
Added:
class="timeframe-adjustment"
28
Added:
type="button"
29
Added:
data-timeframe-adjustment="increase"
30
Added:
data-timeframe="<%= $timeframe->[0] %>"
31
Added:
aria-label="Increase <%= $timeframe->[0] %> range">+</button>
32
Added:
</div>
33
Added:
% }
24
34
</div>
25
Removed:
% }
35
Added:
<label class="smoothing-control">
36
Added:
<input type="checkbox" data-smoothing-toggle checked>
37
Added:
<span>Smoothed</span>
38
Added:
</label>
39
Added:
</div>
26
40
</div>
27
Removed:
<label class="smoothing-control">
28
Removed:
<input type="checkbox" data-smoothing-toggle checked>
29
Removed:
<span>Smoothed</span>
30
Removed:
</label>
31
41
</div>