Ticket update form

This commit is contained in:
fr33domlover 2016-05-02 09:15:10 +00:00
parent 88569a08ad
commit 9d3b7b686f
6 changed files with 120 additions and 15 deletions

View file

@ -72,5 +72,7 @@ Ticket
title Text title Text
desc Text -- Assume this is Pandoc Markdown desc Text -- Assume this is Pandoc Markdown
done Bool done Bool
closed UTCTime
closer PersonId
UniqueTicket project number UniqueTicket project number

View file

@ -15,6 +15,7 @@
module Vervis.Form.Ticket module Vervis.Form.Ticket
( newTicketForm ( newTicketForm
, editTicketForm
) )
where where
@ -22,7 +23,8 @@ import Prelude
import Control.Monad.IO.Class (liftIO) import Control.Monad.IO.Class (liftIO)
import Control.Monad.Trans.Class (lift) import Control.Monad.Trans.Class (lift)
import Data.Time.Clock (getCurrentTime) import Data.Time.Calendar (Day (..))
import Data.Time.Clock (getCurrentTime, UTCTime (..))
import Yesod.Form import Yesod.Form
import Vervis.Foundation (Form, Handler) import Vervis.Foundation (Form, Handler)
@ -32,15 +34,53 @@ import Vervis.Model
--TODO stuff like number and created - do I generate them here using monadic --TODO stuff like number and created - do I generate them here using monadic
-- form or do I rely on handler to provide? which approach is better? -- form or do I rely on handler to provide? which approach is better?
defTime :: UTCTime
defTime = UTCTime (ModifiedJulianDay 0) 0
now :: AForm Handler UTCTime
now = lift $ liftIO getCurrentTime
newTicketAForm :: ProjectId -> Int -> PersonId -> AForm Handler Ticket newTicketAForm :: ProjectId -> Int -> PersonId -> AForm Handler Ticket
newTicketAForm pid number author = Ticket newTicketAForm pid number author = Ticket
<$> pure pid <$> pure pid
<*> pure number <*> pure number
<*> lift (liftIO getCurrentTime) <*> now
<*> pure author <*> pure author
<*> areq textField "Title*" Nothing <*> areq textField "Title*" Nothing
<*> (maybe "" unTextarea <$> aopt textareaField "Description (Markdown)" Nothing) <*> ( maybe "" unTextarea <$>
aopt textareaField "Description (Markdown)" Nothing
)
<*> pure False <*> pure False
<*> pure defTime
<*> pure author
newTicketForm :: ProjectId -> Int -> PersonId -> Form Ticket newTicketForm :: ProjectId -> Int -> PersonId -> Form Ticket
newTicketForm pid number author = renderDivs $ newTicketAForm pid number author newTicketForm pid number author = renderDivs $ newTicketAForm pid number author
editTicketAForm :: Ticket -> PersonId -> AForm Handler Ticket
editTicketAForm ticket pid = fmap fixDone $ Ticket
<$> pure (ticketProject ticket)
<*> pure (ticketNumber ticket)
<*> pure (ticketCreated ticket)
<*> pure (ticketCreator ticket)
<*> areq textField "Title*" (Just $ ticketTitle ticket)
<*> ( maybe "" unTextarea <$>
aopt
textareaField
"Description (Markdown)"
(Just $ Just $ Textarea $ ticketDesc ticket)
)
<*> areq checkBoxField "Done*" (Just $ ticketDone ticket)
<*> now
<*> pure (ticketCloser ticket)
where
fixDone result = case (ticketDone ticket, ticketDone result) of
(True, True) -> result { ticketClosed = ticketClosed ticket }
(False, False) -> result { ticketClosed = ticketClosed ticket }
(False, True) -> result { ticketCloser = pid }
(True, False) -> result { ticketClosed = defTime
, ticketCloser = ticketCreator ticket
}
editTicketForm :: Ticket -> PersonId -> Form Ticket
editTicketForm t p = renderDivs $ editTicketAForm t p

View file

