feat(submissions): warn about multiple submissions for same user
This commit is contained in:
parent
9d1f1c6910
commit
c19a00dcef
@ -403,6 +403,9 @@ input[type="button"].btn-info:not(.btn-link):hover,
|
|||||||
font-weight: 600
|
font-weight: 600
|
||||||
color: var(--color-fontsec)
|
color: var(--color-fontsec)
|
||||||
|
|
||||||
|
.table__td--tooltip
|
||||||
|
width: 2em
|
||||||
|
|
||||||
.table__td
|
.table__td
|
||||||
font-size: 16px
|
font-size: 16px
|
||||||
color: var(--color-font)
|
color: var(--color-font)
|
||||||
|
|||||||
@ -404,6 +404,8 @@ SubmissionFilesCorrected: Abgegebene & Korrigierte Dateien
|
|||||||
RatingUpdatedFiles: Bei der Korrektur wurden Dateien angepasst oder hinzugefügt
|
RatingUpdatedFiles: Bei der Korrektur wurden Dateien angepasst oder hinzugefügt
|
||||||
SubmissionFilesUnchanged: Abgabedateien beibehalten
|
SubmissionFilesUnchanged: Abgabedateien beibehalten
|
||||||
SubmissionFilesUnchangedTip: Sollen die bestehenden Abgabedateien beim Ersetzen der Abgabe unverändert übernommen werden?
|
SubmissionFilesUnchangedTip: Sollen die bestehenden Abgabedateien beim Ersetzen der Abgabe unverändert übernommen werden?
|
||||||
|
SubmissionUserDuplicateWarning: Dieser Teilnehmende ist bereits an einer anderen Abgabe beteiligt
|
||||||
|
SubmissionSomeUsersDuplicateWarning: Manche Abgebende sind auch an einer anderen Abgabe beteiligt
|
||||||
|
|
||||||
SubmissionsDeleteQuestion n@Int: Wollen Sie #{pluralDE n "die unten aufgeführte Abgabe" "die unten aufgeführten Abgaben"} wirklich löschen?
|
SubmissionsDeleteQuestion n@Int: Wollen Sie #{pluralDE n "die unten aufgeführte Abgabe" "die unten aufgeführten Abgaben"} wirklich löschen?
|
||||||
SubmissionsDeleted n@Int: #{pluralDE n "Abgabe gelöscht" "Abgaben gelöscht"}
|
SubmissionsDeleted n@Int: #{pluralDE n "Abgabe gelöscht" "Abgaben gelöscht"}
|
||||||
|
|||||||
@ -402,6 +402,8 @@ SubmissionFilesCorrected: Submitted & Corrected files
|
|||||||
RatingUpdatedFiles: During correction files were added or changed
|
RatingUpdatedFiles: During correction files were added or changed
|
||||||
SubmissionFilesUnchanged: Keep submission files
|
SubmissionFilesUnchanged: Keep submission files
|
||||||
SubmissionFilesUnchangedTip: Should the existing submission files be retained unchanged while replacing the submission?
|
SubmissionFilesUnchangedTip: Should the existing submission files be retained unchanged while replacing the submission?
|
||||||
|
SubmissionUserDuplicateWarning: This participant is already a submittor for a different submission
|
||||||
|
SubmissionSomeUsersDuplicateWarning: Some submittors are also submittors for a different submission
|
||||||
|
|
||||||
SubmissionsDeleteQuestion n: Do you really want to delete the #{pluralEN n "submission" "submissions"} mentioned below?
|
SubmissionsDeleteQuestion n: Do you really want to delete the #{pluralEN n "submission" "submissions"} mentioned below?
|
||||||
SubmissionsDeleted n: #{pluralEN n "Submission" "Submissions"} deleted
|
SubmissionsDeleted n: #{pluralEN n "Submission" "Submissions"} deleted
|
||||||
|
|||||||
@ -32,8 +32,8 @@ import Handler.Submission.SubmissionUserInvite
|
|||||||
import qualified Data.Conduit.Combinators as C
|
import qualified Data.Conduit.Combinators as C
|
||||||
|
|
||||||
|
|
||||||
makeSubmissionForm :: CourseId -> Maybe SubmissionId -> UploadMode -> SheetGroup -> Maybe FileUploads -> Bool -> Set (Either UserEmail UserId) -> Form (Maybe FileUploads, Set (Either UserEmail UserId))
|
makeSubmissionForm :: CourseId -> SheetId -> Maybe SubmissionId -> UploadMode -> SheetGroup -> Maybe FileUploads -> Bool -> Set (Either UserEmail UserId) -> Form (Maybe FileUploads, Set (Either UserEmail UserId))
|
||||||
makeSubmissionForm cid msmid uploadMode grouping mPrev isLecturer prefillUsers = identifyForm FIDsubmission . renderAForm FormStandard $ (,)
|
makeSubmissionForm cid shid msmid uploadMode grouping mPrev isLecturer prefillUsers = identifyForm FIDsubmission . renderAForm FormStandard $ (,)
|
||||||
<$> uploadForm
|
<$> uploadForm
|
||||||
<*> wFormToAForm submittorsForm'
|
<*> wFormToAForm submittorsForm'
|
||||||
where
|
where
|
||||||
@ -51,7 +51,17 @@ makeSubmissionForm cid msmid uploadMode grouping mPrev isLecturer prefillUsers =
|
|||||||
| otherwise -> MsgEmailInvitationWarningPrevCoSubmittors
|
| otherwise -> MsgEmailInvitationWarningPrevCoSubmittors
|
||||||
$(widgetFile "widgets/massinput/submissionUsers/cellInvitation")
|
$(widgetFile "widgets/massinput/submissionUsers/cellInvitation")
|
||||||
miCell' csrf (Right uid) = do
|
miCell' csrf (Right uid) = do
|
||||||
User{..} <- liftHandler . runDB $ getJust uid
|
(User{..}, hasSubmitted) <- liftHandler . runDB $ do
|
||||||
|
user <- getJust uid
|
||||||
|
hasSubmitted <- E.selectExists . E.from $ \(submissionUser `E.InnerJoin` submission) -> do
|
||||||
|
E.on $ submissionUser E.^. SubmissionUserSubmission E.==. submission E.^. SubmissionId
|
||||||
|
E.where_ $ submissionUser E.^. SubmissionUserUser E.==. E.val uid
|
||||||
|
E.&&. submission E.^. SubmissionSheet E.==. E.val shid
|
||||||
|
whenIsJust msmid $ \smid ->
|
||||||
|
E.where_ $ submission E.^. SubmissionId E.!=. E.val smid
|
||||||
|
return (user, hasSubmitted)
|
||||||
|
knownWarning <- runMaybeT $
|
||||||
|
guardOnM hasSubmitted $ messageIconI Error IconSubmissionUserDuplicate MsgSubmissionUserDuplicateWarning
|
||||||
$(widgetFile "widgets/massinput/submissionUsers/cellKnown")
|
$(widgetFile "widgets/massinput/submissionUsers/cellKnown")
|
||||||
|
|
||||||
miLayout :: ListLength
|
miLayout :: ListLength
|
||||||
@ -319,9 +329,9 @@ submissionHelper tid ssh csh shn mcid = do
|
|||||||
-- @submissionModeUser == Nothing@ below iff we are currently serving a user with elevated rights (lecturer, admin, ...)
|
-- @submissionModeUser == Nothing@ below iff we are currently serving a user with elevated rights (lecturer, admin, ...)
|
||||||
-- Therefore we do not restrict upload behaviour in any way in that case
|
-- Therefore we do not restrict upload behaviour in any way in that case
|
||||||
((res,formWidget'), formEnctype) <- do
|
((res,formWidget'), formEnctype) <- do
|
||||||
(Entity _ Sheet{..}, buddies, _, _, isLecturer, isOwner, _, _) <- runDB getSheetInfo
|
(Entity shid Sheet{..}, buddies, _, _, isLecturer, isOwner, _, _) <- runDB getSheetInfo
|
||||||
let mPrevUploads = msmid <&> \smid -> runDBSource $ selectSource [SubmissionFileSubmission ==. smid, SubmissionFileIsUpdate ==. False] [Asc SubmissionFileTitle] .| C.map (view $ _FileReference . _1)
|
let mPrevUploads = msmid <&> \smid -> runDBSource $ selectSource [SubmissionFileSubmission ==. smid, SubmissionFileIsUpdate ==. False] [Asc SubmissionFileTitle] .| C.map (view $ _FileReference . _1)
|
||||||
runFormPost . makeSubmissionForm sheetCourse msmid (fromMaybe (UploadAny True Nothing True) . submissionModeUser $ sheetSubmissionMode) sheetGrouping mPrevUploads isLecturer $ bool id (maybe id (Set.insert . Right) muid) isOwner buddies
|
runFormPost . makeSubmissionForm sheetCourse shid msmid (fromMaybe (UploadAny True Nothing True) . submissionModeUser $ sheetSubmissionMode) sheetGrouping mPrevUploads isLecturer $ bool id (maybe id (Set.insert . Right) muid) isOwner buddies
|
||||||
let formWidget = wrapForm' BtnHandIn formWidget' def
|
let formWidget = wrapForm' BtnHandIn formWidget' def
|
||||||
{ formAction = Just $ SomeRoute actionUrl
|
{ formAction = Just $ SomeRoute actionUrl
|
||||||
, formEncoding = formEnctype
|
, formEncoding = formEnctype
|
||||||
@ -360,6 +370,7 @@ submissionHelper tid ssh csh shn mcid = do
|
|||||||
(FormFailure failmsgs) -> return $ FormFailure failmsgs
|
(FormFailure failmsgs) -> return $ FormFailure failmsgs
|
||||||
(FormSuccess res'@(_, groupMembers))
|
(FormSuccess res'@(_, groupMembers))
|
||||||
| groupMembers == subUsersOld -> return $ FormSuccess res'
|
| groupMembers == subUsersOld -> return $ FormSuccess res'
|
||||||
|
| isLecturer -> return $ FormSuccess res'
|
||||||
| Arbitrary{..} <- sheetGrouping -> do -- Validate AdHoc Group Members
|
| Arbitrary{..} <- sheetGrouping -> do -- Validate AdHoc Group Members
|
||||||
let (gEMails, gIds) = partitionEithers $ Set.toList groupMembers
|
let (gEMails, gIds) = partitionEithers $ Set.toList groupMembers
|
||||||
prep :: [(E.Value UserEmail, (E.Value UserId, E.Value Bool, E.Value Bool))] -> Map UserEmail (Maybe (UserId, Bool, Bool))
|
prep :: [(E.Value UserEmail, (E.Value UserId, E.Value Bool, E.Value Bool))] -> Map UserEmail (Maybe (UserId, Bool, Bool))
|
||||||
@ -486,7 +497,7 @@ submissionHelper tid ssh csh shn mcid = do
|
|||||||
| otherwise -> redirect $ CSheetR tid ssh csh shn SShowR
|
| otherwise -> redirect $ CSheetR tid ssh csh shn SShowR
|
||||||
Nothing -> return ()
|
Nothing -> return ()
|
||||||
|
|
||||||
(Entity _ Sheet{..}, _, lastEdits, maySubmit, _, _, msubmission, corrector) <- runDB getSheetInfo
|
(Entity shid Sheet{..}, _, lastEdits, maySubmit, _, _, msubmission, corrector) <- runDB getSheetInfo
|
||||||
|
|
||||||
(showCorrection, correctionInvisible) <- fmap (fromMaybe (False, Nothing)) . for ((,) <$> mcid <*> (Entity <$> msmid <*> msubmission)) $ \(cid, subEnt) -> runDB $ do
|
(showCorrection, correctionInvisible) <- fmap (fromMaybe (False, Nothing)) . for ((,) <$> mcid <*> (Entity <$> msmid <*> msubmission)) $ \(cid, subEnt) -> runDB $ do
|
||||||
showCorrection <- hasReadAccessTo $ CSubmissionR tid ssh csh shn cid CorrectionR
|
showCorrection <- hasReadAccessTo $ CSubmissionR tid ssh csh shn cid CorrectionR
|
||||||
@ -565,6 +576,22 @@ submissionHelper tid ssh csh shn mcid = do
|
|||||||
|
|
||||||
sheetTypeDesc <- liftHandler . runDB $ sheetTypeDescription sheetCourse sheetType
|
sheetTypeDesc <- liftHandler . runDB $ sheetTypeDescription sheetCourse sheetType
|
||||||
|
|
||||||
|
multipleSubmissionWarnWidget <- runDB . runMaybeT $ do
|
||||||
|
subId <- hoistMaybe msmid
|
||||||
|
cID <- hoistMaybe mcid
|
||||||
|
guardM . lift $ orM
|
||||||
|
[ hasWriteAccessTo $ CSubmissionR tid ssh csh shn cID SubDelR
|
||||||
|
, hasWriteAccessTo $ CSubmissionR tid ssh csh shn cID SubShowR
|
||||||
|
]
|
||||||
|
guardM . lift . E.selectExists . E.from $ \(submissionUser `E.InnerJoin` (otherSubmissionUser `E.InnerJoin` submission)) -> do
|
||||||
|
E.on $ otherSubmissionUser E.^. SubmissionUserSubmission E.==. submission E.^. SubmissionId
|
||||||
|
E.on $ submissionUser E.^. SubmissionUserSubmission E.!=. otherSubmissionUser E.^. SubmissionUserSubmission
|
||||||
|
E.&&. submissionUser E.^. SubmissionUserUser E.==. otherSubmissionUser E.^. SubmissionUserUser
|
||||||
|
E.where_ $ submission E.^. SubmissionSheet E.==. E.val shid
|
||||||
|
E.&&. submission E.^. SubmissionId E.!=. E.val subId
|
||||||
|
E.&&. submissionUser E.^. SubmissionUserSubmission E.==. E.val subId
|
||||||
|
return $ notification NotificationBroad =<< messageIconI Warning IconSubmissionUserDuplicate MsgSubmissionSomeUsersDuplicateWarning
|
||||||
|
|
||||||
defaultLayout $ do
|
defaultLayout $ do
|
||||||
setTitleI $ MsgSubmissionEditHead tid ssh csh shn
|
setTitleI $ MsgSubmissionEditHead tid ssh csh shn
|
||||||
(urlArchive, urlOriginal) <- fmap ((,) <$> preview (_Just . _1) <*> preview (_Just . _2)) . for mcid $ \cID
|
(urlArchive, urlOriginal) <- fmap ((,) <$> preview (_Just . _1) <*> preview (_Just . _2)) . for mcid $ \cID
|
||||||
|
|||||||
@ -92,6 +92,7 @@ data Icon
|
|||||||
| IconPersonalIdentification
|
| IconPersonalIdentification
|
||||||
| IconMenuWorkflows
|
| IconMenuWorkflows
|
||||||
| IconVideo
|
| IconVideo
|
||||||
|
| IconSubmissionUserDuplicate
|
||||||
deriving (Eq, Ord, Enum, Bounded, Show, Read, Generic, Typeable)
|
deriving (Eq, Ord, Enum, Bounded, Show, Read, Generic, Typeable)
|
||||||
|
|
||||||
iconText :: Icon -> Text
|
iconText :: Icon -> Text
|
||||||
@ -164,6 +165,7 @@ iconText = \case
|
|||||||
IconPersonalIdentification -> "id-card"
|
IconPersonalIdentification -> "id-card"
|
||||||
IconMenuWorkflows -> "project-diagram"
|
IconMenuWorkflows -> "project-diagram"
|
||||||
IconVideo -> "video"
|
IconVideo -> "video"
|
||||||
|
IconSubmissionUserDuplicate -> "copy"
|
||||||
|
|
||||||
instance Universe Icon
|
instance Universe Icon
|
||||||
instance Finite Icon
|
instance Finite Icon
|
||||||
|
|||||||
@ -8,6 +8,8 @@ $if is _Just mcid
|
|||||||
^{warning}
|
^{warning}
|
||||||
|
|
||||||
^{wdgt}
|
^{wdgt}
|
||||||
|
|
||||||
|
^{maybeVoid multipleSubmissionWarnWidget}
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
$case sheetSubmissionMode
|
$case sheetSubmissionMode
|
||||||
|
|||||||
@ -2,5 +2,5 @@ $newline never
|
|||||||
<td>
|
<td>
|
||||||
<span .email>
|
<span .email>
|
||||||
#{email}
|
#{email}
|
||||||
<td>
|
<td .table__td--tooltip>
|
||||||
^{messageTooltip invWarnMsg}
|
^{messageTooltip invWarnMsg}
|
||||||
|
|||||||
@ -2,5 +2,5 @@
|
|||||||
<td>
|
<td>
|
||||||
<span .email>
|
<span .email>
|
||||||
#{email}
|
#{email}
|
||||||
<td>
|
<td .table__td--tooltip>
|
||||||
^{messageTooltip invWarnMsg}
|
^{messageTooltip invWarnMsg}
|
||||||
|
|||||||
@ -3,5 +3,5 @@
|
|||||||
#{csrf}
|
#{csrf}
|
||||||
<span .email>
|
<span .email>
|
||||||
#{email}
|
#{email}
|
||||||
<td>
|
<td .table__td--tooltip>
|
||||||
^{messageTooltip invWarnMsg}
|
^{messageTooltip invWarnMsg}
|
||||||
|
|||||||
@ -1,4 +1,11 @@
|
|||||||
$newline never
|
$newline never
|
||||||
<td colspan=2>
|
$maybe wrn <- knownWarning
|
||||||
#{csrf}
|
<td>
|
||||||
^{nameEmailWidget userEmail userDisplayName userSurname}
|
#{csrf}
|
||||||
|
^{nameEmailWidget userEmail userDisplayName userSurname}
|
||||||
|
<td .table__td--tooltip>
|
||||||
|
^{messageTooltip wrn}
|
||||||
|
$nothing
|
||||||
|
<td colspan=2>
|
||||||
|
#{csrf}
|
||||||
|
^{nameEmailWidget userEmail userDisplayName userSurname}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user