module Handler.Annotations where import Import import qualified Database.Esqueleto as E import qualified Yesod.Table as Table import Handler.Tables (timestampCell) getListAnnotationsR :: Handler Html getListAnnotationsR = do annotations <- runDB $ selectList [] [Asc AnnotationTaskId] defaultLayout $ do setTitle "List annotation tasks" $(widgetFile "list-annotations") getAnnotationTaskR :: AnnotationTaskId -> Handler Html getAnnotationTaskR annotationTaskId = do (Entity userId _) <- requireAuth annotationTask <- runDB $ get annotationTaskId -- Get all labels labels <- runDB $ selectList [AnnotationLabelAnnotationTask ==. annotationTaskId] [Asc AnnotationLabelOrder] -- Get list of user decisions for this annotation task taskDecisionIds' <- runDB $ E.select $ E.from $ \(annotationItem `E.InnerJoin` annotationDecision) -> do E.on (annotationItem E.^. AnnotationItemId E.==. annotationDecision E.^. AnnotationDecisionAnnotationItem) E.where_ (annotationItem E.^. AnnotationItemAnnotationTask E.==. E.val annotationTaskId E.&&. annotationDecision E.^. AnnotationDecisionUser E.==. E.val userId) return $ annotationDecision E.^. AnnotationDecisionAnnotationItem let decisionLength = length taskDecisionIds' -- Get number of items for this annotation task taskItemsLength <- runDB $ count [AnnotationItemAnnotationTask ==. annotationTaskId] -- Get first item to annotate which was not annotated let taskDecisionIds = map E.unValue taskDecisionIds' maybeItem <- runDB $ selectFirst [AnnotationItemAnnotationTask ==. annotationTaskId, AnnotationItemId /<-. taskDecisionIds] [Asc AnnotationItemOrder] let allDone = decisionLength == taskItemsLength && decisionLength > 0 defaultLayout $ do setTitle "Annotation task" $(widgetFile "annotation-task") postAnnotationTaskDecisionR :: AnnotationTaskId -> AnnotationItemId -> AnnotationLabelId -> Handler Html postAnnotationTaskDecisionR annotationTaskId itemId labelId = do (Entity userId _) <- requireAuth now <- liftIO getCurrentTime label <- runDB $ get404 labelId -- Check decision exists maybeSaveDecision <- runDB $ selectFirst [AnnotationDecisionAnnotationItem ==. itemId, AnnotationDecisionUser ==. userId] [] case maybeSaveDecision of -- Update if exists Nothing -> do _ <- runDB $ insert $ AnnotationDecision itemId userId (annotationLabelValue label) now return () -- Insert new Just (Entity saveDecisionId _) -> do _ <- runDB $ updateWhere [AnnotationDecisionId ==. saveDecisionId] [AnnotationDecisionValue =. annotationLabelValue label, AnnotationDecisionStamp =. now] return () -- Redirect to annotation page redirect $ AnnotationTaskR annotationTaskId getAnnotationTaskResultsR :: AnnotationTaskId -> Handler Html getAnnotationTaskResultsR annotationTaskId = do results <- runDB $ E.select $ E.from $ \(annotationDecision `E.InnerJoin` annotationItem) -> do E.on (annotationDecision E.^. AnnotationDecisionAnnotationItem E.==. annotationItem E.^. AnnotationItemId) E.where_ (annotationItem E.^. AnnotationItemAnnotationTask E.==. E.val annotationTaskId) E.orderBy [E.asc (annotationItem E.^. AnnotationItemOrder), E.asc (annotationDecision E.^. AnnotationDecisionUser)] return (annotationItem E.^. AnnotationItemContent, annotationItem E.^. AnnotationItemOrder, annotationDecision E.^. AnnotationDecisionUser, annotationDecision E.^. AnnotationDecisionValue) labels <- runDB $ selectList [AnnotationLabelAnnotationTask ==. annotationTaskId] [Asc AnnotationLabelOrder] defaultLayout $ do setTitle "Annotation task results" $(widgetFile "annotation-task-results") annotationListTable :: Table.Table App (Entity AnnotationTask) annotationListTable = mempty ++ Table.text "Name" (annotationTaskName . entityVal) ++ Table.linked "Annotation link" (const "Annotation link") (AnnotationTaskR . entityKey) ++ Table.linked "Results link" (const "Results link") (AnnotationTaskResultsR . entityKey) ++ timestampCell "Date added" (annotationTaskAdded . entityVal) annotationResultsTable :: Table.Table App (E.Value Text, E.Value Int, E.Value (Key User), E.Value Text) annotationResultsTable = mempty ++ Table.int "ID" (\(_, order, _, _) -> E.unValue order) ++ Table.int "UserID" (\(_, _, userId, _) -> fromIntegral $ E.fromSqlKey $ E.unValue userId) ++ Table.text "Answer value" (\(_, _, _, answer) -> E.unValue answer) ++ Table.text "Text" (\(content, _, _, _) -> E.unValue content) annotationLabelsTable :: Table.Table App (Entity AnnotationLabel) annotationLabelsTable = mempty ++ Table.text "Answer value" (annotationLabelValue . entityVal) ++ Table.text "Text" (annotationLabelName . entityVal)