[Perl] DAQ system for the FAPG.
feat add info toggle with explainer to probe cards
Each probe card now has an ⓘ button that reveals a collapsible explanation of the measurement: what it means, optimal range, and what affects it. Same WCAG-compliant pattern as insights. Explainers per probe: - pH: acidity, nitrification/photosynthesis effects - DO: oxygen levels, night/temperature dependencies - ORP: water cleanliness, correlation with DO - EC: nutrient concentration, water change effects
roles/dashboard/templates/dashboard/probe-card.html.ep
@@ -1,3 +1,10 @@
1
Added:
% my %explainers = (
2
Added:
% ph => 'Measures acidity/alkalinity of the water. Optimal range for aquaponics is 6.4–7.2 pH. Affected by nitrification (lowers pH) and photosynthesis (raises pH).',
3
Added:
% do => 'Dissolved oxygen available to fish and bacteria. Should stay above 5.5 mg/L. Drops at night (no photosynthesis) and in warm water (lower O₂ solubility).',
4
Added:
% orp => 'Oxidation-Reduction Potential indicates water cleanliness. 250–400 mV is healthy. Low ORP suggests organic buildup; correlates with DO.',
5
Added:
% ec => 'Electrical conductivity reflects dissolved nutrient concentration. 300–1500 µS/cm is typical. Rising EC means nutrient accumulation; drops after water changes.',
6
Added:
% );
7
Added:
% my $info_id = "info-probe-$probe->{key}";
1
8
<div class="card">
2
9
<div class="card-header d-flex justify-content-between align-items-start gap-2">
3
10
<div class="probe-card-title min-w-0">
@@ -6,29 +13,48 @@
6
13
</h1>
7
14
<p class="small mb-0 mt-1" data-variation="<%= $probe->{key} %>"></p>
8
15
</div>
9
Removed:
<div class="dropdown flex-shrink-0">
10
Removed:
<button
11
Removed:
class="btn btn-sm btn-outline-secondary dropdown-toggle"
12
Removed:
type="button"
13
Removed:
data-bs-toggle="dropdown"
14
Removed:
aria-expanded="false"
15
Removed:
aria-label="Actions for <%= $probe->{label} %>">
16
Added:
<div class="d-flex align-items-center gap-2 flex-shrink-0">
17
Added:
<button class="btn btn-sm btn-link text-body-secondary p-0 info-toggle"
18
Added:
type="button"
19
Added:
data-bs-toggle="collapse"
20
Added:
data-bs-target="#<%= $info_id %>"
21
Added:
aria-expanded="false"
22
Added:
aria-controls="<%= $info_id %>"
23
Added:
aria-label="About this probe">
24
Added:
<svg width="18" height="18" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true">
25
Added:
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16"/>
26
Added:
<path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0"/>
27
Added:
</svg>
16
28
</button>
17
Removed:
<ul class="dropdown-menu dropdown-menu-end">
18
Removed:
<li>
19
Removed:
<a
20
Removed:
class="dropdown-item graph-download-button"
21
Removed:
href="/downloads/readings.csv?probe=<%= $probe->{key} %>&timeframe=day&range=1"
22
Removed:
data-raw-download
23
Removed:
data-probe="<%= $probe->{key} %>">Download raw data</a>
24
Removed:
</li>
25
Removed:
</ul>
29
Added:
<div class="dropdown">
30
Added:
<button
31
Added:
class="btn btn-sm btn-outline-secondary dropdown-toggle"
32
Added:
type="button"
33
Added:
data-bs-toggle="dropdown"
34
Added:
aria-expanded="false"
35
Added:
aria-label="Actions for <%= $probe->{label} %>">
36
Added:
</button>
37
Added:
<ul class="dropdown-menu dropdown-menu-end">
38
Added:
<li>
39
Added:
<a
40
Added:
class="dropdown-item graph-download-button"
41
Added:
href="/downloads/readings.csv?probe=<%= $probe->{key} %>&timeframe=day&range=1"
42
Added:
data-raw-download
43
Added:
data-probe="<%= $probe->{key} %>">Download raw data</a>
44
Added:
</li>
45
Added:
</ul>
46
Added:
</div>
26
47
</div>
27
48
</div>
49
Added:
<div class="collapse" id="<%= $info_id %>">
50
Added:
<div class="card-body border-bottom py-2">
51
Added:
<p class="text-body-secondary small mb-0"><%= $explainers{$probe->{key}} // 'Trend for this measurement over time.' %></p>
52
Added:
</div>
53
Added:
</div>
28
54
<div class="card-body">
29
55
<section id="probe-<%= $probe->{key} %>" class="tab-panel is-active" data-panel="<%= $probe->{key} %>">
30
56
<div class="chart-wrap">
31
Removed:
<canvas id="chart-<%= $probe->{key} %>" role="img" aria-label="<%= $probe->{label} %> readings chart"></canvas>
57
Added:
<canvas id="chart-<%= $probe->{key} %>" role="img" aria-label="<%= $probe->{label} %> trend over time"></canvas>
32
58
</div>
33
59
% unless (stash('single_probe')) {
34
60
<p class="text-body-secondary small mt-2 mb-0 reading-status placeholder-glow" data-status="<%= $probe->{key} %>">