[OCaml] High Intensity Training Online
refactor Cross the logbook boundary with a view model
The logbook record list read the workout name, stimuli count, and completeness straight off Repository.record and Evidence.Workout. Add a Logbook_entry DTO, map it in the controller, and render only the DTO. This was the last entity crossing: the presenter now names no core entity or repository type, so `open Hito_app` is gone from both pages.ml and pages.mli. Only plain view models cross into the presenter. 243 tests pass.
lib/web/handlers.ml
@@ -798,6 +798,19 @@
798
798
in
799
799
List.find_map of_signal (Evidence.Feedback.signals report)
800
800
801
Added:
let entry_view (record : Repository.record) : View_model.Logbook_entry.t =
802
Added:
let workout = record.Repository.workout in
803
Added:
{
804
Added:
id = (record.Repository.id :> string);
805
Added:
workout_name =
806
Added:
Prescription.Workout.name (Evidence.Workout.prescription workout);
807
Added:
stimuli_count = List.length (Evidence.Workout.stimuli workout);
808
Added:
complete =
809
Added:
(match Evidence.Workout.completeness workout with
810
Added:
| Evidence.Workout.Complete -> true
811
Added:
| Incomplete -> false);
812
Added:
}
813
Added:
801
814
let feedback_view (report : Evidence.Feedback.t) :
802
815
View_model.Feedback.report =
803
816
{
@@ -820,6 +833,7 @@
820
833
Service.history t.service trainee.Trainee.id >>= fun records ->
821
834
Service.feedback t.service trainee.Trainee.id >>= fun feedback ->
822
835
let feedback = List.map feedback_view feedback in
836
Added:
let records = List.map entry_view records in
823
837
let saved_flow = feedback_flow request in
824
838
let feedback_open =
825
839
match
lib/web/pages.ml
@@ -1,5 +1,4 @@
1
1
open Dream_html
2
Removed:
open Hito_app
3
2
4
3
type page = Dream_html.node
5
4
@@ -1383,27 +1382,24 @@
1383
1382
else
1384
1383
tag "ul" []
1385
1384
(List.map
1386
Removed:
(fun record ->
1387
Removed:
let workout = record.Repository.workout in
1388
Removed:
let status =
1389
Removed:
match Evidence.Workout.completeness workout with
1390
Removed:
| Evidence.Workout.Complete -> "complete"
1391
Removed:
| Incomplete -> "incomplete"
1392
Removed:
in
1385
Added:
(fun (entry : View_model.Logbook_entry.t) ->
1393
1386
tag "li" []
1394
1387
[
1395
1388
tag "a"
1396
1389
[
1397
Removed:
href Routes.record (record.Repository.id :> string);
1390
Added:
href Routes.record entry.id;
1398
1391
Dream_html.attr "data-hito-app-link";
1399
1392
]
1400
1393
[
1401
Removed:
txt "%s — %d stimuli"
1402
Removed:
(Prescription.Workout.name
1403
Removed:
(Evidence.Workout.prescription workout))
1404
Removed:
(List.length (Evidence.Workout.stimuli workout));
1394
Added:
txt "%s — %d stimuli" entry.workout_name
1395
Added:
entry.stimuli_count;
1405
1396
];
1406
Removed:
tag "p" [ class_ "done" ] [ txt "%s" status ];
1397
Added:
tag "p"
1398
Added:
[ class_ "done" ]
1399
Added:
[
1400
Added:
txt "%s"
1401
Added:
(if entry.complete then "complete" else "incomplete");
1402
Added:
];
1407
1403
])
1408
1404
records));
1409
1405
tag "section"
lib/web/pages.mli
@@ -1,5 +1,3 @@
1
Removed:
open Hito_app
2
Removed:
3
1
type page = Dream_html.node
4
2
5
3
val login :
@@ -63,7 +61,7 @@
63
61
?suggest_feedback:bool ->
64
62
?feedback_flow:feedback_flow ->
65
63
?feedback_open:bool ->
66
Removed:
Repository.record list ->
64
Added:
View_model.Logbook_entry.t list ->
67
65
page
68
66
(** The logbook: recorded workouts and a modal sequential subjective feedback
69
67
flow. [feedback] lists past reports, most recent first. [suggest_feedback]
lib/web/view_model.ml
@@ -120,3 +120,15 @@
120
120
Prescription entity. Extension/ending selection stays in the presenter
121
121
form, since its option set is fixed UI vocabulary, not domain data. *)
122
122
end
123
Added:
124
Added:
module Logbook_entry = struct
125
Added:
type t = {
126
Added:
id : string; (** Record id for the link. *)
127
Added:
workout_name : string;
128
Added:
stimuli_count : int;
129
Added:
complete : bool;
130
Added:
}
131
Added:
(** One saved workout as the logbook list shows it: a link, a name, how many
132
Added:
stimuli it holds, and whether it is complete. No Repository record and no
133
Added:
Evidence.Workout entity. *)
134
Added:
end