Skip to content

Commit b676771

Browse files
committed
furtherchanges
1 parent d462550 commit b676771

File tree

15 files changed

+392
-289
lines changed

15 files changed

+392
-289
lines changed

crates/server/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ async fn main() {
99
// Get allowed origins from environment variable or use defaults
1010
let origins_str = std::env::var("HRT_ALLOWED_ORIGINS")
1111
.unwrap_or_else(|_| "http://127.0.0.1:4100,http://127.0.0.1:3000,http://localhost:4100,http://localhost:3000".to_string());
12-
12+
1313
let origins: Vec<HeaderValue> = origins_str
1414
.split(',')
1515
.filter_map(|s| s.trim().parse::<HeaderValue>().ok())

crates/web/src/charts/estrannaise.rs

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use leptos::window;
21
use chrono::{Local, TimeZone};
2+
use leptos::window;
33
use plotters::element::DashedPathElement;
44
use plotters::prelude::*;
55
use plotters_canvas::CanvasBackend;
@@ -175,9 +175,7 @@ pub fn draw_estrannaise_chart(canvas_id: &str, series: &EstrannaiseSeries, zoom:
175175
}
176176
} else {
177177
let line = series.blended.iter().map(|p| (p.x, p.y));
178-
chart
179-
.draw_series(LineSeries::new(line, blended_style))
180-
.ok();
178+
chart.draw_series(LineSeries::new(line, blended_style)).ok();
181179
}
182180
}
183181
if !series.stepped.is_empty() {
@@ -195,32 +193,27 @@ pub fn draw_estrannaise_chart(canvas_id: &str, series: &EstrannaiseSeries, zoom:
195193
if historical.len() > 1 {
196194
chart
197195
.draw_series(std::iter::once(DashedPathElement::new(
198-
historical,
199-
6,
200-
4,
201-
step_style,
196+
historical, 6, 4, step_style,
202197
)))
203198
.ok();
204199
}
205200
if forecast.len() > 1 {
206201
chart
207202
.draw_series(std::iter::once(DashedPathElement::new(
208-
forecast,
209-
2,
210-
6,
211-
step_style,
203+
forecast, 2, 6, step_style,
212204
)))
213205
.ok();
214206
}
215207
} else {
216-
let line = series.stepped.iter().map(|p| (p.x, p.y)).collect::<Vec<_>>();
208+
let line = series
209+
.stepped
210+
.iter()
211+
.map(|p| (p.x, p.y))
212+
.collect::<Vec<_>>();
217213
if line.len() > 1 {
218214
chart
219215
.draw_series(std::iter::once(DashedPathElement::new(
220-
line,
221-
6,
222-
4,
223-
step_style,
216+
line, 6, 4, step_style,
224217
)))
225218
.ok();
226219
}

crates/web/src/layout.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pub fn page_layout(title: &'static str, body: View) -> impl IntoView {
2222

2323
let is_running = move || stopwatch_start.get().is_some();
2424
let elapsed_ms = move || {
25+
let _tick = stopwatch_tick.get();
2526
let base = stopwatch_accum.get();
2627
if let Some(start) = stopwatch_start.get() {
2728
base + (Date::now() - start)
@@ -121,7 +122,6 @@ pub fn page_layout(title: &'static str, body: View) -> impl IntoView {
121122
on:click=move |_| stopwatch_open.set(!stopwatch_open.get())
122123
>
123124
{move || {
124-
let _tick = stopwatch_tick.get();
125125
if is_running() {
126126
format!("Stopwatch · {}", format_stopwatch(elapsed_ms()))
127127
} else {

crates/web/src/lib.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,40 @@ pub fn mount_app() {
7272

7373
#[cfg(not(target_arch = "wasm32"))]
7474
pub use server::serve;
75+
76+
#[cfg(test)]
77+
mod tests {
78+
fn assert_no_numeric_input_type(file_name: &str, source: &str) {
79+
assert!(
80+
!source.contains("type=\"number\""),
81+
"{file_name} still contains type=\"number\" which blocks decimal typing in some browsers/locales"
82+
);
83+
}
84+
85+
#[test]
86+
fn decimal_entry_pages_do_not_use_number_input_type() {
87+
let pages = [
88+
("pages/backup.rs", include_str!("pages/backup.rs")),
89+
("pages/calc.rs", include_str!("pages/calc.rs")),
90+
(
91+
"pages/create_blood_test.rs",
92+
include_str!("pages/create_blood_test.rs"),
93+
),
94+
(
95+
"pages/create_dosage.rs",
96+
include_str!("pages/create_dosage.rs"),
97+
),
98+
(
99+
"pages/create_measurement.rs",
100+
include_str!("pages/create_measurement.rs"),
101+
),
102+
("pages/estrannaise.rs", include_str!("pages/estrannaise.rs")),
103+
("pages/vials.rs", include_str!("pages/vials.rs")),
104+
("pages/view.rs", include_str!("pages/view.rs")),
105+
];
106+
107+
for (file_name, source) in pages {
108+
assert_no_numeric_input_type(file_name, source);
109+
}
110+
}
111+
}

crates/web/src/pages/backup.rs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use wasm_bindgen::JsCast;
77
use crate::layout::page_layout;
88
use crate::store;
99
use crate::store::use_store;
10+
use crate::utils::parse_decimal;
1011
use hrt_shared::types::{HormoneUnits, Settings};
1112

1213
#[component]
@@ -15,6 +16,13 @@ pub fn BackupPage() -> impl IntoView {
1516
let settings = store.settings;
1617

1718
let ics_secret = create_rw_signal(settings.get().icsSecret.unwrap_or_default());
19+
let blood_test_interval_months = create_rw_signal(
20+
settings
21+
.get()
22+
.bloodTestIntervalMonths
23+
.map(|v| v.to_string())
24+
.unwrap_or_default(),
25+
);
1826
let ics_url = create_memo({
1927
let ics_secret = ics_secret;
2028
move |_| {
@@ -40,14 +48,17 @@ pub fn BackupPage() -> impl IntoView {
4048
let on_save_settings = {
4149
let store = store.clone();
4250
let ics_secret = ics_secret;
51+
let blood_test_interval_months = blood_test_interval_months;
4352
move |_: leptos::ev::MouseEvent| {
4453
let secret = ics_secret.get();
54+
let interval = parse_decimal(&blood_test_interval_months.get());
4555
store.settings.update(|s| {
4656
s.icsSecret = if secret.trim().is_empty() {
4757
None
4858
} else {
4959
Some(secret)
5060
};
61+
s.bloodTestIntervalMonths = interval;
5162
});
5263
store.mark_dirty();
5364
}
@@ -209,24 +220,20 @@ pub fn BackupPage() -> impl IntoView {
209220
</div>
210221
<label>"Blood test interval (months)"</label>
211222
<input
212-
type="number"
223+
type="text"
213224
step="any"
214225
min="1"
215-
on:input={
226+
on:input=move |ev| blood_test_interval_months.set(event_target_value(&ev))
227+
on:blur={
216228
let store = store.clone();
217-
move |ev| {
218-
let value = event_target_value(&ev);
219-
let parsed = value.parse::<f64>().ok();
229+
let blood_test_interval_months = blood_test_interval_months;
230+
move |_| {
231+
let parsed = parse_decimal(&blood_test_interval_months.get());
220232
store.settings.update(|s| s.bloodTestIntervalMonths = parsed);
221233
store.mark_dirty();
222234
}
223235
}
224-
prop:value=move || store
225-
.settings
226-
.get()
227-
.bloodTestIntervalMonths
228-
.map(|v| v.to_string())
229-
.unwrap_or_else(|| "".to_string())
236+
prop:value=move || blood_test_interval_months.get()
230237
/>
231238
<label>"ICS URL secret (optional)"</label>
232239
<input

crates/web/src/pages/calc.rs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use leptos::*;
22

33
use crate::layout::page_layout;
4+
use crate::utils::parse_decimal_or_nan;
45

56
#[derive(Clone, Copy)]
67
struct Gear {
@@ -37,11 +38,7 @@ const GEARS: [Gear; 4] = [
3738
];
3839

3940
fn parse_num(value: &str) -> f64 {
40-
value
41-
.trim()
42-
.replace(',', ".")
43-
.parse::<f64>()
44-
.unwrap_or(f64::NAN)
41+
parse_decimal_or_nan(value)
4542
}
4643

4744
fn fmt(value: f64, decimals: usize) -> String {
@@ -169,7 +166,7 @@ pub fn CalcPage() -> impl IntoView {
169166
<label class="calc-field">
170167
"Dose (mg)"
171168
<input
172-
type="number"
169+
type="text"
173170
min="0"
174171
step="any"
175172
on:input=move |ev| tfs_dose_mg.set(event_target_value(&ev))
@@ -179,7 +176,7 @@ pub fn CalcPage() -> impl IntoView {
179176
<label class="calc-field">
180177
"Concentration (mg/mL)"
181178
<input
182-
type="number"
179+
type="text"
183180
min="0"
184181
step="any"
185182
on:input=move |ev| tfs_conc_mg_ml.set(event_target_value(&ev))
@@ -206,7 +203,7 @@ pub fn CalcPage() -> impl IntoView {
206203
<label class="calc-field">
207204
"Volume (mL)"
208205
<input
209-
type="number"
206+
type="text"
210207
min="0"
211208
step="any"
212209
on:input=move |ev| tfs_vol2_ml.set(event_target_value(&ev))
@@ -216,7 +213,7 @@ pub fn CalcPage() -> impl IntoView {
216213
<label class="calc-field">
217214
"Concentration (mg/mL)"
218215
<input
219-
type="number"
216+
type="text"
220217
min="0"
221218
step="any"
222219
on:input=move |ev| tfs_conc2_mg_ml.set(event_target_value(&ev))
@@ -251,7 +248,7 @@ pub fn CalcPage() -> impl IntoView {
251248
<label class="calc-field">
252249
"I am injecting (mg)"
253250
<input
254-
type="number"
251+
type="text"
255252
min="0"
256253
step="any"
257254
inputmode="decimal"
@@ -262,7 +259,7 @@ pub fn CalcPage() -> impl IntoView {
262259
<label class="calc-field">
263260
"Every (days)"
264261
<input
265-
type="number"
262+
type="text"
266263
min="0"
267264
step="any"
268265
inputmode="decimal"
@@ -273,7 +270,7 @@ pub fn CalcPage() -> impl IntoView {
273270
<label class="calc-field">
274271
"My vial is (mL)"
275272
<input
276-
type="number"
273+
type="text"
277274
min="0"
278275
step="any"
279276
inputmode="decimal"
@@ -284,7 +281,7 @@ pub fn CalcPage() -> impl IntoView {
284281
<label class="calc-field">
285282
"At concentration (mg/mL)"
286283
<input
287-
type="number"
284+
type="text"
288285
min="0"
289286
step="any"
290287
inputmode="decimal"

0 commit comments

Comments
 (0)