parent
4c492861f1
commit
72191315b6
@ -183,6 +183,9 @@
|
|||||||
- fixity: "infix 4 <<<.>="
|
- fixity: "infix 4 <<<.>="
|
||||||
|
|
||||||
- suggest: { lhs: maybeT (return ()), rhs: maybeT_ }
|
- suggest: { lhs: maybeT (return ()), rhs: maybeT_ }
|
||||||
|
- suggest: { lhs: fromMaybe (return ()), rhs: maybeVoid }
|
||||||
|
- suggest: { lhs: maybe (return ()) void, rhs: maybeVoid }
|
||||||
|
|
||||||
- warn: { lhs: length xs >= n, rhs: minLength n xs, note: IncreasesLaziness }
|
- warn: { lhs: length xs >= n, rhs: minLength n xs, note: IncreasesLaziness }
|
||||||
- warn: { lhs: n <= length xs, rhs: minLength n xs, note: IncreasesLaziness }
|
- warn: { lhs: n <= length xs, rhs: minLength n xs, note: IncreasesLaziness }
|
||||||
- warn: { lhs: length xs > n, rhs: minLength (n + 1) xs, note: IncreasesLaziness }
|
- warn: { lhs: length xs > n, rhs: minLength (n + 1) xs, note: IncreasesLaziness }
|
||||||
|
|||||||
@ -402,6 +402,8 @@ SubmissionUserAlreadyAdded: Dieser Nutzer ist bereits als Mitabgebende(r) einget
|
|||||||
NoOpenSubmissions: Keine unkorrigierten Abgaben vorhanden
|
NoOpenSubmissions: Keine unkorrigierten Abgaben vorhanden
|
||||||
SubmissionFilesCorrected: Abgegebene & Korrigierte Dateien
|
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
|
||||||
|
SubmissionFilesUnchangedTip: Sollen die bestehenden Abgabedateien beim Ersetzen der Abgabe unverändert übernommen werden?
|
||||||
|
|
||||||
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"}
|
||||||
|
|||||||
@ -400,6 +400,8 @@ SubmissionUserAlreadyAdded: This user is already configured as a submittor
|
|||||||
NoOpenSubmissions: No open submissions exist
|
NoOpenSubmissions: No open submissions exist
|
||||||
SubmissionFilesCorrected: Submitted & Corrected files
|
SubmissionFilesCorrected: Submitted & Corrected files
|
||||||
RatingUpdatedFiles: During correction files were added or changed
|
RatingUpdatedFiles: During correction files were added or changed
|
||||||
|
SubmissionFilesUnchanged: Keep submission files
|
||||||
|
SubmissionFilesUnchangedTip: Should the existing submission files be retained unchanged while replacing the 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
|
||||||
|
|||||||
@ -174,11 +174,12 @@ applicationForm maId@(is _Just -> isAlloc) cid muid ApplicationFormMode{..} mcsr
|
|||||||
|
|
||||||
(filesRes, filesView) <-
|
(filesRes, filesView) <-
|
||||||
let mkFs = bool MsgCourseApplicationFile MsgCourseApplicationArchive
|
let mkFs = bool MsgCourseApplicationFile MsgCourseApplicationArchive
|
||||||
|
prevAppFiles (Entity aId _) = runDBSource $ selectSource [CourseApplicationFileApplication ==. aId] [Asc CourseApplicationFileTitle] .| C.map (view $ _FileReference . _1)
|
||||||
in if
|
in if
|
||||||
| not afmApplicantEdit || is _NoUpload courseApplicationsFiles
|
| not afmApplicantEdit || is _NoUpload courseApplicationsFiles
|
||||||
-> return (FormSuccess Nothing, Nothing)
|
-> return (FormSuccess Nothing, Nothing)
|
||||||
| otherwise
|
| otherwise
|
||||||
-> fmap (over _2 $ Just . ($ [])) . aFormToForm $ fileUploadForm False (fslI . mkFs) courseApplicationsFiles
|
-> fmap (over _2 $ Just . ($ [])) . aFormToForm $ fileUploadForm False (fslI . mkFs) courseApplicationsFiles (prevAppFiles <$> mApp)
|
||||||
|
|
||||||
(vetoRes, vetoView) <- if
|
(vetoRes, vetoView) <- if
|
||||||
| afmLecturer
|
| afmLecturer
|
||||||
|
|||||||
@ -303,7 +303,7 @@ makeCourseForm miButtonAction template = identifyForm FIDcourse . validateFormDB
|
|||||||
<*> allocationForm
|
<*> allocationForm
|
||||||
<*> apopt checkBoxField (fslI MsgCourseApplicationRequired & setTooltip MsgCourseApplicationRequiredTip) (cfAppRequired <$> template)
|
<*> apopt checkBoxField (fslI MsgCourseApplicationRequired & setTooltip MsgCourseApplicationRequiredTip) (cfAppRequired <$> template)
|
||||||
<*> aopt htmlField (fslI MsgCourseApplicationInstructions & setTooltip MsgCourseApplicationInstructionsTip) (cfAppInstructions <$> template)
|
<*> aopt htmlField (fslI MsgCourseApplicationInstructions & setTooltip MsgCourseApplicationInstructionsTip) (cfAppInstructions <$> template)
|
||||||
<*> aopt (multiFileField' . fromMaybe (return ()) $ cfAppInstructionFiles =<< template) (fslI MsgCourseApplicationTemplate & setTooltip MsgCourseApplicationTemplateTip) (cfAppInstructionFiles <$> template)
|
<*> aopt (multiFileField' . maybeVoid $ cfAppInstructionFiles =<< template) (fslI MsgCourseApplicationTemplate & setTooltip MsgCourseApplicationTemplateTip) (cfAppInstructionFiles <$> template)
|
||||||
<*> apopt checkBoxField (fslI MsgCourseApplicationsText & setTooltip MsgCourseApplicationsTextTip) (cfAppText <$> template)
|
<*> apopt checkBoxField (fslI MsgCourseApplicationsText & setTooltip MsgCourseApplicationsTextTip) (cfAppText <$> template)
|
||||||
<*> uploadModeForm (fslI MsgCourseApplicationsFiles & setTooltip MsgCourseApplicationsFilesTip) (fmap cfAppFiles template <|> pure NoUpload)
|
<*> uploadModeForm (fslI MsgCourseApplicationsFiles & setTooltip MsgCourseApplicationsFilesTip) (fmap cfAppFiles template <|> pure NoUpload)
|
||||||
<*> apopt checkBoxField (fslI MsgCourseApplicationRatingsVisible & setTooltip MsgCourseApplicationRatingsVisibleTip) (cfAppRatingsVisible <$> template)
|
<*> apopt checkBoxField (fslI MsgCourseApplicationRatingsVisible & setTooltip MsgCourseApplicationRatingsVisibleTip) (cfAppRatingsVisible <$> template)
|
||||||
|
|||||||
@ -23,7 +23,7 @@ courseNewsForm :: Maybe CourseNewsForm -> Form CourseNewsForm
|
|||||||
courseNewsForm template = identifyForm FIDCourseNews . renderWForm FormStandard $ do
|
courseNewsForm template = identifyForm FIDCourseNews . renderWForm FormStandard $ do
|
||||||
now <- liftIO getCurrentTime
|
now <- liftIO getCurrentTime
|
||||||
|
|
||||||
let oldFileIds = fromMaybe (return ()) $ template >>= cnfFiles
|
let oldFileIds = maybeVoid $ template >>= cnfFiles
|
||||||
cTime = ceilingQuarterHour now
|
cTime = ceilingQuarterHour now
|
||||||
visibleFromTip
|
visibleFromTip
|
||||||
| Just vFrom <- template >>= cnfVisibleFrom
|
| Just vFrom <- template >>= cnfVisibleFrom
|
||||||
|
|||||||
@ -132,11 +132,12 @@ courseRegisterForm (Entity cid Course{..}) = liftHandler $ do
|
|||||||
|
|
||||||
appFilesRes <- let mkFs | courseApplicationsRequired = bool MsgCourseApplicationFile MsgCourseApplicationArchive
|
appFilesRes <- let mkFs | courseApplicationsRequired = bool MsgCourseApplicationFile MsgCourseApplicationArchive
|
||||||
| otherwise = bool MsgCourseRegistrationFile MsgCourseRegistrationArchive
|
| otherwise = bool MsgCourseRegistrationFile MsgCourseRegistrationArchive
|
||||||
|
prevAppFiles (Entity aId _) = runDBSource $ selectSource [CourseApplicationFileApplication ==. aId] [Asc CourseApplicationFileTitle] .| C.map (view $ _FileReference . _1)
|
||||||
in if
|
in if
|
||||||
| isRegistered
|
| isRegistered
|
||||||
-> return $ FormSuccess Nothing
|
-> return $ FormSuccess Nothing
|
||||||
| otherwise
|
| otherwise
|
||||||
-> aFormToWForm $ fileUploadForm False (fslI . mkFs) courseApplicationsFiles
|
-> aFormToWForm $ fileUploadForm False (fslI . mkFs) courseApplicationsFiles (prevAppFiles <$> application)
|
||||||
|
|
||||||
mayViewCourseAfterDeregistration <- liftHandler . runDB $ E.selectExists . E.from $ \course -> E.where_ $
|
mayViewCourseAfterDeregistration <- liftHandler . runDB $ E.selectExists . E.from $ \course -> E.where_ $
|
||||||
course E.^. CourseId E.==. E.val cid
|
course E.^. CourseId E.==. E.val cid
|
||||||
|
|||||||
@ -87,7 +87,7 @@ postCUserR tid ssh csh uCId = do
|
|||||||
siteLayout headingLong $ do
|
siteLayout headingLong $ do
|
||||||
setTitleI headingShort
|
setTitleI headingShort
|
||||||
|
|
||||||
forM_ sections . fromMaybe $ return ()
|
mapM_ maybeVoid sections
|
||||||
|
|
||||||
courseUserProfileSection :: Entity Course -> Entity User -> MaybeT Handler Widget
|
courseUserProfileSection :: Entity Course -> Entity User -> MaybeT Handler Widget
|
||||||
courseUserProfileSection course@(Entity cid Course{..}) (Entity uid User{ userShowSex = _, ..}) = do
|
courseUserProfileSection course@(Entity cid Course{..}) (Entity uid User{ userShowSex = _, ..}) = do
|
||||||
|
|||||||
@ -63,7 +63,7 @@ makeMaterialForm cid template = identifyForm FIDmaterial $ \html -> do
|
|||||||
(mfDescription <$> template)
|
(mfDescription <$> template)
|
||||||
<*> aopt utcTimeField (fslI MsgMaterialVisibleFrom & setTooltip visibleToolTip)
|
<*> aopt utcTimeField (fslI MsgMaterialVisibleFrom & setTooltip visibleToolTip)
|
||||||
((mfVisibleFrom <$> template) <|> pure (Just ctime))
|
((mfVisibleFrom <$> template) <|> pure (Just ctime))
|
||||||
<*> aopt (multiFileField' . fromMaybe (return ()) $ mfFiles =<< template)
|
<*> aopt (multiFileField' . maybeVoid $ mfFiles =<< template)
|
||||||
(fslI MsgMaterialFiles) (mfFiles <$> template)
|
(fslI MsgMaterialFiles) (mfFiles <$> template)
|
||||||
|
|
||||||
fetchMaterial :: TermId -> SchoolId -> CourseShorthand -> MaterialName -> DB (Entity Material)
|
fetchMaterial :: TermId -> SchoolId -> CourseShorthand -> MaterialName -> DB (Entity Material)
|
||||||
@ -326,7 +326,7 @@ handleMaterialEdit tid ssh csh cid template dbMaterial = do
|
|||||||
case mbmid of
|
case mbmid of
|
||||||
Nothing -> False <$ addMessageI Error (MsgMaterialNameDup tid ssh csh mfName)
|
Nothing -> False <$ addMessageI Error (MsgMaterialNameDup tid ssh csh mfName)
|
||||||
(Just mid) -> do -- save files in DB
|
(Just mid) -> do -- save files in DB
|
||||||
insertMaterialFile' mid $ fromMaybe (return ()) mfFiles
|
insertMaterialFile' mid $ maybeVoid mfFiles
|
||||||
addMessageI Success $ MsgMaterialSaveOk tid ssh csh mfName
|
addMessageI Success $ MsgMaterialSaveOk tid ssh csh mfName
|
||||||
-- more info/warnings could go here
|
-- more info/warnings could go here
|
||||||
return True
|
return True
|
||||||
|
|||||||
@ -92,10 +92,10 @@ handleSheetEdit tid ssh csh msId template dbAction = do
|
|||||||
case mbsid of
|
case mbsid of
|
||||||
Nothing -> False <$ addMessageI Error (MsgSheetNameDup tid ssh csh sfName)
|
Nothing -> False <$ addMessageI Error (MsgSheetNameDup tid ssh csh sfName)
|
||||||
(Just sid) -> do -- save files in DB:
|
(Just sid) -> do -- save files in DB:
|
||||||
insertSheetFile' sid SheetExercise $ fromMaybe (return ()) sfSheetF
|
insertSheetFile' sid SheetExercise $ maybeVoid sfSheetF
|
||||||
insertSheetFile' sid SheetHint $ fromMaybe (return ()) sfHintF
|
insertSheetFile' sid SheetHint $ maybeVoid sfHintF
|
||||||
insertSheetFile' sid SheetSolution $ fromMaybe (return ()) sfSolutionF
|
insertSheetFile' sid SheetSolution $ maybeVoid sfSolutionF
|
||||||
insertSheetFile' sid SheetMarking $ fromMaybe (return ()) sfMarkingF
|
insertSheetFile' sid SheetMarking $ maybeVoid sfMarkingF
|
||||||
runConduit $
|
runConduit $
|
||||||
maybe (return ()) (transPipe liftHandler) (spffFiles =<< sfPersonalF)
|
maybe (return ()) (transPipe liftHandler) (spffFiles =<< sfPersonalF)
|
||||||
.| sinkPersonalisedSheetFiles cid sid (maybe False spffFilesKeepExisting sfPersonalF)
|
.| sinkPersonalisedSheetFiles cid sid (maybe False spffFilesKeepExisting sfPersonalF)
|
||||||
|
|||||||
@ -149,7 +149,7 @@ postCorrectionR tid ssh csh shn cid = do
|
|||||||
setTitleI heading
|
setTitleI heading
|
||||||
urlArchive <- toTextUrl . CSubmissionR tid ssh csh shn cid $ SubArchiveR SubmissionCorrected
|
urlArchive <- toTextUrl . CSubmissionR tid ssh csh shn cid $ SubArchiveR SubmissionCorrected
|
||||||
let userCorrection = $(widgetFile "correction-user")
|
let userCorrection = $(widgetFile "correction-user")
|
||||||
fromMaybe (return ()) invisibleWidget
|
maybeVoid invisibleWidget
|
||||||
$(widgetFile "correction")
|
$(widgetFile "correction")
|
||||||
_ -> notFound
|
_ -> notFound
|
||||||
getCorrectionUserR tid ssh csh shn cid = do
|
getCorrectionUserR tid ssh csh shn cid = do
|
||||||
|
|||||||
@ -29,12 +29,21 @@ import Data.Aeson.Lens
|
|||||||
|
|
||||||
import Handler.Submission.SubmissionUserInvite
|
import Handler.Submission.SubmissionUserInvite
|
||||||
|
|
||||||
|
import qualified Data.Conduit.Combinators as C
|
||||||
|
|
||||||
makeSubmissionForm :: CourseId -> Maybe SubmissionId -> UploadMode -> SheetGroup -> Bool -> Set (Either UserEmail UserId) -> Form (Maybe FileUploads, Set (Either UserEmail UserId))
|
|
||||||
makeSubmissionForm cid msmid uploadMode grouping isLecturer prefillUsers = identifyForm FIDsubmission . renderAForm FormStandard $ (,)
|
makeSubmissionForm :: CourseId -> Maybe SubmissionId -> UploadMode -> SheetGroup -> Maybe FileUploads -> Bool -> Set (Either UserEmail UserId) -> Form (Maybe FileUploads, Set (Either UserEmail UserId))
|
||||||
<$> fileUploadForm (not isLecturer && is _Nothing msmid) (fslI . bool MsgSubmissionFile MsgSubmissionArchive) uploadMode
|
makeSubmissionForm cid msmid uploadMode grouping mPrev isLecturer prefillUsers = identifyForm FIDsubmission . renderAForm FormStandard $ (,)
|
||||||
|
<$> uploadForm
|
||||||
<*> wFormToAForm submittorsForm'
|
<*> wFormToAForm submittorsForm'
|
||||||
where
|
where
|
||||||
|
uploadForm
|
||||||
|
| is _NoUpload uploadMode = pure Nothing
|
||||||
|
| is _Nothing msmid = uploadForm'
|
||||||
|
| otherwise = join <$> optionalActionNegatedA uploadForm' (fslI MsgSubmissionFilesUnchanged & setTooltip MsgSubmissionFilesUnchangedTip) (Just False)
|
||||||
|
|
||||||
|
uploadForm' = fileUploadForm (not isLecturer) (fslI . bool MsgSubmissionFile MsgSubmissionArchive) uploadMode mPrev
|
||||||
|
|
||||||
miCell' :: Markup -> Either UserEmail UserId -> Widget
|
miCell' :: Markup -> Either UserEmail UserId -> Widget
|
||||||
miCell' csrf (Left email) = do
|
miCell' csrf (Left email) = do
|
||||||
invWarnMsg <- messageIconI Info IconEmail $ if
|
invWarnMsg <- messageIconI Info IconEmail $ if
|
||||||
@ -311,7 +320,8 @@ submissionHelper tid ssh csh shn mcid = do
|
|||||||
-- 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 _ Sheet{..}, buddies, _, _, isLecturer, isOwner, _, _) <- runDB getSheetInfo
|
||||||
runFormPost . makeSubmissionForm sheetCourse msmid (fromMaybe (UploadAny True Nothing True) . submissionModeUser $ sheetSubmissionMode) sheetGrouping isLecturer $ bool id (maybe id (Set.insert . Right) muid) isOwner buddies
|
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
|
||||||
let formWidget = wrapForm' BtnHandIn formWidget' def
|
let formWidget = wrapForm' BtnHandIn formWidget' def
|
||||||
{ formAction = Just $ SomeRoute actionUrl
|
{ formAction = Just $ SomeRoute actionUrl
|
||||||
, formEncoding = formEnctype
|
, formEncoding = formEnctype
|
||||||
|
|||||||
@ -181,6 +181,20 @@ linkButton defWdgt lbl cls url = do
|
|||||||
-- Interactive fieldset --
|
-- Interactive fieldset --
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
|
optionalAction'' :: Bool -- ^ negated?
|
||||||
|
-> (Field Handler Bool -> FieldSettings UniWorX -> Maybe Bool -> MForm Handler (FormResult Bool, FieldView UniWorX))
|
||||||
|
-> AForm Handler a
|
||||||
|
-> FieldSettings UniWorX
|
||||||
|
-> Maybe Bool
|
||||||
|
-> (Html -> MForm Handler (FormResult (Maybe a), [FieldView UniWorX]))
|
||||||
|
optionalAction'' negated minp justAct fs@FieldSettings{..} defActive csrf = do
|
||||||
|
(doRes, doView) <- minp (bool id (isoField _not) negated checkBoxField) fs defActive
|
||||||
|
(actionRes, actionViews') <- over _2 ($ []) <$> aFormToForm justAct
|
||||||
|
|
||||||
|
let actionViews = over (mapped . _fvInput) (\w -> $(widgetFile "widgets/multi-action/optional-action")) actionViews'
|
||||||
|
|
||||||
|
return (doRes >>= bool (pure Nothing) (Just <$> actionRes), over _fvInput (mappend $ toWidget csrf) doView : actionViews)
|
||||||
|
|
||||||
optionalAction :: AForm Handler a
|
optionalAction :: AForm Handler a
|
||||||
-> FieldSettings UniWorX
|
-> FieldSettings UniWorX
|
||||||
-> Maybe Bool
|
-> Maybe Bool
|
||||||
@ -192,19 +206,19 @@ optionalAction' :: (Field Handler Bool -> FieldSettings UniWorX -> Maybe Bool ->
|
|||||||
-> FieldSettings UniWorX
|
-> FieldSettings UniWorX
|
||||||
-> Maybe Bool
|
-> Maybe Bool
|
||||||
-> (Html -> MForm Handler (FormResult (Maybe a), [FieldView UniWorX]))
|
-> (Html -> MForm Handler (FormResult (Maybe a), [FieldView UniWorX]))
|
||||||
optionalAction' minp justAct fs@FieldSettings{..} defActive csrf = do
|
optionalAction' = optionalAction'' False
|
||||||
(doRes, doView) <- minp checkBoxField fs defActive
|
|
||||||
(actionRes, actionViews') <- over _2 ($ []) <$> aFormToForm justAct
|
|
||||||
|
|
||||||
let actionViews = over (mapped . _fvInput) (\w -> $(widgetFile "widgets/multi-action/optional-action")) actionViews'
|
|
||||||
|
|
||||||
return (doRes >>= bool (pure Nothing) (Just <$> actionRes), over _fvInput (mappend $ toWidget csrf) doView : actionViews)
|
|
||||||
|
|
||||||
optionalActionA :: AForm Handler a
|
optionalActionA :: AForm Handler a
|
||||||
-> FieldSettings UniWorX
|
-> FieldSettings UniWorX
|
||||||
-> Maybe Bool
|
-> Maybe Bool
|
||||||
-> AForm Handler (Maybe a)
|
-> AForm Handler (Maybe a)
|
||||||
optionalActionA = optionalActionA' mpopt
|
optionalActionA = optionalActionA' mpopt
|
||||||
|
|
||||||
|
optionalActionNegatedA :: AForm Handler a
|
||||||
|
-> FieldSettings UniWorX
|
||||||
|
-> Maybe Bool
|
||||||
|
-> AForm Handler (Maybe a)
|
||||||
|
optionalActionNegatedA = optionalActionA'' True mpopt
|
||||||
|
|
||||||
optionalActionA' :: (Field Handler Bool -> FieldSettings UniWorX -> Maybe Bool -> MForm Handler (FormResult Bool, FieldView UniWorX))
|
optionalActionA' :: (Field Handler Bool -> FieldSettings UniWorX -> Maybe Bool -> MForm Handler (FormResult Bool, FieldView UniWorX))
|
||||||
-> AForm Handler a
|
-> AForm Handler a
|
||||||
@ -213,6 +227,14 @@ optionalActionA' :: (Field Handler Bool -> FieldSettings UniWorX -> Maybe Bool -
|
|||||||
-> AForm Handler (Maybe a)
|
-> AForm Handler (Maybe a)
|
||||||
optionalActionA' minp justAct fs defActive = formToAForm $ optionalAction' minp justAct fs defActive mempty
|
optionalActionA' minp justAct fs defActive = formToAForm $ optionalAction' minp justAct fs defActive mempty
|
||||||
|
|
||||||
|
optionalActionA'' :: Bool
|
||||||
|
-> (Field Handler Bool -> FieldSettings UniWorX -> Maybe Bool -> MForm Handler (FormResult Bool, FieldView UniWorX))
|
||||||
|
-> AForm Handler a
|
||||||
|
-> FieldSettings UniWorX
|
||||||
|
-> Maybe Bool
|
||||||
|
-> AForm Handler (Maybe a)
|
||||||
|
optionalActionA'' negated minp justAct fs defActive = formToAForm $ optionalAction'' negated minp justAct fs defActive mempty
|
||||||
|
|
||||||
optionalActionW :: AForm Handler a
|
optionalActionW :: AForm Handler a
|
||||||
-> FieldSettings UniWorX
|
-> FieldSettings UniWorX
|
||||||
-> Maybe Bool
|
-> Maybe Bool
|
||||||
@ -921,13 +943,15 @@ genericFileField mkOpts = Field{..}
|
|||||||
|
|
||||||
fieldEnctype = Multipart
|
fieldEnctype = Multipart
|
||||||
fieldParse :: [Text] -> [FileInfo] -> m (Either (SomeMessage (HandlerSite m)) (Maybe FileUploads))
|
fieldParse :: [Text] -> [FileInfo] -> m (Either (SomeMessage (HandlerSite m)) (Maybe FileUploads))
|
||||||
fieldParse vals files = runExceptT $ do
|
fieldParse vals files' = runExceptT $ do
|
||||||
|
let files = filter (not . null . fileName) files'
|
||||||
|
|
||||||
opts@FileField{..} <- liftHandler mkOpts
|
opts@FileField{..} <- liftHandler mkOpts
|
||||||
|
|
||||||
mIdent <- fmap getFirst . flip foldMapM vals $ \v ->
|
mIdent <- fmap getFirst . flip foldMapM vals $ \v ->
|
||||||
fmap First . runMaybeT . exceptTMaybe $ encodedSecretBoxOpen v
|
fmap First . runMaybeT . exceptTMaybe $ encodedSecretBoxOpen v
|
||||||
|
|
||||||
let uploadedFilenames = fileName <$> bool (take 1) id fieldMultiple files
|
let uploadedFilenames = fileName <$> files
|
||||||
|
|
||||||
let
|
let
|
||||||
doUnpack
|
doUnpack
|
||||||
@ -974,7 +998,7 @@ genericFileField mkOpts = Field{..}
|
|||||||
.| C.mapMaybe (\fTitle -> fmap (fTitle, ) . assertM (views _3 $ not . fieldOptionForce) $ Map.lookup fTitle permittedFiles)
|
.| C.mapMaybe (\fTitle -> fmap (fTitle, ) . assertM (views _3 $ not . fieldOptionForce) $ Map.lookup fTitle permittedFiles)
|
||||||
.| C.filter (\(fTitle, _) ->
|
.| C.filter (\(fTitle, _) ->
|
||||||
fieldMultiple
|
fieldMultiple
|
||||||
|| ( bool (\n h -> h == pure n) elem fieldMultiple fTitle (mapMaybe (preview _FileTitle) vals)
|
|| ( fTitle `elem` mapMaybe (preview _FileTitle) vals
|
||||||
&& null files
|
&& null files
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -1092,47 +1116,67 @@ singleFileField prev = genericFileField $ do
|
|||||||
, fieldAllEmptyOk = True
|
, fieldAllEmptyOk = True
|
||||||
}
|
}
|
||||||
|
|
||||||
specificFileField :: UploadSpecificFile -> Field Handler FileUploads
|
specificFileField :: UploadSpecificFile -> Maybe FileUploads -> Field Handler FileUploads
|
||||||
specificFileField UploadSpecificFile{..} = convertField (.| fixupFileTitles) id . genericFileField $ return FileField
|
specificFileField UploadSpecificFile{..} mPrev = convertField (.| fixupFileTitles) id . genericFileField $ do
|
||||||
{ fieldIdent = Nothing
|
previous <- runConduit $ maybeVoid mPrev .| C.foldMap Set.singleton
|
||||||
, fieldUnpackZips = FileFieldUserOption True False
|
return FileField
|
||||||
, fieldMultiple = False
|
{ fieldIdent = Nothing
|
||||||
, fieldRestrictExtensions = fromNullable . maybe Set.empty (Set.singleton . view _2) . Map.lookupMin . Map.fromList . map (length &&& id) $ fileNameExtensions specificFileName
|
, fieldUnpackZips = FileFieldUserOption True False
|
||||||
, fieldAdditionalFiles = _FileReferenceFileReferenceTitleMap # Map.empty
|
, fieldMultiple = False
|
||||||
, fieldMaxFileSize = specificFileMaxSize
|
, fieldRestrictExtensions = fromNullable . maybe Set.empty (Set.singleton . view _2) . Map.lookupMin . Map.fromList . map (length &&& id) $ fileNameExtensions specificFileName
|
||||||
, fieldAllEmptyOk = specificFileEmptyOk
|
, fieldAdditionalFiles = _FileReferenceFileReferenceTitleMap # Map.fromList
|
||||||
}
|
[ (fileReferenceTitle, (fileReferenceContent, fileReferenceModified, FileFieldUserOption False True))
|
||||||
|
| FileReference{..} <- Set.toList previous
|
||||||
|
]
|
||||||
|
, fieldMaxFileSize = specificFileMaxSize
|
||||||
|
, fieldAllEmptyOk = specificFileEmptyOk
|
||||||
|
}
|
||||||
where
|
where
|
||||||
fixupFileTitles = C.map $ set _fileReferenceTitle (unpack specificFileName)
|
fixupFileTitles = C.map $ set _fileReferenceTitle (unpack specificFileName)
|
||||||
|
|
||||||
zipFileField :: Bool -- ^ Unpack zips?
|
zipFileField :: Bool -- ^ Unpack zips?
|
||||||
-> Maybe (NonNull (Set Extension)) -- ^ Restrictions on file extensions
|
-> Maybe (NonNull (Set Extension)) -- ^ Restrictions on file extensions
|
||||||
-> Bool -- ^ Empty files ok?
|
-> Bool -- ^ Empty files ok?
|
||||||
-> Field Handler FileUploads
|
-> Field Handler FileUploads
|
||||||
zipFileField doUnpack permittedExtensions emptyOk = genericFileField $ return FileField
|
zipFileField doUnpack permittedExtensions emptyOk = zipFileField' doUnpack permittedExtensions emptyOk Nothing
|
||||||
{ fieldIdent = Nothing
|
|
||||||
, fieldUnpackZips = FileFieldUserOption True doUnpack
|
zipFileField' :: Bool -- ^ Unpack zips?
|
||||||
, fieldMultiple = doUnpack
|
-> Maybe (NonNull (Set Extension)) -- ^ Restrictions on file extensions
|
||||||
, fieldRestrictExtensions = permittedExtensions
|
-> Bool -- ^ Empty files ok?
|
||||||
, fieldAdditionalFiles = _FileReferenceFileReferenceTitleMap # Map.empty
|
-> Maybe FileUploads
|
||||||
, fieldMaxFileSize = Nothing
|
-> Field Handler FileUploads
|
||||||
, fieldAllEmptyOk = emptyOk
|
zipFileField' doUnpack permittedExtensions emptyOk mPrev = genericFileField $ do
|
||||||
}
|
previous <- runConduit $ maybeVoid mPrev .| C.foldMap Set.singleton
|
||||||
|
return FileField
|
||||||
|
{ fieldIdent = Nothing
|
||||||
|
, fieldUnpackZips = FileFieldUserOption True doUnpack
|
||||||
|
, fieldMultiple = doUnpack
|
||||||
|
, fieldRestrictExtensions = permittedExtensions
|
||||||
|
, fieldAdditionalFiles = _FileReferenceFileReferenceTitleMap # Map.fromList
|
||||||
|
[ (fileReferenceTitle, (fileReferenceContent, fileReferenceModified, FileFieldUserOption False True))
|
||||||
|
| FileReference{..} <- Set.toList previous
|
||||||
|
]
|
||||||
|
, fieldMaxFileSize = Nothing
|
||||||
|
, fieldAllEmptyOk = emptyOk
|
||||||
|
}
|
||||||
|
|
||||||
fileUploadForm :: Bool -- ^ Required?
|
fileUploadForm :: Bool -- ^ Required?
|
||||||
-> (Bool -> FieldSettings UniWorX) -- ^ given @unpackZips@ generate `FieldSettings` in the case of `UploadAny`
|
-> (Bool -> FieldSettings UniWorX) -- ^ given @unpackZips@ generate `FieldSettings` in the case of `UploadAny`
|
||||||
-> UploadMode -> AForm Handler (Maybe FileUploads)
|
-> UploadMode
|
||||||
fileUploadForm isReq mkFs = \case
|
-> Maybe FileUploads
|
||||||
|
-> AForm Handler (Maybe FileUploads)
|
||||||
|
fileUploadForm isReq mkFs uMode mPrev = case uMode of
|
||||||
NoUpload
|
NoUpload
|
||||||
-> pure Nothing
|
-> pure Nothing
|
||||||
UploadAny{..}
|
UploadAny{..}
|
||||||
-> bool aopt (\f fs _ -> Just <$> areq f fs Nothing) isReq (zipFileField uploadUnpackZips uploadExtensionRestriction uploadEmptyOk) (mkFs uploadUnpackZips) Nothing
|
-> bool (\f fs d -> aopt f fs $ Just <$> d) (\f fs d -> Just <$> apreq f fs d) isReq (zipFileField' uploadUnpackZips uploadExtensionRestriction uploadEmptyOk mPrev) (mkFs uploadUnpackZips) mPrev
|
||||||
UploadSpecific{..}
|
UploadSpecific{..}
|
||||||
-> mergeFileSources <$> traverse specificFileForm (Set.toList $ toNullable uploadSpecificFiles)
|
-> mergeFileSources <$> traverse specificFileForm (Set.toList $ toNullable uploadSpecificFiles)
|
||||||
where
|
where
|
||||||
specificFileForm :: UploadSpecificFile -> AForm Handler (Maybe FileUploads)
|
specificFileForm :: UploadSpecificFile -> AForm Handler (Maybe FileUploads)
|
||||||
specificFileForm spec@UploadSpecificFile{..}
|
specificFileForm spec@UploadSpecificFile{..}
|
||||||
= bool (\f fs d -> aopt f fs $ fmap Just d) (\f fs d -> Just <$> areq f fs d) (specificFileRequired && isReq) (specificFileField spec) (fsl specificFileLabel) Nothing
|
= bool (\f fs d -> aopt f fs $ Just <$> d) (\f fs d -> Just <$> apreq f fs d) (specificFileRequired && isReq) (specificFileField spec mPrev') (fsl specificFileLabel) mPrev'
|
||||||
|
where mPrev' = flip (.|) (C.filter . has $ _fileReferenceTitle . only (unpack specificFileName)) <$> mPrev
|
||||||
|
|
||||||
mergeFileSources :: [Maybe FileUploads] -> Maybe FileUploads
|
mergeFileSources :: [Maybe FileUploads] -> Maybe FileUploads
|
||||||
mergeFileSources (catMaybes -> sources) = case sources of
|
mergeFileSources (catMaybes -> sources) = case sources of
|
||||||
|
|||||||
@ -700,6 +700,9 @@ hoistMaybe = maybe mzero return
|
|||||||
hoistMaybeM :: MonadPlus m => m (Maybe a) -> m a
|
hoistMaybeM :: MonadPlus m => m (Maybe a) -> m a
|
||||||
hoistMaybeM = (=<<) hoistMaybe
|
hoistMaybeM = (=<<) hoistMaybe
|
||||||
|
|
||||||
|
maybeVoid :: Monad m => Maybe (m a) -> m ()
|
||||||
|
maybeVoid = maybe (return ()) void
|
||||||
|
|
||||||
catchIfMaybeT :: (MonadCatch m, Exception e) => (e -> Bool) -> m a -> MaybeT m a
|
catchIfMaybeT :: (MonadCatch m, Exception e) => (e -> Bool) -> m a -> MaybeT m a
|
||||||
catchIfMaybeT p act = catchIf p (lift act) (const mzero)
|
catchIfMaybeT p act = catchIf p (lift act) (const mzero)
|
||||||
|
|
||||||
|
|||||||
@ -82,6 +82,8 @@ _SqlKey = _SqlKey' . _Unwrapped
|
|||||||
_Integral :: (Integral a, Integral b) => Iso' a b
|
_Integral :: (Integral a, Integral b) => Iso' a b
|
||||||
_Integral = iso fromIntegral fromIntegral
|
_Integral = iso fromIntegral fromIntegral
|
||||||
|
|
||||||
|
_not :: Iso' Bool Bool
|
||||||
|
_not = iso not not
|
||||||
|
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
-- Lens Definitions for our Types
|
-- Lens Definitions for our Types
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
<fieldset uw-interactive-fieldset data-conditional-input=#{fvId doView}>
|
<fieldset uw-interactive-fieldset data-conditional-input=#{fvId doView} :negated:data-conditional-negated>
|
||||||
<legend>
|
<legend>
|
||||||
_{fsLabel}
|
_{fsLabel}
|
||||||
^{w}
|
^{w}
|
||||||
|
|||||||
Reference in New Issue
Block a user