UI: Fix and re-enable deck ticket list view

This commit is contained in:
fr33domlover 2022-09-17 10:14:27 +00:00
parent c495d78d05
commit e69d775f3f
7 changed files with 91 additions and 83 deletions

View file

@ -1,6 +1,6 @@
{- This file is part of Vervis. {- This file is part of Vervis.
- -
- Written in 2016, 2019, 2020 by fr33domlover <fr33domlover@riseup.net>. - Written in 2016, 2019, 2020, 2022 by fr33domlover <fr33domlover@riseup.net>.
- -
- Copying is an act of love. Please copy, reuse and share. - Copying is an act of love. Please copy, reuse and share.
- -
@ -14,12 +14,12 @@
-} -}
module Vervis.Form.Ticket module Vervis.Form.Ticket
( NewTicket (..) ( --NewTicket (..)
, newTicketForm --, newTicketForm
, editTicketContentForm --, editTicketContentForm
, assignTicketForm --, assignTicketForm
, claimRequestForm --, claimRequestForm
, ticketFilterForm ticketFilterForm
--, ticketDepForm --, ticketDepForm
) )
where where
@ -39,7 +39,6 @@ import Yesod.Persist.Core (runDB)
import qualified Data.Text as T import qualified Data.Text as T
import Vervis.Field.Ticket
import Vervis.Foundation (App, Form, Handler) import Vervis.Foundation (App, Form, Handler)
import Vervis.Model import Vervis.Model
import Vervis.Model.Ticket import Vervis.Model.Ticket
@ -49,6 +48,7 @@ import Vervis.TicketFilter (TicketFilter (..))
--TODO use custom fields to ensure uniqueness or other constraints? --TODO use custom fields to ensure uniqueness or other constraints?
{-
data NewTicket = NewTicket data NewTicket = NewTicket
{ ntTitle :: Text { ntTitle :: Text
, ntDesc :: Text , ntDesc :: Text
@ -137,7 +137,9 @@ newTicketForm wid html = do
<*> (fmap catMaybes $ sequenceA $ mapMaybe efield efs) <*> (fmap catMaybes $ sequenceA $ mapMaybe efield efs)
<*> (catMaybes <$> traverse cfield cfs) <*> (catMaybes <$> traverse cfield cfs)
<*> areq checkBoxField "Offer" Nothing <*> areq checkBoxField "Offer" Nothing
-}
{-
editTicketContentAForm :: Ticket -> AForm Handler Ticket editTicketContentAForm :: Ticket -> AForm Handler Ticket
editTicketContentAForm ticket = Ticket editTicketContentAForm ticket = Ticket
<$> pure (ticketNumber ticket) <$> pure (ticketNumber ticket)
@ -240,19 +242,24 @@ editTicketContentForm tid t wid html = do
<*> traverse tEditField tfs <*> traverse tEditField tfs
<*> traverse eEditField efs <*> traverse eEditField efs
<*> traverse cEditField cfs <*> traverse cEditField cfs
-}
{-
assignTicketAForm :: PersonId -> ProjectId -> AForm Handler PersonId assignTicketAForm :: PersonId -> ProjectId -> AForm Handler PersonId
assignTicketAForm pid jid = assignTicketAForm pid jid =
areq (selectAssigneeFromProject pid jid) "Assignee*" Nothing areq (selectAssigneeFromProject pid jid) "Assignee*" Nothing
assignTicketForm :: PersonId -> ProjectId -> Form PersonId assignTicketForm :: PersonId -> ProjectId -> Form PersonId
assignTicketForm pid jid = renderDivs $ assignTicketAForm pid jid assignTicketForm pid jid = renderDivs $ assignTicketAForm pid jid
-}
{-
claimRequestAForm :: AForm Handler Text claimRequestAForm :: AForm Handler Text
claimRequestAForm = unTextarea <$> areq textareaField "Message*" Nothing claimRequestAForm = unTextarea <$> areq textareaField "Message*" Nothing
claimRequestForm :: Form Text claimRequestForm :: Form Text
claimRequestForm = renderDivs claimRequestAForm claimRequestForm = renderDivs claimRequestAForm
-}
ticketFilterAForm :: AForm Handler TicketFilter ticketFilterAForm :: AForm Handler TicketFilter
ticketFilterAForm = mk ticketFilterAForm = mk

View file

@ -57,6 +57,7 @@ import Control.Monad
import Control.Monad.Trans.Except import Control.Monad.Trans.Except
import Data.Aeson import Data.Aeson
import Data.ByteString (ByteString) import Data.ByteString (ByteString)
import Data.Default.Class
import Data.Foldable import Data.Foldable
import Data.Maybe (fromMaybe) import Data.Maybe (fromMaybe)
import Data.Text (Text) import Data.Text (Text)
@ -67,7 +68,7 @@ import Text.Blaze.Html (Html)
import Yesod.Auth (requireAuth) import Yesod.Auth (requireAuth)
import Yesod.Core import Yesod.Core
import Yesod.Core.Handler (redirect, setMessage, lookupPostParam, notFound) import Yesod.Core.Handler (redirect, setMessage, lookupPostParam, notFound)
import Yesod.Form.Functions (runFormPost) import Yesod.Form.Functions (runFormPost, runFormGet)
import Yesod.Form.Types (FormResult (..)) import Yesod.Form.Types (FormResult (..))
import Yesod.Persist.Core (runDB, get404, getBy404) import Yesod.Persist.Core (runDB, get404, getBy404)
@ -98,13 +99,17 @@ import Vervis.Federation.Auth
import Vervis.Federation.Collab import Vervis.Federation.Collab
import Vervis.FedURI import Vervis.FedURI
import Vervis.Form.Project import Vervis.Form.Project
import Vervis.Form.Ticket
import Vervis.Foundation import Vervis.Foundation
import Vervis.Model import Vervis.Model
import Vervis.Paginate import Vervis.Paginate
import Vervis.Recipient import Vervis.Recipient
import Vervis.Settings import Vervis.Settings
import Vervis.Ticket
import Vervis.TicketFilter
import Vervis.Web.Actor import Vervis.Web.Actor
import Vervis.Widget.Person import Vervis.Widget.Person
import Vervis.Widget.Ticket
import qualified Vervis.Client as C import qualified Vervis.Client as C
@ -209,7 +214,6 @@ getDeckFollowersR = getActorFollowersCollection DeckFollowersR deckActor
getDeckTicketsR :: KeyHashid Deck -> Handler TypedContent getDeckTicketsR :: KeyHashid Deck -> Handler TypedContent
getDeckTicketsR deckHash = selectRep $ do getDeckTicketsR deckHash = selectRep $ do
{-
provideRep $ do provideRep $ do
((filtResult, filtWidget), filtEnctype) <- runFormGet ticketFilterForm ((filtResult, filtWidget), filtEnctype) <- runFormGet ticketFilterForm
let tf = let tf =
@ -218,26 +222,26 @@ getDeckTicketsR deckHash = selectRep $ do
FormMissing -> def FormMissing -> def
FormFailure l -> FormFailure l ->
error $ "Ticket filter form failed: " ++ show l error $ "Ticket filter form failed: " ++ show l
deckID <- decodeKeyHashid404 deckHash
(total, pages, mpage) <- runDB $ do (total, pages, mpage) <- runDB $ do
Entity sid _ <- getBy404 $ UniqueSharer shr _ <- get404 deckID
Entity jid _ <- getBy404 $ UniqueProject prj sid let countAllTickets = count [TicketDeckDeck ==. deckID]
let countAllTickets = count [TicketProjectLocalProject ==. jid]
selectTickets off lim = selectTickets off lim =
getTicketSummaries getTicketSummaries
(filterTickets tf) (filterTickets tf)
(Just $ \ t -> [E.asc $ t E.^. TicketId]) (Just $ \ t -> [E.desc $ t E.^. TicketId])
(Just (off, lim)) (Just (off, lim))
jid deckID
getPageAndNavCount countAllTickets selectTickets getPageAndNavCount countAllTickets selectTickets
case mpage of case mpage of
Nothing -> redirectFirstPage here Nothing -> redirectFirstPage here
Just (rows, navModel) -> Just (rows, navModel) ->
let pageNav = navWidget navModel let pageNav = navWidget navModel
in defaultLayout $(widgetFile "ticket/list") in defaultLayout $(widgetFile "ticket/list")
-}
provideAP' $ do provideAP' $ do
deckID <- decodeKeyHashid404 deckHash deckID <- decodeKeyHashid404 deckHash
(total, pages, mpage) <- runDB $ do (total, pages, mpage) <- runDB $ do
_ <- get404 deckID
let countAllTickets = count [TicketDeckDeck ==. deckID] let countAllTickets = count [TicketDeckDeck ==. deckID]
selectTickets off lim = selectTickets off lim =
selectKeysList selectKeysList

View file

@ -16,9 +16,9 @@
module Vervis.Ticket module Vervis.Ticket
( (
{-
getTicketSummaries getTicketSummaries
--, getTicketDepEdges --, getTicketDepEdges
{-
, WorkflowFieldFilter (..) , WorkflowFieldFilter (..)
, WorkflowFieldSummary (..) , WorkflowFieldSummary (..)
, TicketTextParamValue (..) , TicketTextParamValue (..)
@ -32,7 +32,7 @@ module Vervis.Ticket
, getTicketClasses , getTicketClasses
-} -}
getTicket , getTicket
, getTicket404 , getTicket404
--, getDependencyCollection --, getDependencyCollection
@ -88,43 +88,42 @@ import Vervis.Model.Ident
import Vervis.Model.Workflow import Vervis.Model.Workflow
import Vervis.Paginate import Vervis.Paginate
import Vervis.Recipient import Vervis.Recipient
import Vervis.Widget.Ticket
{-
-- | Get summaries of all the tickets in the given project. -- | Get summaries of all the tickets in the given project.
getTicketSummaries getTicketSummaries
:: Maybe (E.SqlExpr (Entity Ticket) -> E.SqlExpr (E.Value Bool)) :: Maybe (E.SqlExpr (Entity Ticket) -> E.SqlExpr (E.Value Bool))
-> Maybe (E.SqlExpr (Entity Ticket) -> [E.SqlExpr E.OrderBy]) -> Maybe (E.SqlExpr (Entity Ticket) -> [E.SqlExpr E.OrderBy])
-> Maybe (Int, Int) -> Maybe (Int, Int)
-> ProjectId -> DeckId
-> AppDB [TicketSummary] -> AppDB [TicketSummary]
getTicketSummaries mfilt morder offlim jid = do getTicketSummaries mfilt morder offlim deckID = do
tickets <- E.select $ E.from $ tickets <- E.select $ E.from $
\ ( t \ ( t
`E.InnerJoin` lt `E.InnerJoin` td
`E.InnerJoin` tcl `E.LeftOuterJoin` (tal `E.InnerJoin` p `E.InnerJoin` a)
`E.InnerJoin` tpl
`E.LeftOuterJoin` (tal `E.InnerJoin` p `E.InnerJoin` s `E.LeftOuterJoin` tup)
`E.LeftOuterJoin` (tar `E.InnerJoin` ra `E.InnerJoin` ro `E.InnerJoin` i) `E.LeftOuterJoin` (tar `E.InnerJoin` ra `E.InnerJoin` ro `E.InnerJoin` i)
`E.InnerJoin` d `E.InnerJoin` d
`E.LeftOuterJoin` m `E.LeftOuterJoin` m
) -> do ) -> do
E.on $ E.just (d E.^. DiscussionId) E.==. m E.?. MessageRoot E.on $ E.just (d E.^. DiscussionId) E.==. m E.?. MessageRoot
E.on $ lt E.^. LocalTicketDiscuss E.==. d E.^. DiscussionId E.on $ t E.^. TicketDiscuss E.==. d E.^. DiscussionId
E.on $ ro E.?. RemoteObjectInstance E.==. i E.?. InstanceId E.on $ ro E.?. RemoteObjectInstance E.==. i E.?. InstanceId
E.on $ ra E.?. RemoteActorIdent E.==. ro E.?. RemoteObjectId E.on $ ra E.?. RemoteActorIdent E.==. ro E.?. RemoteObjectId
E.on $ tar E.?. TicketAuthorRemoteAuthor E.==. ra E.?. RemoteActorId E.on $ tar E.?. TicketAuthorRemoteAuthor E.==. ra E.?. RemoteActorId
E.on $ E.just (tcl E.^. TicketContextLocalId) E.==. tar E.?. TicketAuthorRemoteTicket E.on $ E.just (t E.^. TicketId) E.==. tar E.?. TicketAuthorRemoteTicket
E.on $ tal E.?. TicketAuthorLocalId E.==. tup E.?. TicketUnderProjectAuthor
E.on $ p E.?. PersonIdent E.==. s E.?. SharerId E.on $ p E.?. PersonActor E.==. a E.?. ActorId
E.on $ tal E.?. TicketAuthorLocalAuthor E.==. p E.?. PersonId E.on $ tal E.?. TicketAuthorLocalAuthor E.==. p E.?. PersonId
E.on $ E.just (lt E.^. LocalTicketId) E.==. tal E.?. TicketAuthorLocalTicket E.on $ E.just (t E.^. TicketId) E.==. tal E.?. TicketAuthorLocalTicket
E.on $ tcl E.^. TicketContextLocalId E.==. tpl E.^. TicketProjectLocalContext
E.on $ t E.^. TicketId E.==. tcl E.^. TicketContextLocalTicket E.on $ t E.^. TicketId E.==. td E.^. TicketDeckTicket
E.on $ t E.^. TicketId E.==. lt E.^. LocalTicketTicket
E.where_ $ tpl E.^. TicketProjectLocalProject E.==. E.val jid E.where_ $ td E.^. TicketDeckDeck E.==. E.val deckID
E.groupBy E.groupBy
( t E.^. TicketId, lt E.^. LocalTicketId ( t E.^. TicketId
, tal E.?. TicketAuthorLocalId, s E.?. SharerId, tup E.?. TicketUnderProjectId , tal E.?. TicketAuthorLocalId, p E.?. PersonId, a E.?. ActorId
, ra E.?. RemoteActorId, ro E.?. RemoteObjectId, i E.?. InstanceId , ra E.?. RemoteActorId, ro E.?. RemoteObjectId, i E.?. InstanceId
) )
for_ mfilt $ \ filt -> E.where_ $ filt t for_ mfilt $ \ filt -> E.where_ $ filt t
@ -132,35 +131,30 @@ getTicketSummaries mfilt morder offlim jid = do
for_ offlim $ \ (off, lim) -> do for_ offlim $ \ (off, lim) -> do
E.offset $ fromIntegral off E.offset $ fromIntegral off
E.limit $ fromIntegral lim E.limit $ fromIntegral lim
return return
( t E.^. TicketId ( t E.^. TicketId
, lt E.^. LocalTicketId , td E.^. TicketDeckId
, tal E.?. TicketAuthorLocalId , p, a
, s , i, ro, ra
, tup E.?. TicketUnderProjectId
, i
, ro
, ra
, t E.^. TicketCreated , t E.^. TicketCreated
, t E.^. TicketTitle , t E.^. TicketTitle
, t E.^. TicketStatus , t E.^. TicketStatus
, E.count $ m E.?. MessageId , E.count $ m E.?. MessageId
) )
for tickets $ for tickets $
\ (E.Value tid, E.Value ltid, E.Value mtalid, ms, E.Value mtupid, mi, mro, mra, E.Value c, E.Value t, E.Value d, E.Value r) -> do \ (E.Value tid, E.Value tdid, mp, ma, mi, mro, mra, E.Value c, E.Value t, E.Value d, E.Value r) -> do
labels <- E.select $ E.from $ \ (tpc `E.InnerJoin` wf) -> do labels <- E.select $ E.from $ \ (tpc `E.InnerJoin` wf) -> do
E.on $ tpc E.^. TicketParamClassField E.==. wf E.^. WorkflowFieldId E.on $ tpc E.^. TicketParamClassField E.==. wf E.^. WorkflowFieldId
E.where_ $ tpc E.^. TicketParamClassTicket E.==. E.val tid E.where_ $ tpc E.^. TicketParamClassTicket E.==. E.val tid
return wf return wf
return TicketSummary return TicketSummary
{ tsId = ltid { tsId = tdid
, tsCreatedBy = , tsCreatedBy =
case (mtalid, ms, mi, mro, mra) of case (mp, ma, mi, mro, mra) of
(Just talid, Just s, Nothing, Nothing, Nothing) -> (Just p, Just a, Nothing, Nothing, Nothing) ->
Left Left (p, entityVal a)
( entityVal s
, if isJust mtupid then Nothing else Just talid
)
(Nothing, Nothing, Just i, Just ro, Just ra) -> (Nothing, Nothing, Just i, Just ro, Just ra) ->
Right (entityVal i, entityVal ro, entityVal ra) Right (entityVal i, entityVal ro, entityVal ra)
_ -> error "Ticket author DB invalid state" _ -> error "Ticket author DB invalid state"
@ -171,6 +165,7 @@ getTicketSummaries mfilt morder offlim jid = do
, tsComments = r , tsComments = r
} }
{-
-- | Get the child-parent ticket number pairs of all the ticket dependencies -- | Get the child-parent ticket number pairs of all the ticket dependencies
-- in the given project, in ascending order by child, and then ascending order -- in the given project, in ascending order by child, and then ascending order
-- by parent. -- by parent.

View file

@ -1,6 +1,6 @@
{- This file is part of Vervis. {- This file is part of Vervis.
- -
- Written in 2016, 2019, 2020 by fr33domlover <fr33domlover@riseup.net>. - Written in 2016, 2019, 2020, 2022 by fr33domlover <fr33domlover@riseup.net>.
- -
- Copying is an act of love. Please copy, reuse and share. - Copying is an act of love. Please copy, reuse and share.
- -
@ -15,10 +15,10 @@
module Vervis.Widget.Ticket module Vervis.Widget.Ticket
( TicketSummary (..) ( TicketSummary (..)
, ticketDepW --, ticketDepW
, ticketSummaryW , ticketSummaryW
, ticketTreeVW --, ticketTreeVW
, ticketTreeDW --, ticketTreeDW
) )
where where
@ -45,16 +45,17 @@ import Yesod.Hashids
import Vervis.Foundation import Vervis.Foundation
import Vervis.Model import Vervis.Model
import Vervis.Model.Ident
import Vervis.Model.Ticket import Vervis.Model.Ticket
import Vervis.Settings (widgetFile) import Vervis.Settings (widgetFile)
import Vervis.Style import Vervis.Style
import Vervis.Time (showDate) import Vervis.Time (showDate)
import Vervis.Widget.Sharer import Vervis.Widget.Person
data TicketSummary = TicketSummary data TicketSummary = TicketSummary
{ tsId :: LocalTicketId { tsId :: TicketDeckId
, tsCreatedBy :: Either (Sharer, Maybe TicketAuthorLocalId) (Instance, RemoteObject, RemoteActor) , tsCreatedBy :: Either
(Entity Person, Actor)
(Instance, RemoteObject, RemoteActor)
, tsCreatedAt :: UTCTime , tsCreatedAt :: UTCTime
, tsTitle :: Text , tsTitle :: Text
, tsLabels :: [WorkflowField] , tsLabels :: [WorkflowField]
@ -62,6 +63,7 @@ data TicketSummary = TicketSummary
, tsComments :: Int , tsComments :: Int
} }
{-
ticketDepW :: ShrIdent -> PrjIdent -> LocalTicketId -> Ticket -> Widget ticketDepW :: ShrIdent -> PrjIdent -> LocalTicketId -> Ticket -> Widget
ticketDepW shr prj ltid ticket = do ticketDepW shr prj ltid ticket = do
encodeTicketKey <- getEncodeKeyHashid encodeTicketKey <- getEncodeKeyHashid
@ -69,31 +71,28 @@ ticketDepW shr prj ltid ticket = do
cTodo <- newIdent cTodo <- newIdent
cClosed <- newIdent cClosed <- newIdent
$(widgetFile "ticket/widget/dep") $(widgetFile "ticket/widget/dep")
-}
ticketSummaryW ticketSummaryW
:: ShrIdent :: KeyHashid Deck
-> PrjIdent
-> TicketSummary -> TicketSummary
-> Maybe (HashMap Int64 Int64) -> Maybe (HashMap Int64 Int64)
-> Widget -> Widget
ticketSummaryW shr prj ts mcs = do ticketSummaryW deckHash ts mcs = do
encodeLT <- getEncodeKeyHashid hashTicket <- getEncodeKeyHashid
encodeTAL <- getEncodeKeyHashid
cNew <- newIdent cNew <- newIdent
cTodo <- newIdent cTodo <- newIdent
cClosed <- newIdent cClosed <- newIdent
let tshow = T.pack . show let tshow = T.pack . show
mparams = map (tshow *** tshow) . M.toList <$> mcs mparams = map (tshow *** tshow) . M.toList <$> mcs
ticketRoute = ticketRoute' encodeLT encodeTAL ticketRoute = ticketRoute' hashTicket
mroute <- getCurrentRoute mroute <- getCurrentRoute
$(widgetFile "ticket/widget/summary") $(widgetFile "ticket/widget/summary")
where where
ticketRoute' encodeLT encodeTAL summary = ticketRoute' hashTicket summary =
case tsCreatedBy summary of TicketR deckHash (hashTicket $ tsId summary)
Left (s, Just talid) ->
SharerTicketR (sharerIdent s) (encodeTAL talid)
_ -> ProjectTicketR shr prj $ encodeLT $ tsId summary
{-
-- I'm noticing a pattern. A problem. Some of my widget functions take data and -- I'm noticing a pattern. A problem. Some of my widget functions take data and
-- directly represent it in HTML. Others take some other more general -- directly represent it in HTML. Others take some other more general
-- structures, then pick the relevant pieces and generate HTML. Others involve -- structures, then pick the relevant pieces and generate HTML. Others involve
@ -121,7 +120,9 @@ ticketTreeVW shr prj cDeps t = go t
^{go tree} ^{go tree}
|] |]
go (LinkNode (ts, cs)) = summary ts (Just cs) go (LinkNode (ts, cs)) = summary ts (Just cs)
-}
{-
-- | In the request's GET parameters, find ones of the form @N=M@ where N and M -- | In the request's GET parameters, find ones of the form @N=M@ where N and M
-- are integers. Return a list of pairs corresponding to those parameters. -- are integers. Return a list of pairs corresponding to those parameters.
getParentChoices :: MonadHandler m => m [(Int64, Int64)] getParentChoices :: MonadHandler m => m [(Int64, Int64)]
@ -144,3 +145,4 @@ ticketTreeDW shr prj summaries deps = do
oneTree = ticketTreeVW shr prj cDeps oneTree = ticketTreeVW shr prj cDeps
forest = map oneTree $ dagViewTree nodes deps choices forest = map oneTree $ dagViewTree nodes deps choices
$(widgetFile "ticket/widget/tree") $(widgetFile "ticket/widget/tree")
-}

View file

@ -1,6 +1,6 @@
$# This file is part of Vervis. $# This file is part of Vervis.
$# $#
$# Written in 2016, 2018 by fr33domlover <fr33domlover@riseup.net>. $# Written in 2016, 2018, 2022 by fr33domlover <fr33domlover@riseup.net>.
$# $#
$# ♡ Copying is an act of love. Please copy, reuse and share. $# ♡ Copying is an act of love. Please copy, reuse and share.
$# $#
@ -12,13 +12,13 @@ $# You should have received a copy of the CC0 Public Domain Dedication along
$# with this software. If not, see $# with this software. If not, see
$# <http://creativecommons.org/publicdomain/zero/1.0/>. $# <http://creativecommons.org/publicdomain/zero/1.0/>.
<p> $# <p>
<a href=@{ProjectTicketNewR shr prj}>Create new… $# <a href=@{ProjectTicketNewR shr prj}>Create new…
<p> $# <p>
<a href=@{ProjectTicketTreeR shr prj}>View as tree… $# <a href=@{ProjectTicketTreeR shr prj}>View as tree…
<form method=GET action=@{ProjectTicketsR shr prj} enctype=#{filtEnctype}> <form method=GET action=@{DeckTicketsR deckHash} enctype=#{filtEnctype}>
^{filtWidget} ^{filtWidget}
<div class="submit"> <div class="submit">
<input type="submit" value="Filter"> <input type="submit" value="Filter">
@ -27,6 +27,6 @@ $# <http://creativecommons.org/publicdomain/zero/1.0/>.
<div .container> <div .container>
$forall ts <- rows $forall ts <- rows
^{ticketSummaryW shr prj ts Nothing} ^{ticketSummaryW deckHash ts Nothing}
^{pageNav} ^{pageNav}

View file

@ -1,6 +1,6 @@
$# This file is part of Vervis. $# This file is part of Vervis.
$# $#
$# Written in 2016, 2019, 2020 by fr33domlover <fr33domlover@riseup.net>. $# Written in 2016, 2019, 2020, 2022 by fr33domlover <fr33domlover@riseup.net>.
$# $#
$# ♡ Copying is an act of love. Please copy, reuse and share. $# ♡ Copying is an act of love. Please copy, reuse and share.
$# $#
@ -32,7 +32,7 @@ $# <http://creativecommons.org/publicdomain/zero/1.0/>.
#{showDate $ tsCreatedAt ts} #{showDate $ tsCreatedAt ts}
<span .ticket-sharer-column> <span .ticket-sharer-column>
^{sharerLinkFedW $ first fst $ tsCreatedBy ts} ^{personLinkFedW $ tsCreatedBy ts}
<span .ticket-title-column> <span .ticket-title-column>
<a href=@{ticketRoute ts}> <a href=@{ticketRoute ts}>
@ -52,11 +52,11 @@ $# <http://creativecommons.org/publicdomain/zero/1.0/>.
$maybe params <- mparams $maybe params <- mparams
<span .ticket-node-column> <span .ticket-node-column>
<a href="#node-#{keyHashidText $ encodeLT $ tsId ts}" title="Jump to subtree"> <a href="#node-#{keyHashidText $ hashTicket $ tsId ts}" title="Jump to subtree">
$maybe route <- mroute $maybe route <- mroute
<a href=@?{(route, params)} title="Move subtree here"> <a href=@?{(route, params)} title="Move subtree here">
$nothing $nothing
<span .ticket-node-column> <span .ticket-node-column>
<a id="node-#{keyHashidText $ encodeLT $ tsId ts}"> <a id="node-#{keyHashidText $ hashTicket $ tsId ts}">

View file

@ -166,7 +166,7 @@ library
Vervis.Form.Project Vervis.Form.Project
Vervis.Form.Repo Vervis.Form.Repo
--Vervis.Form.Role --Vervis.Form.Role
--Vervis.Form.Ticket Vervis.Form.Ticket
-- Vervis.Form.Workflow -- Vervis.Form.Workflow
Vervis.Formatting Vervis.Formatting
Vervis.Foundation Vervis.Foundation
@ -236,7 +236,7 @@ library
--Vervis.Widget.Project --Vervis.Widget.Project
Vervis.Widget.Repo Vervis.Widget.Repo
--Vervis.Widget.Role --Vervis.Widget.Role
--Vervis.Widget.Ticket Vervis.Widget.Ticket
-- Vervis.Widget.Workflow -- Vervis.Widget.Workflow
-- Vervis.Wiki -- Vervis.Wiki
Vervis.WorkItem Vervis.WorkItem