refactor remove unused workout inline errors

The workout flow reports validation errors through post-redirect-get flash messages, so the unreachable inline-error API only duplicated wording.

Commit
b7c159117a2f3a58da6c8d706ca8d5fb7a37a08f
Author
Marius Peter <dev@marius-peter.com>
Author date
Committer
Marius Peter <dev@marius-peter.com>
Committer date
Changed files
lib/presenter/page_kit.ml
index 6ecfb26a..4c2e2324 100644..100644
@@ -21,15 +21,3 @@
21 21 tag "p"
22 22 [ class_ "warn"; Dream_html.string_attr "role" "alert" ]
23 23 [ Dream_html.txt "%s" message ]
24 Removed:
25 Removed: let error_text = function
26 Removed: | "error.required" -> "Enter a value."
27 Removed: | "error.expected.number" -> "Enter a valid number."
28 Removed: | "error.expected.int" -> "Enter a valid whole number."
29 Removed: | "error.reps" -> "Enter at least one repetition."
30 Removed: | "error.load" -> "Enter a finite, nonnegative load."
31 Removed: | "error.extension" -> "Select one of the offered endings."
32 Removed: | key -> key
33 Removed:
34 Removed: let errors_to_text errors =
35 Removed: errors |> List.map (fun (_, key) -> error_text key) |> String.concat " "
lib/presenter/pages.mli
index bcb01521..b0d7816a 100644..100644
@@ -35,8 +35,6 @@
35 35 val workout :
36 36 Dream.request ->
37 37 viewer:View_model.Viewer.t ->
38 Removed: ?errors:(string * string) list ->
39 Removed: ?editing:int ->
40 38 ?workout_started:int ->
41 39 record_id:string option ->
42 40 active_slot:int ->
@@ -52,7 +50,8 @@
52 50 and [Some id] for a saved history record. [workout_started] drives the nav
53 51 timer: a live workout uses its own start, so it is ignored there; a
54 52 saved-record view passes the epoch of a separate workout in progress, if
55 Removed: any. *)
53 Added: any. A refused record or correction is reported through the flash message on
54 Added: the post-redirect-get reload, not inline. *)
56 55
57 56 val feedback_factors : (string * string) list
58 57 (** Ordered factor codes and labels. Each is a radio group in the feedback form
lib/presenter/pages_workout.ml
index 42077072..3d2cbd0d 100644..100644
@@ -2,17 +2,7 @@
2 2 open Page_kit
3 3 open Page_shell
4 4
5 Removed: let error_id input_id = input_id ^ "-error"
6 Removed:
7 Removed: let extension_select ?(selected = "") ?(invalid = false) ~input_id () =
8 Removed: let error_attrs =
9 Removed: if invalid then
10 Removed: [
11 Removed: Dream_html.string_attr "aria-invalid" "true";
12 Removed: Dream_html.string_attr "aria-describedby" "%s" (error_id input_id);
13 Removed: ]
14 Removed: else []
15 Removed: in
5 Added: let extension_select ?(selected = "") ~input_id () =
16 6 let option (code : string) label =
17 7 let attrs = [ Dream_html.string_attr "value" "%s" code ] in
18 8 let attrs =
@@ -22,8 +12,7 @@
22 12 tag "option" attrs [ txt "%s" label ]
23 13 in
24 14 tag "select"
25 Removed: ([ name "extension"; Dream_html.string_attr "id" "%s" input_id ]
26 Removed: @ error_attrs)
15 Added: [ name "extension"; Dream_html.string_attr "id" "%s" input_id ]
27 16 [
28 17 option "" "to positive failure";
29 18 option "forced" "then forced reps";
@@ -31,26 +20,12 @@
31 20 option "static" "then a static hold";
32 21 ]
33 22
34 Removed: let error_for ~input_id (field : string) (errors : (string * string) list) =
35 Removed: match List.assoc_opt field errors with
36 Removed: | None -> []
37 Removed: | Some error ->
38 Removed: [
39 Removed: tag "p"
40 Removed: [
41 Removed: Dream_html.string_attr "id" "%s" (error_id input_id);
42 Removed: class_ "warn";
43 Removed: Dream_html.string_attr "role" "alert";
44 Removed: ]
45 Removed: [ txt "%s" (errors_to_text [ (field, error) ]) ];
46 Removed: ]
47 Removed:
48 23 (* One movement as a grid group: exercise name, load input, reps input. The
49 24 group is a [div] that is [display:contents], so its three cells fall on the
50 25 enclosing grid under the shared Load and Reps headings. A pre-exhaust pair is
51 26 two such groups. *)
52 Removed: let movement_group ~(errors : (string * string) list) ~name ~load_id ~load_field
53 Removed: ~reps_id ~reps_field ?load_value ?reps_value ?previous ~reps_label () =
27 Added: let movement_group ~name ~load_id ~load_field ~reps_id ~reps_field ?load_value
28 Added: ?reps_value ?previous ~reps_label () =
54 29 let number_field ~input_id ~field ~value ~step_ ~label =
55 30 tag "div"
56 31 [ class_ "field field-number" ]
@@ -66,13 +41,6 @@
66 41 step "%s" step_;
67 42 required;
68 43 ]
69 Removed: @ (if List.mem_assoc field errors then
70 Removed: [
71 Removed: Dream_html.string_attr "aria-invalid" "true";
72 Removed: Dream_html.string_attr "aria-describedby" "%s"
73 Removed: (error_id input_id);
74 Removed: ]
75 Removed: else [])
76 44 @
77 45 match value with
78 46 | None -> []
@@ -103,24 +71,16 @@
103 71 let form_for_stimulus request ~action_path ~slot
104 72 ~(movements : View_model.Workout.movement list) ~selected_extension
105 73 ~selected_extension_amount ?(enhanced = false) ?(submit = "Record")
106 Removed: ?(correction = false) ~(errors : (string * string) list) () =
74 Added: ?(correction = false) () =
107 75 let field_id field = Printf.sprintf "slot-%d-%s" slot field in
108 76 let selected = selected_extension in
109 77 let movement_of (m : View_model.Workout.movement) =
110 Removed: movement_group ~errors ~name:m.name ~load_id:(field_id m.load_field)
78 Added: movement_group ~name:m.name ~load_id:(field_id m.load_field)
111 79 ~load_field:m.load_field ~reps_id:(field_id m.reps_field)
112 80 ~reps_field:m.reps_field ?load_value:m.load_value ?reps_value:m.reps_value
113 81 ?previous:m.previous ~reps_label:m.reps_label ()
114 82 in
115 83 let movement_groups = List.map movement_of movements in
116 Removed: (* The error rows follow the fields present, so a single-exercise slot reports
117 Removed: load/reps and a pre-exhaust slot reports the iso/comp fields. *)
118 Removed: let field_names =
119 Removed: List.concat_map
120 Removed: (fun (m : View_model.Workout.movement) -> [ m.load_field; m.reps_field ])
121 Removed: movements
122 Removed: @ [ "extension"; "extension_amount" ]
123 Removed: in
124 84 tag "form"
125 85 ([ action_path; post_form ]
126 86 @ (if enhanced then [ Dream_html.attr "data-hito-workout-form" ]
@@ -136,22 +96,25 @@
136 96 grid. The per-input labels carry the accessible names, so the two
137 97 visible headings are decorative. The Ending block is separate,
138 98 below the grid. *)
139 Removed: tag "div"
140 Removed: [ class_ "logging-grid" ]
141 Removed: (tag "div"
142 Removed: [
143 Removed: class_ "logging-grid-head";
144 Removed: Dream_html.string_attr "aria-hidden" "true";
145 Removed: ]
146 Removed: [
147 Removed: tag "span" [ class_ "logging-grid-head-name" ] [];
148 Removed: tag "span"
149 Removed: [ class_ "logging-grid-head-load" ]
150 Removed: [ txt "Load (kg)" ];
151 Removed: tag "span" [ class_ "logging-grid-head-reps" ] [ txt "Reps" ];
152 Removed: ]
153 Removed: :: movement_groups)
154 Removed: :: tag "div"
99 Added: [
100 Added: tag "div"
101 Added: [ class_ "logging-grid" ]
102 Added: (tag "div"
103 Added: [
104 Added: class_ "logging-grid-head";
105 Added: Dream_html.string_attr "aria-hidden" "true";
106 Added: ]
107 Added: [
108 Added: tag "span" [ class_ "logging-grid-head-name" ] [];
109 Added: tag "span"
110 Added: [ class_ "logging-grid-head-load" ]
111 Added: [ txt "Load (kg)" ];
112 Added: tag "span" [ class_ "logging-grid-head-reps" ] [ txt "Reps" ];
113 Added: ]
114 Added: :: movement_groups);
115 Added: ]
116 Added: @ [
117 Added: tag "div"
155 118 [ class_ "ending-block" ]
156 119 [
157 120 tag "div"
@@ -163,9 +126,8 @@
163 126 class_ "sr-only";
164 127 ]
165 128 [ txt "Ending" ];
166 Removed: extension_select ~selected
167 Removed: ~invalid:(List.mem_assoc "extension" errors)
168 Removed: ~input_id:(field_id "extension") ();
129 Added: extension_select ~selected ~input_id:(field_id "extension")
130 Added: ();
169 131 ];
170 132 tag "div"
171 133 [ class_ "field field-extension-amount" ]
@@ -206,10 +168,8 @@
206 168 [ txt "seconds" ];
207 169 ];
208 170 ];
209 Removed: ]
210 Removed: :: List.concat_map
211 Removed: (fun field -> error_for ~input_id:(field_id field) field errors)
212 Removed: field_names
171 Added: ];
172 Added: ]
213 173 @
214 174 if correction then
215 175 [
@@ -237,8 +197,8 @@
237 197 ]);
238 198 ]
239 199
240 Removed: let workout request ~viewer ?(errors = []) ?editing ?workout_started ~record_id
241 Removed: ~active_slot (vm : View_model.Workout.t) =
200 Added: let workout request ~viewer ?workout_started ~record_id ~active_slot
201 Added: (vm : View_model.Workout.t) =
242 202 let enhanced = Option.is_none record_id in
243 203 (* A live workout view is itself the workout in progress, so its own start
244 204 drives the nav timer. A saved-record view is history: the timer, if any,
@@ -263,10 +223,9 @@
263 223 summary carries the slot's level-two heading: its number and exercise label,
264 224 struck through once recorded. A recorded slot shows a pre-filled correction
265 225 form (which replaces the slot rather than adding volume); an outstanding
266 Removed: slot shows the record form. Errors render only under the slot being edited. *)
226 Added: slot shows the record form. *)
267 227 let slot_section (slot : View_model.Workout.slot) =
268 228 let index = slot.index in
269 Removed: let errors = if editing = Some index then errors else [] in
270 229 let done_ = Option.is_some slot.recorded_summary in
271 230 let body =
272 231 match slot.recorded_summary with
@@ -276,7 +235,7 @@
276 235 ~slot:index ~movements:slot.movements
277 236 ~selected_extension:slot.selected_extension
278 237 ~selected_extension_amount:slot.selected_extension_amount
279 Removed: ~enhanced ~submit:"Save correction" ~correction:true ~errors ();
238 Added: ~enhanced ~submit:"Save correction" ~correction:true ();
280 239 ]
281 240 | None ->
282 241 [
@@ -284,7 +243,7 @@
284 243 ~slot:index ~movements:slot.movements
285 244 ~selected_extension:slot.selected_extension
286 245 ~selected_extension_amount:slot.selected_extension_amount
287 Removed: ~enhanced ~errors ();
246 Added: ~enhanced ();
288 247 ]
289 248 in
290 249 tag "details"