diff --git a/src/app/learnocaml_teacher_tab.ml b/src/app/learnocaml_teacher_tab.ml index 0993e6470..641ee8cee 100644 --- a/src/app/learnocaml_teacher_tab.ml +++ b/src/app/learnocaml_teacher_tab.ml @@ -299,13 +299,12 @@ let rec teacher_tab token _select _params () = H.td [stars_div meta.Exercise.Meta.stars]; H.td [ let cls, text = - match Token.Map.is_empty ES.(st.assignments.token_map), - ES.(st.assignments.default) with - | true, ES.Open -> "exo_open", [%i"Open"] - | true, ES.Closed -> "exo_closed", [%i"Closed"] - | _, (ES.Assigned _ | ES.Closed) -> - "exo_assigned", [%i"Assigned"] - | false, ES.Open -> "exo_assigned", [%i"Open/Assg"] + let open ES in + match is_open_or_assigned_globally st.assignments with + | GloballyOpen -> "exo_open", [%i"Open"] + | GloballyOpenOrAssigned -> "exo_assigned", [%i"Open/Assigned"] + | GloballyClosedOrAssigned -> "exo_assigned", [%i"Assigned"] + | GloballyClosed -> "exo_closed", [%i"Closed"] in H.span ~a:[H.a_class [cls]] [H.txt text] ]; @@ -856,17 +855,12 @@ let rec teacher_tab token _select _params () = let ids = htbl_keys selected_exercises in let fstat = if List.exists (fun id -> - let st = get_status id in - ES.(default_assignment st.assignments = Open)) + let st = get_status id in + let open_assg = ES.is_open_or_assigned_globally st.ES.assignments in + open_assg = ES.GloballyOpen || open_assg = ES.GloballyOpenOrAssigned) ids - then ES.(fun assg -> - match default_assignment assg with - | Open -> set_default_assignment assg Closed - | _ -> assg) - else ES.(fun assg -> - match default_assignment assg with - | Closed -> set_default_assignment assg Open - | _ -> assg) + then ES.set_close_or_assigned_globally + else ES.set_open_or_assigned_globally in !exercise_status_change (htbl_keys selected_exercises) fstat; true) @@ -1330,7 +1324,11 @@ let rec teacher_tab token _select _params () = in let open_exercises = SMap.fold (fun ex st acc -> - if ES.(st.assignments.default = Open) then ex::acc else acc) + let open ES in + let global_st = is_open_or_assigned_globally st.assignments in + if global_st = GloballyOpen + || global_st = GloballyOpenOrAssigned + then ex :: acc else acc) !status_map [] |> List.rev in diff --git a/src/state/learnocaml_data.ml b/src/state/learnocaml_data.ml index e92a37dbf..54ba73da3 100644 --- a/src/state/learnocaml_data.ml +++ b/src/state/learnocaml_data.ml @@ -513,6 +513,54 @@ module Exercise = struct | Some a -> a | None -> a.default + type global_status = + | GloballyOpen (** "Open" *) + | GloballyClosed (** "Closed" *) + | GloballyOpenOrAssigned (** "Open/Assigned" *) + | GloballyClosedOrAssigned (** "Assigned" *) + + let is_open_or_assigned_globally a = + match a.default with + | Open -> + if Token.Map.exists (fun _tok -> function Assigned _ -> true | _ -> false) a.token_map + then GloballyOpenOrAssigned + else GloballyOpen + | Closed -> + if Token.Map.exists (fun _tok -> function Assigned _ -> true | _ -> false) a.token_map + then GloballyClosedOrAssigned + else GloballyClosed + | Assigned _ -> + if Token.Map.exists (fun _tok -> (=) Open) a.token_map + then GloballyOpenOrAssigned + else GloballyClosedOrAssigned + + let make_assignments token_map default = + { token_map; default } + + let set_close_or_assigned_globally a = + match is_open_or_assigned_globally a with + | GloballyOpen -> make_assignments Token.Map.empty Closed + | GloballyOpenOrAssigned -> + make_assignments + (Token.Map.map (function Open -> Closed | st -> st) a.token_map) + (match a.default with Open -> Closed | a -> a) + (* otherwise, maybe: forget the map and re-add all tokens ? *) + | GloballyClosedOrAssigned -> a + | GloballyClosed -> a + + let set_open_or_assigned_globally a = + match is_open_or_assigned_globally a with + | GloballyClosed -> make_assignments Token.Map.empty Open + | GloballyClosedOrAssigned -> + make_assignments + (Token.Map.map (function Closed -> Open | st -> st) a.token_map) + (match a.default with Closed -> Open | a -> a) + (* otherwise, maybe: forget the map and re-add all tokens ? *) + | GloballyOpenOrAssigned -> a + | GloballyOpen -> a + + (* Note/Erik: we may also want to implement set_assigned_globally *) + let is_open_assignment token a = match get_status token a with | Assigned a -> @@ -640,9 +688,6 @@ module Exercise = struct skills_focus; assignments = { default; token_map } } - let make_assignments token_map default = - { token_map; default } - let enc = let status_enc = J.union [ diff --git a/src/state/learnocaml_data.mli b/src/state/learnocaml_data.mli index 5048697c5..3091e87d3 100644 --- a/src/state/learnocaml_data.mli +++ b/src/state/learnocaml_data.mli @@ -206,6 +206,39 @@ module Exercise: sig val get_status: Token.t -> assignments -> status + (** Global assignment status, w.r.t. all students as a whole + + Invariants: forall exo_status : t, + + 1.(REQUIRED): + (exo_status.assignments.default <> Open && Token.Map.for_all (fun _ st -> st <> Open)) + || (exo_status.assignments.default <> Closed && Token.Map.for_all (fun _ st -> st <> Closed)) + + 2.(IfNormalized): + is_open_assigned_globally exo_status.assignments \in \{GloballyOpen, GloballyClosed\} -> + exo_status.assignments.token_map = Token.Map.empty + *) + type global_status = + | GloballyOpen (** "Open" *) + | GloballyClosed (** "Closed" *) + | GloballyOpenOrAssigned (** "Open/Assigned" *) + | GloballyClosedOrAssigned (** "Assigned" *) + + val is_open_or_assigned_globally: assignments -> global_status + + (** Close assignments status globally (for all unassigned students), namely: + - GloballyOpen -> GloballyClosed + - GloballyOpenOrAssigned -> GloballyClosedOrAssigned + - other -> no-op *) + val set_close_or_assigned_globally: assignments -> assignments + + (** Open assignments status globally (for all unassigned students), namely: + - GloballyClosed -> GloballyOpen + - GloballyClosedOrAssigned -> GloballyOpenOrAssigned + - other -> no-op + *) + val set_open_or_assigned_globally: assignments -> assignments + val is_open_assignment: Token.t -> assignments -> [> `Open | `Closed | `Deadline of float] diff --git a/translations/fr.po b/translations/fr.po index e1b48342d..42a262895 100644 --- a/translations/fr.po +++ b/translations/fr.po @@ -633,7 +633,7 @@ msgid "Assigned" msgstr "Devoir" #: File "src/app/learnocaml_teacher_tab.ml", line 308, characters 57-68 -msgid "Open/Assg" +msgid "Open/Assigned" msgstr "Ouvert/Devoir" #: File "src/app/learnocaml_teacher_tab.ml", line 368, characters 49-61 391,