diff --git a/src/Vervis/Client.hs b/src/Vervis/Client.hs index b9312aa..ff6c134 100644 --- a/src/Vervis/Client.hs +++ b/src/Vervis/Client.hs @@ -24,7 +24,7 @@ module Vervis.Client --, followProject --, followTicket --, followRepo - --, offerTicket + , offerIssue --, resolve --, undoFollowSharer --, undoFollowProject @@ -299,55 +299,65 @@ followRepo shrAuthor shrObject rpObject hide = do let uObject = encodeRouteHome $ RepoR shrObject rpObject follow shrAuthor uObject uObject hide -} +-} + +offerIssue + :: KeyHashid Person -> Text -> PandocMarkdown -> FedURI + -> ExceptT Text Handler (Maybe HTML, [Aud URIMode], AP.Ticket URIMode) +offerIssue senderHash title desc uTracker = do + + tracker <- do + tracker <- checkTracker uTracker + case tracker of + TrackerDeck deckID -> Left <$> encodeKeyHashid deckID + TrackerLoom _ -> throwE "Local patch tracker doesn't take issues" + TrackerRemote (ObjURI hTracker luTracker) -> Right <$> do + instanceID <- lift $ runDB $ either entityKey id <$> insertBy' (Instance hTracker) + result <- ExceptT $ first (T.pack . displayException) <$> fetchRemoteActor instanceID hTracker luTracker + case result of + Left Nothing -> throwE "Tracker @id mismatch" + Left (Just err) -> throwE $ T.pack $ displayException err + Right Nothing -> throwE "Tracker isn't an actor" + Right (Just actor) -> return (entityVal actor, uTracker) -offerTicket - :: (MonadHandler m, HandlerSite m ~ App, MonadSite m, SiteEnv m ~ App) - => ShrIdent -> TextHtml -> TextPandocMarkdown -> ShrIdent -> PrjIdent -> m (Either Text (TextHtml, Audience URIMode, AP.Ticket URIMode, FedURI)) -offerTicket shrAuthor (TextHtml title) (TextPandocMarkdown desc) shr prj = runExceptT $ do - error "Temporarily disabled" - {- - encodeRouteLocal <- getEncodeRouteLocal - encodeRouteHome <- getEncodeRouteHome descHtml <- ExceptT . pure $ renderPandocMarkdown desc - summary <- - TextHtml . TL.toStrict . renderHtml <$> - withUrlRenderer - [hamlet| -
-
- #{shr2text shrAuthor}
- \ offered a ticket to project #
-
- ./s/#{shr2text shr}/p/#{prj2text prj}
- : #{preEscapedToHtml title}.
- |]
- let recipsA = [ProjectR shr prj]
- recipsC = [ProjectTeamR shr prj, ProjectFollowersR shr prj]
+
+ encodeRouteLocal <- getEncodeRouteLocal
+ hLocal <- asksSite siteInstanceHost
+
+ let audAuthor =
+ AudLocal [] [LocalStagePersonFollowers senderHash]
+ audTracker =
+ case tracker of
+ Left deckHash ->
+ AudLocal
+ [LocalActorDeck deckHash]
+ [LocalStageDeckFollowers deckHash]
+ Right (remoteActor, ObjURI hTracker luTracker) ->
+ AudRemote hTracker
+ [luTracker]
+ (maybeToList $ remoteActorFollowers remoteActor)
+
+ audience = [audAuthor, audTracker]
+
ticket = AP.Ticket
{ AP.ticketLocal = Nothing
- , AP.ticketAttributedTo = encodeRouteLocal $ SharerR shrAuthor
+ , AP.ticketAttributedTo = encodeRouteLocal $ PersonR senderHash
, AP.ticketPublished = Nothing
, AP.ticketUpdated = Nothing
, AP.ticketContext = Nothing
- -- , AP.ticketName = Nothing
- , AP.ticketSummary = TextHtml title
- , AP.ticketContent = TextHtml descHtml
- , AP.ticketSource = TextPandocMarkdown desc
+ , AP.ticketSummary = encodeEntities title
+ , AP.ticketContent = descHtml
+ , AP.ticketSource = desc
, AP.ticketAssignedTo = Nothing
, AP.ticketResolved = Nothing
, AP.ticketAttachment = Nothing
}
- target = encodeRouteHome $ ProjectR shr prj
- audience = Audience
- { audienceTo = map encodeRouteHome $ recipsA ++ recipsC
- , audienceBto = []
- , audienceCc = []
- , audienceBcc = []
- , audienceGeneral = []
- , audienceNonActors = map encodeRouteHome recipsC
- }
- return (summary, audience, ticket, target)
+ return (Nothing, audience, ticket)
+
+{-
+{-
resolve
:: (MonadHandler m, HandlerSite m ~ App, MonadSite m, SiteEnv m ~ App)
=> ShrIdent
diff --git a/src/Vervis/Form/Ticket.hs b/src/Vervis/Form/Ticket.hs
index ca3c581..9b5acc5 100644
--- a/src/Vervis/Form/Ticket.hs
+++ b/src/Vervis/Form/Ticket.hs
@@ -14,12 +14,16 @@
-}
module Vervis.Form.Ticket
- ( --NewTicket (..)
- --, newTicketForm
+ ( fedUriField
+
+ , NewTicket (..)
+ , NewCloth (..)
+ , newTicketForm
+ , newClothForm
--, editTicketContentForm
--, assignTicketForm
--, claimRequestForm
- ticketFilterForm
+ , ticketFilterForm
--, ticketDepForm
)
where
@@ -32,13 +36,19 @@ import Data.Maybe
import Data.Text (Text)
import Data.Time.Calendar (Day (..))
import Data.Time.Clock (getCurrentTime, UTCTime (..))
+import Data.Traversable
import Database.Persist
-import Text.HTML.SanitizeXSS
+import Yesod.Core
import Yesod.Form
import Yesod.Persist.Core (runDB)
import qualified Data.Text as T
+import Development.PatchMediaType
+import Network.FedURI
+import Web.Text
+
+import Vervis.FedURI
import Vervis.Foundation (App, Form, Handler)
import Vervis.Model
import Vervis.Model.Ticket
@@ -46,18 +56,36 @@ import Vervis.Model.Workflow
import Vervis.Ticket
import Vervis.TicketFilter (TicketFilter (..))
+fedUriField
+ :: (Monad m, RenderMessage (HandlerSite m) FormMessage) => Field m FedURI
+fedUriField = Field
+ { fieldParse = parseHelper $ \ t ->
+ case parseObjURI t of
+ Left e -> Left $ MsgInvalidUrl $ T.pack e <> ": " <> t
+ Right u -> Right u
+ , fieldView = \theId name attrs val isReq ->
+ [whamlet||]
+ , fieldEnctype = UrlEncoded
+ }
--TODO use custom fields to ensure uniqueness or other constraints?
-{-
data NewTicket = NewTicket
{ ntTitle :: Text
- , ntDesc :: Text
- , ntTParams :: [(WorkflowFieldId, Text)]
- , ntEParams :: [(WorkflowFieldId, WorkflowEnumCtorId)]
- , ntCParams :: [WorkflowFieldId]
- , ntOffer :: Bool
+ , ntDesc :: PandocMarkdown
+ --, ntTParams :: [(WorkflowFieldId, Text)]
+ --, ntEParams :: [(WorkflowFieldId, WorkflowEnumCtorId)]
+ --, ntCParams :: [WorkflowFieldId]
}
+data NewCloth = NewCloth
+ { ncTitle :: Text
+ , ncDesc :: PandocMarkdown
+ , ncTarget :: Maybe Text
+ , ncOrigin :: Maybe (FedURI, Maybe Text)
+ , ncPatch :: Maybe (PatchMediaType, FileInfo)
+ }
+
+{-
fieldSettings :: Text -> Bool -> FieldSettings App
fieldSettings name req =
fieldSettingsLabel $
@@ -103,9 +131,11 @@ cfield (Entity fid f) =
in if workflowFieldRequired f
then mkval <$> areq checkBoxField sets Nothing
else mkval . fromMaybe False <$> aopt checkBoxField sets Nothing
+-}
newTicketForm :: WorkflowId -> Form NewTicket
newTicketForm wid html = do
+ {-
(tfs, efs, cfs) <- lift $ runDB $ do
tfs <- selectList
[ WorkflowFieldWorkflow ==. wid
@@ -128,16 +158,37 @@ newTicketForm wid html = do
]
[]
return (tfs, efs, cfs)
+ -}
flip renderDivs html $ NewTicket
- <$> (sanitizeBalance <$> areq textField "Title*" Nothing)
- <*> ( maybe "" (T.filter (/= '\r') . unTextarea) <$>
- aopt textareaField "Description (Markdown)" Nothing
+ <$> (areq textField "Title*" Nothing)
+ <*> ( pandocMarkdownFromText . T.filter (/= '\r') . unTextarea <$>
+ areq textareaField "Description (Markdown)*" Nothing
)
- <*> (catMaybes <$> traverse tfield tfs)
- <*> (fmap catMaybes $ sequenceA $ mapMaybe efield efs)
- <*> (catMaybes <$> traverse cfield cfs)
- <*> areq checkBoxField "Offer" Nothing
--}
+ -- <*> (catMaybes <$> traverse tfield tfs)
+ -- <*> (fmap catMaybes $ sequenceA $ mapMaybe efield efs)
+ -- <*> (catMaybes <$> traverse cfield cfs)
+
+newClothForm :: Form NewCloth
+newClothForm = renderDivs $ mk
+ <$> (areq textField "Title*" Nothing)
+ <*> ( pandocMarkdownFromText . T.filter (/= '\r') . unTextarea <$>
+ areq textareaField "Description (Markdown)*" Nothing
+ )
+ <*> aopt textField "Target branch" Nothing
+ <*> aopt fedUriField "Origin repo" Nothing
+ <*> aopt textField "Origin branch" Nothing
+ <*> aopt (selectFieldList typeList) "Patch type" Nothing
+ <*> aopt fileField "Patch file" Nothing
+ where
+ typeList :: [(Text, PatchMediaType)]
+ typeList =
+ [ ("Darcs", PatchMediaTypeDarcs)
+ , ("Git" , PatchMediaTypeGit)
+ ]
+ mk title desc targetBranch originRepo originBranch typ file =
+ NewCloth
+ title desc targetBranch
+ ((,originBranch) <$> originRepo) ((,) <$> typ <*> file)
{-
editTicketContentAForm :: Ticket -> AForm Handler Ticket
diff --git a/src/Vervis/Form/Project.hs b/src/Vervis/Form/Tracker.hs
similarity index 95%
rename from src/Vervis/Form/Project.hs
rename to src/Vervis/Form/Tracker.hs
index c2337b7..ad6a5e9 100644
--- a/src/Vervis/Form/Project.hs
+++ b/src/Vervis/Form/Tracker.hs
@@ -13,9 +13,9 @@
-