@ -116,6 +116,10 @@ instance Yesod App where
isAuthorized (KeyNewR user) _ = isAuthorized (KeyNewR user) _ =
loggedInAs user "You cant add keys for other users" loggedInAs user "You cant add keys for other users"
isAuthorized (TicketNewR _ _) _ = loggedIn isAuthorized (TicketNewR _ _) _ = loggedIn
isAuthorized (TicketR user _ _) True =
loggedInAs user "Only project members can modify this ticket"
isAuthorized (TicketEditR user _ _) _ =
loggedInAs user "Only project members can modify this ticket"
isAuthorized _ _ = return Authorized isAuthorized _ _ = return Authorized
-- This function creates static content files in the static folder -- This function creates static content files in the static folder

View file

@ -34,7 +34,7 @@ import Database.Persist
import Text.Blaze.Html (Html, toHtml) import Text.Blaze.Html (Html, toHtml)
import Yesod.Auth (requireAuthId) import Yesod.Auth (requireAuthId)
import Yesod.Core (defaultLayout) import Yesod.Core (defaultLayout)
import Yesod.Core.Handler (redirectUltDest, setMessage) import Yesod.Core.Handler (setMessage, redirect)
import Yesod.Core.Widget (setTitle) import Yesod.Core.Widget (setTitle)
import Yesod.Form.Functions (runFormPost) import Yesod.Form.Functions (runFormPost)
import Yesod.Form.Types (FormResult (..)) import Yesod.Form.Types (FormResult (..))
@ -50,10 +50,6 @@ import Vervis.Settings (widgetFile)
getTicketsR :: Text -> Text -> Handler Html getTicketsR :: Text -> Text -> Handler Html
getTicketsR shar proj = do getTicketsR shar proj = do
--tickets <- runDB $ do
-- Entity sid _sharer <- getBy404 $ UniqueSharerIdent shar
-- Entity pid _project <- getBy404 $ UniqueProject proj sid
-- selectList [TicketProject ==. pid] [Asc TicketNumber]
rows <- runDB $ select $ from $ \ (ticket, person, sharer) -> do rows <- runDB $ select $ from $ \ (ticket, person, sharer) -> do
where_ $ where_ $
ticket ^. TicketCreator E.==. person ^. PersonId &&. ticket ^. TicketCreator E.==. person ^. PersonId &&.
@ -84,7 +80,7 @@ postTicketsR shar proj = do
update pid [ProjectNextTicket +=. 1] update pid [ProjectNextTicket +=. 1]
insert_ ticket insert_ ticket
setMessage "Ticket created." setMessage "Ticket created."
redirectUltDest HomeR redirect $ TicketR shar proj (ticketNumber ticket)
FormMissing -> do FormMissing -> do
setMessage "Field(s) missing." setMessage "Field(s) missing."
defaultLayout $(widgetFile "ticket/new") defaultLayout $(widgetFile "ticket/new")
@ -106,23 +102,59 @@ getTicketNewR shar proj = do
getTicketR :: Text -> Text -> Int -> Handler Html getTicketR :: Text -> Text -> Int -> Handler Html
getTicketR shar proj num = do getTicketR shar proj num = do
(author, ticket) <- runDB $ do (author, closer, ticket) <- runDB $ do
Entity sid _sharer <- getBy404 $ UniqueSharerIdent shar Entity sid _sharer <- getBy404 $ UniqueSharerIdent shar
Entity pid _project <- getBy404 $ UniqueProject proj sid Entity pid _project <- getBy404 $ UniqueProject proj sid
Entity _tid ticket <- getBy404 $ UniqueTicket pid num Entity _tid ticket <- getBy404 $ UniqueTicket pid num
person <- get404 $ ticketCreator ticket person <- get404 $ ticketCreator ticket
author <- get404 $ personIdent person author <- get404 $ personIdent person
return (author, ticket) closer <-
if ticketDone ticket
then do
person' <- get404 $ ticketCloser ticket
get404 $ personIdent person'
else return author
return (author, closer, ticket)
defaultLayout $ do defaultLayout $ do
setTitle $ toHtml $ T.intercalate " :: " setTitle $ toHtml $ T.intercalate " :: "
[shar, proj, "Tickets", T.pack ('#' : show num)] [shar, proj, "Tickets", T.pack ('#' : show num)]
$(widgetFile "ticket/one") $(widgetFile "ticket/one")
putTicketR :: Text -> Text -> Int -> Handler Html putTicketR :: Text -> Text -> Int -> Handler Html
putTicketR shar proj num = error "Not implemented" putTicketR shar proj num = do
Entity tid ticket <- runDB $ do
Entity sid _sharer <- getBy404 $ UniqueSharerIdent shar
Entity pid _project <- getBy404 $ UniqueProject proj sid
getBy404 $ UniqueTicket pid num
user <- requireAuthId
((result, widget), enctype) <- runFormPost $ editTicketForm ticket user
case result of
FormSuccess ticket' -> do
runDB $ replace tid ticket'
setMessage "Ticket created."
redirect $ TicketR shar proj num
FormMissing -> do
setMessage "Field(s) missing."
defaultLayout $(widgetFile "ticket/edit")
FormFailure _l -> do
setMessage "Ticket update failed, see errors below."
defaultLayout $(widgetFile "ticket/edit")
deleteTicketR :: Text -> Text -> Int -> Handler Html deleteTicketR :: Text -> Text -> Int -> Handler Html
deleteTicketR shar proj num = error "Not implemented" deleteTicketR shar proj num =
--TODO: I can easily implement this, but should it even be possible to
--delete tickets?
error "Not implemented"
getTicketEditR :: Text -> Text -> Int -> Handler Html getTicketEditR :: Text -> Text -> Int -> Handler Html
getTicketEditR shar proj num = error "Not implemented" getTicketEditR shar proj num = do
Entity _tid ticket <- runDB $ do
Entity sid _sharer <- getBy404 $ UniqueSharerIdent shar
Entity pid _project <- getBy404 $ UniqueProject proj sid
getBy404 $ UniqueTicket pid num
user <- requireAuthId
((_result, widget), enctype) <- runFormPost $ editTicketForm ticket user
defaultLayout $ do
setTitle $ toHtml $ T.intercalate " :: "
[shar, proj, "Tickets", T.pack ('#' : show num), "Edit"]
$(widgetFile "ticket/edit")

