From 222d566bdaa84382b24299d6e9179eb2ebb09564 Mon Sep 17 00:00:00 2001 From: Sarah Vaupel <> Date: Fri, 24 Jul 2020 18:52:54 +0200 Subject: [PATCH] feat(course-visibility): add visibleFrom,visibleTo add visibleFrom and visibleTo to model, add fields (CEditR), add info (CShowR) --- messages/uniworx/de-de-formal.msg | 9 ++++++++- messages/uniworx/en-eu.msg | 7 +++++++ models/courses.model | 2 ++ package-lock.json | 3 +-- src/Handler/Course/Edit.hs | 12 ++++++++++++ src/Handler/Course/Show.hs | 1 + templates/course.hamlet | 19 +++++++++++++++++++ 7 files changed, 50 insertions(+), 3 deletions(-) diff --git a/messages/uniworx/de-de-formal.msg b/messages/uniworx/de-de-formal.msg index e54dde4cd..6beb6b500 100644 --- a/messages/uniworx/de-de-formal.msg +++ b/messages/uniworx/de-de-formal.msg @@ -53,6 +53,9 @@ RegisterTo: Anmeldungen bis DeRegUntil: Abmeldungen bis RegisterRetry: Sie wurden noch nicht angemeldet. Drücken Sie dazu den Knopf "Anmelden" +CourseVisibleFrom: Sichtbar ab +CourseVisibleTo: Sichtbar bis + CourseRegistrationInterval: Anmeldung CourseDirectRegistrationInterval: Direkte Anmeldung CourseDeregisterUntil time@Text: Abmeldung nur bis #{time} @@ -112,6 +115,8 @@ CourseNoCapacity: In diesem Kurs sind keine Plätze mehr frei. TutorialNoCapacity: In dieser Übung sind keine Plätze mehr frei. ExamOccurrenceNoCapacity: Zu diesem Termin/Raum sind keine Plätze mehr frei. CourseNotEmpty: In diesem Kurs sind momentan Teilnehmer angemeldet. +CourseVisibility: Sichtbarkeit +CourseInvisible: Dieser Kurs ist momentan nicht sichtbar. TODO CourseRegistration: Kursanmeldung CourseRegisterOpen: Anmeldung möglich CourseRegisterOk: Erfolgreich zum Kurs angemeldet @@ -158,6 +163,8 @@ CourseSchoolShort: Institut CourseSchoolMultipleTip: Es stehen für Sie mehrere Institute zur Auswahl. Stellen Sie bitte sicher, dass Sie das für den Kurs korrekte Institut wählen. CourseSecretTip: Anmeldung zum Kurs erfordert Eingabe des Passworts, sofern gesetzt CourseSecretFormat: beliebige Zeichenkette +CourseVisibleFromTip: Ab diesem Zeitpunkt können andere Nutzer (außer Verwalter dieses Kurses) den Kurs sehen. Ohne Datum ist der Kurs nie für andere Nutzer sichtbar. +CourseVisibleToTip: Der Kurs ist ab "Sichtbar ab" bis zu diesem Zeitpunkt für andere Nutzer sichtbar. Ohne Datum bleibt ein sichtbarer Kurs unbegrenzt sichtbar. CourseRegisterFromTip: Ohne Datum ist keine eigenständige Anmeldung von Studierenden erlaubt. CourseRegisterToTip: Darf auch unbegrenzt offen bleiben CourseDeregisterUntilTip: Abmeldung ist ab "Anmeldungen von" bis zu diesem Zeitpunkt erlaubt. Die Abmeldung darf auch unbegrenzt erlaubt bleiben. @@ -2664,4 +2671,4 @@ SubmissionDoneNever: Nie SubmissionDoneByFile: Je nach Bewertungsdatei SubmissionDoneAlways: Immer CorrUploadSubmissionDoneMode: Bewertung abgeschlossen -CorrUploadSubmissionDoneModeTip: Sollen hochgeladene Korrekturen als abgeschlossen markiert werden? Bewertungen sind erst für Studierende sichtbar und zählen gegen Examboni, wenn sie abgeschlossen sind. \ No newline at end of file +CorrUploadSubmissionDoneModeTip: Sollen hochgeladene Korrekturen als abgeschlossen markiert werden? Bewertungen sind erst für Studierende sichtbar und zählen gegen Examboni, wenn sie abgeschlossen sind. diff --git a/messages/uniworx/en-eu.msg b/messages/uniworx/en-eu.msg index 30a50e075..0687468c0 100644 --- a/messages/uniworx/en-eu.msg +++ b/messages/uniworx/en-eu.msg @@ -53,6 +53,9 @@ RegisterTo: Enrolment ends DeRegUntil: Deregistration until RegisterRetry: You haven't been enrolled. Press "Enrol for course" to enrol +CourseVisibleFrom: Visible from +CourseVisibleTo: Visible to + CourseRegistrationInterval: Enrolment CourseDirectRegistrationInterval: Direct enrolment CourseDeregisterUntil time: Deregistration only until #{time} @@ -112,6 +115,8 @@ CourseNoCapacity: Course has reached maximum capacity TutorialNoCapacity: Tutorial has reached maximum capacity ExamOccurrenceNoCapacity: Occurrence/Room has reached maximum capacity CourseNotEmpty: There are currently no participants enrolled for this course. +CourseVisibility: Visibility +CourseInvisible: This course is currently invisible. TODO CourseRegistration: Enrolment CourseRegisterOpen: Enrolment is allowed CourseRegisterOk: Successfully enrolled for course @@ -158,6 +163,8 @@ CourseSchoolShort: Department CourseSchoolMultipleTip: You may select from among multiple departments. Please ensure that you select the appropriate department for your course. CourseSecretTip: Enrollment for this course will require the password, if set CourseSecretFormat: Arbitrary string +CourseVisibleFromTip: Other users will only be able to see the course from this date onward. When left empty nobody except administrators of this course will be able to see the course. +CourseVisibleToTip: Other users will be able to see the course from "Visible From" up to this date. When left empty visible courses will remain visible indefinitely. CourseRegisterFromTip: When left empty students will not be able to enrol themselves CourseRegisterToTip: May be left empty to allow enrolment indefinitely CourseDeregisterUntilTip: Participants may deregister from immediately after registration starts up to this time. May be left empty to allow deregistration indefinitely. diff --git a/models/courses.model b/models/courses.model index db9ba46e0..708064a28 100644 --- a/models/courses.model +++ b/models/courses.model @@ -12,6 +12,8 @@ Course -- Information about a single course; contained info is always visible school SchoolId capacity Int Maybe -- number of allowed enrolements, if restricted -- canRegisterNow = maybe False (<= currentTime) registerFrom && maybe True (>= currentTime) registerTo + visibleFrom UTCTime Maybe default=now() -- course may be visible from a given day onwards or always hidden + visibleTo UTCTime Maybe -- course may be hidden from a given date onwards registerFrom UTCTime Maybe -- enrolement allowed from a given day onwwards or prohibited registerTo UTCTime Maybe -- enrolement may be prohibited from a given date onwards deregisterUntil UTCTime Maybe -- unenrolement may be prohibited from a given date onwards diff --git a/package-lock.json b/package-lock.json index fdd0d86eb..e60ada17e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10943,8 +10943,7 @@ "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" }, "lodash.defaults": { "version": "4.2.0", diff --git a/src/Handler/Course/Edit.hs b/src/Handler/Course/Edit.hs index 03d867a6b..74f30ccb7 100644 --- a/src/Handler/Course/Edit.hs +++ b/src/Handler/Course/Edit.hs @@ -46,6 +46,8 @@ data CourseForm = CourseForm , cfAppRatingsVisible :: Bool , cfCapacity :: Maybe Int , cfSecret :: Maybe Text + , cfVisFrom :: Maybe UTCTime + , cfVisTo :: Maybe UTCTime , cfRegFrom :: Maybe UTCTime , cfRegTo :: Maybe UTCTime , cfDeRegUntil :: Maybe UTCTime @@ -77,6 +79,8 @@ courseToForm cEnt@(Entity cid Course{..}) lecs lecInvites alloc = CourseForm , cfAppText = courseApplicationsText , cfAppFiles = courseApplicationsFiles , cfAppRatingsVisible = courseApplicationsRatingsVisible + , cfVisFrom = courseVisibleFrom + , cfVisTo = courseVisibleTo , cfRegFrom = courseRegisterFrom , cfRegTo = courseRegisterTo , cfDeRegUntil = courseDeregisterUntil @@ -286,6 +290,10 @@ makeCourseForm miButtonAction template = identifyForm FIDcourse . validateFormDB & setTooltip MsgCourseCapacityTip) (cfCapacity <$> template) <*> aopt (textField & cfStrip) (fslpI MsgCourseSecret (mr MsgCourseSecretFormat) & setTooltip MsgCourseSecretTip) (cfSecret <$> template) + <*> aopt utcTimeField (fslpI MsgCourseVisibleFrom (mr MsgDate) + & setTooltip MsgCourseVisibleFromTip) (cfVisFrom <$> template) + <*> aopt utcTimeField (fslpI MsgCourseVisibleTo (mr MsgDate) + & setTooltip MsgCourseVisibleToTip) (cfVisTo <$> template) <*> aopt utcTimeField (fslpI MsgRegisterFrom (mr MsgDate) & setTooltip MsgCourseRegisterFromTip) (deepAlt (cfRegFrom <$> template) newRegFrom) <*> aopt utcTimeField (fslpI MsgRegisterTo (mr MsgDate) @@ -456,6 +464,8 @@ courseEditHandler miButtonAction mbCourseForm = do , courseApplicationsText = cfAppText , courseApplicationsFiles = cfAppFiles , courseApplicationsRatingsVisible = cfAppRatingsVisible + , courseVisibleFrom = cfVisFrom + , courseVisibleTo = cfVisTo , courseRegisterFrom = cfRegFrom , courseRegisterTo = cfRegTo , courseDeregisterUntil = cfDeRegUntil @@ -504,6 +514,8 @@ courseEditHandler miButtonAction mbCourseForm = do , courseApplicationsText = cfAppText , courseApplicationsFiles = cfAppFiles , courseApplicationsRatingsVisible = cfAppRatingsVisible + , courseVisibleFrom = cfVisFrom + , courseVisibleTo = cfVisTo , courseRegisterFrom = cfRegFrom , courseRegisterTo = cfRegTo , courseDeregisterUntil = cfDeRegUntil diff --git a/src/Handler/Course/Show.hs b/src/Handler/Course/Show.hs index d8cd57425..03be86723 100644 --- a/src/Handler/Course/Show.hs +++ b/src/Handler/Course/Show.hs @@ -219,6 +219,7 @@ getCShowR tid ssh csh = do hiddenEventNotes = all (\(_,CourseEvent{..}) -> is _Nothing courseEventNote) events mayCreateNews <- hasWriteAccessTo $ CourseR tid ssh csh CNewsNewR mayCreateEvents <- hasWriteAccessTo $ CourseR tid ssh csh CEventsNewR + mayEditCourse <- hasWriteAccessTo $ CourseR tid ssh csh CEditR siteLayout (toWgt $ courseName course) $ do setTitleI $ prependCourseTitle tid ssh csh (""::Text) diff --git a/templates/course.hamlet b/templates/course.hamlet index 71192130c..da5dedc5b 100644 --- a/templates/course.hamlet +++ b/templates/course.hamlet @@ -116,6 +116,7 @@ $# #{summary} #{iconLink} \ #{link} + $# $if NTop (Just 0) < NTop (courseCapacity course)
_{MsgCourseParticipantsHeading}
@@ -123,6 +124,20 @@ $# $if NTop (Just 0) < NTop (courseCapacity course) _{MsgCourseParticipantsCountOf participants capacity} $nothing _{MsgCourseParticipantsCount participants} + + $if mayEditCourse +
+ $if isJust (courseVisibleTo course) + _{MsgCourseVisibility} + $else + _{MsgCourseVisibleFrom} +
+ $maybe visFrom <- courseVisibleFrom course +

+ ^{formatTimeRangeW SelFormatDateTime visFrom (courseVisibleTo course)} + $nothing + _{MsgCourseInvisible} + $maybe (Allocation{allocationName, allocationRegisterByCourse}, url) <- mAllocation'

_{MsgCourseAllocation}
@@ -148,6 +163,7 @@ $# $if NTop (Just 0) < NTop (courseCapacity course) $maybe dereg <- mDereg

_{MsgCourseDeregisterUntil dereg} + $maybe aInst <- courseApplicationsInstructions course

$if courseApplicationsRequired course @@ -189,6 +205,7 @@ $# $if NTop (Just 0) < NTop (courseCapacity course) $nothing _{MsgNoSubmissionGroup} + $if registrationOpen || isJust registration
_{MsgCourseRegistration} @@ -210,6 +227,7 @@ $# $if NTop (Just 0) < NTop (courseCapacity course) $if isJust registration

_{MsgCourseRegistrationDeleteToEdit} +

_{MsgCourseMaterial}
@@ -217,6 +235,7 @@ $# $if NTop (Just 0) < NTop (courseCapacity course) _{MsgCourseMaterialFree} $else _{MsgCourseMaterialNotFree} + $if hasExams
_{MsgCourseExams}