[OCaml] High Intensity Training Online
feat give each prescribed exercise its own routine sub-row
Render the routine table with one sub-row per prescribed exercise. The workout name spans its exercises through a row-group heading, and each sub-row carries its own exercise-name and rep-band cells. Drop the stimuli-count column: a count is neither a plan detail a trainee acts on nor, per HD1, an achievement to display. Reps stay a band the load calibrates against, never a target.
Changed files
lib/web/pages.ml
@@ -342,17 +342,22 @@
342
342
let id_string (id : Repository.routine_id) = (id :> string)
343
343
let error_id input_id = input_id ^ "-error"
344
344
345
Removed:
let describe_prescription prescription =
345
Added:
(* The exercise name for one prescribed stimulus, without the rep window. A
346
Added:
pre-exhaust names both movements. *)
347
Added:
let prescription_exercise prescription =
348
Added:
match Prescription.Stimulus.delivery prescription with
349
Added:
| Prescription.Stimulus.Single exercise -> Exercise.name exercise
350
Added:
| Prescription.Stimulus.Pre_exhaust { isolation; compound } ->
351
Added:
Printf.sprintf "%s into %s, no pause" (Exercise.name isolation)
352
Added:
(Exercise.name compound)
353
Added:
354
Added:
(* The prescribed rep window, phrased as a band the load calibrates against.
355
Added:
Reps are an outcome, never a target (HD1, "Proper Weight Selection"). *)
356
Added:
let prescription_reps prescription =
346
357
let min_reps, max_reps =
347
358
Prescription.Rep_range.bounds (Prescription.Stimulus.rep_range prescription)
348
359
in
349
Removed:
let window = Printf.sprintf "%d-%d reps" min_reps max_reps in
350
Removed:
match Prescription.Stimulus.delivery prescription with
351
Removed:
| Prescription.Stimulus.Single exercise ->
352
Removed:
Printf.sprintf "%s — %s" (Exercise.name exercise) window
353
Removed:
| Prescription.Stimulus.Pre_exhaust { isolation; compound } ->
354
Removed:
Printf.sprintf "%s into %s, no pause — %s" (Exercise.name isolation)
355
Removed:
(Exercise.name compound) window
360
Added:
Printf.sprintf "%d-%d reps" min_reps max_reps
356
361
357
362
let extension_select ?(selected = "") ?(invalid = false) ~input_id () =
358
363
let error_attrs =
@@ -563,32 +568,43 @@
563
568
[ txt "Workout" ];
564
569
tag "th"
565
570
[ Dream_html.string_attr "scope" "col" ]
566
Removed:
[ txt "Stimuli" ];
571
Added:
[ txt "Exercise" ];
567
572
tag "th"
568
573
[ Dream_html.string_attr "scope" "col" ]
569
Removed:
[ txt "Prescription" ];
574
Added:
[ txt "Reps" ];
570
575
];
571
576
];
577
Added:
(* One sub-row per prescribed exercise. The workout name spans its
578
Added:
exercises through a row-group heading, so each exercise gets its
579
Added:
own name and rep-band cells and no stimuli count is shown. *)
572
580
tag "tbody" []
573
Removed:
(List.map
581
Added:
(List.concat_map
574
582
(fun workout ->
575
583
let stimuli = Prescription.Workout.stimuli workout in
576
Removed:
tag "tr" []
577
Removed:
[
578
Removed:
tag "th"
579
Removed:
[ Dream_html.string_attr "scope" "row" ]
580
Removed:
[ txt "%s" (Prescription.Workout.name workout) ];
581
Removed:
tag "td" [] [ txt "%d" (List.length stimuli) ];
582
Removed:
tag "td" []
583
Removed:
[
584
Removed:
tag "ul" []
585
Removed:
(List.map
586
Removed:
(fun stimulus ->
587
Removed:
tag "li" []
588
Removed:
[ txt "%s" (describe_prescription stimulus) ])
589
Removed:
stimuli);
590
Removed:
];
591
Removed:
])
584
Added:
let name = Prescription.Workout.name workout in
585
Added:
List.mapi
586
Added:
(fun index stimulus ->
587
Added:
let workout_cell =
588
Added:
if index = 0 then
589
Added:
[
590
Added:
tag "th"
591
Added:
[
592
Added:
Dream_html.string_attr "scope" "rowgroup";
593
Added:
Dream_html.string_attr "rowspan" "%d"
594
Added:
(List.length stimuli);
595
Added:
]
596
Added:
[ txt "%s" name ];
597
Added:
]
598
Added:
else []
599
Added:
in
600
Added:
tag "tr" []
601
Added:
(workout_cell
602
Added:
@ [
603
Added:
tag "td" []
604
Added:
[ txt "%s" (prescription_exercise stimulus) ];
605
Added:
tag "td" [] [ txt "%s" (prescription_reps stimulus) ];
606
Added:
]))
607
Added:
stimuli)
592
608
(Prescription.Routine.workouts routine));
593
609
];
594
610
]
test/test_web.ml
@@ -603,6 +603,18 @@
603
603
"includes prescription" true
604
604
(contains ~substring:"Dumbbell Flyes into Incline Presses" page);
605
605
Alcotest.(check bool)
606
Added:
"heads an exercise column" true
607
Added:
(contains ~substring:"Exercise" page);
608
Added:
Alcotest.(check bool)
609
Added:
"heads a reps column" true
610
Added:
(contains ~substring:"Reps" page);
611
Added:
Alcotest.(check bool)
612
Added:
"gives each exercise its own sub-row" true
613
Added:
(contains ~substring:"rowgroup" page);
614
Added:
Alcotest.(check bool)
615
Added:
"drops the stimuli count column" false
616
Added:
(contains ~substring:"Stimuli" page);
617
Added:
Alcotest.(check bool)
606
618
"shows primary navigation" true
607
619
(contains ~substring:"primary-nav" page);
608
620
Alcotest.(check bool)