View file

@ -0,0 +1,21 @@
$# This file is part of Vervis.
$#
$# Written in 2016 by fr33domlover <fr33domlover@riseup.net>.
$#
$# ♡ Copying is an act of love. Please copy, reuse and share.
$#
$# The author(s) have dedicated all copyright and related and neighboring
$# rights to this software to the public domain worldwide. This software is
$# distributed without any warranty.
$#
$# You should have received a copy of the CC0 Public Domain Dedication along
$# with this software. If not, see
$# <http://creativecommons.org/publicdomain/zero/1.0/>.
<h1>#{shar} :: #{proj} :: Tickets :: ##{num} :: Edit
Enter the details and click "Submit" to update the ticket.
<form method=PUT action=@{TicketR shar proj num} enctype=#{enctype}>
^{widget}
<input type=submit>

View file

@ -24,7 +24,13 @@ $# <http://creativecommons.org/publicdomain/zero/1.0/>.
Created on #{formatTime defaultTimeLocale "%F" $ ticketCreated ticket} by Created on #{formatTime defaultTimeLocale "%F" $ ticketCreated ticket} by
#{fromMaybe (sharerIdent author) $ sharerName author} #{fromMaybe (sharerIdent author) $ sharerName author}
<p>Done: #{ticketDone ticket} <p>
Status:
$if ticketDone ticket
Closed on #{formatTime defaultTimeLocale "%F" $ ticketClosed ticket} by
#{fromMaybe (sharerIdent closer) $ sharerName closer}
$else
Open
<h2>#{ticketTitle ticket} <h2>#{ticketTitle ticket}