UI, AP: Display project and team children and parents

This commit is contained in:
Pere Lev 2023-12-12 23:21:06 +02:00
parent 1f06d689f5
commit 802df6b15b
No known key found for this signature in database
GPG key ID: 5252C5C863E5E57D
11 changed files with 584 additions and 18 deletions

View file

@ -161,6 +161,8 @@ type ProjectKeyHashid = KeyHashid Project
type CollabEnableKeyHashid = KeyHashid CollabEnable type CollabEnableKeyHashid = KeyHashid CollabEnable
type StemKeyHashid = KeyHashid Stem type StemKeyHashid = KeyHashid Stem
type PermitFulfillsInviteKeyHashid = KeyHashid PermitFulfillsInvite type PermitFulfillsInviteKeyHashid = KeyHashid PermitFulfillsInvite
type DestThemSendDelegatorLocalKeyHashid = KeyHashid DestThemSendDelegatorLocal
type DestThemSendDelegatorRemoteKeyHashid = KeyHashid DestThemSendDelegatorRemote
-- This is where we define all of the routes in our application. For a full -- This is where we define all of the routes in our application. For a full
-- explanation of the syntax, please see: -- explanation of the syntax, please see:
@ -890,6 +892,11 @@ instance YesodBreadcrumbs App where
GroupInviteR g -> ("Invite", Just $ GroupR g) GroupInviteR g -> ("Invite", Just $ GroupR g)
GroupRemoveR _ _ -> ("", Nothing) GroupRemoveR _ _ -> ("", Nothing)
GroupChildrenR j -> ("Child teams", Just $ GroupR j)
GroupChildLocalLiveR j d -> ("Local " <> keyHashidText d, Just $ GroupChildrenR j)
GroupChildRemoteLiveR j d -> ("Remote " <> keyHashidText d, Just $ GroupChildrenR j)
GroupParentsR j -> ("Parent teams", Just $ GroupR j)
RepoR r -> ("Repo ^" <> keyHashidText r, Just HomeR) RepoR r -> ("Repo ^" <> keyHashidText r, Just HomeR)
RepoInboxR r -> ("Inbox", Just $ RepoR r) RepoInboxR r -> ("Inbox", Just $ RepoR r)
RepoOutboxR r -> ("Outbox", Just $ RepoR r) RepoOutboxR r -> ("Outbox", Just $ RepoR r)
@ -1025,3 +1032,8 @@ instance YesodBreadcrumbs App where
ProjectCollabLiveR j c -> (keyHashidText c, Just $ ProjectCollabsR j) ProjectCollabLiveR j c -> (keyHashidText c, Just $ ProjectCollabsR j)
ProjectInviteCompR d -> ("Invite", Just $ ProjectComponentsR d) ProjectInviteCompR d -> ("Invite", Just $ ProjectComponentsR d)
ProjectChildrenR j -> ("Child projects", Just $ ProjectR j)
ProjectParentsR j -> ("Parent projects", Just $ ProjectR j)
ProjectParentLocalLiveR j d -> ("Local " <> keyHashidText d, Just $ ProjectParentsR j)
ProjectParentRemoteLiveR j d -> ("Remote " <> keyHashidText d, Just $ ProjectParentsR j)

View file

@ -32,6 +32,10 @@ module Vervis.Handler.Group
, postGroupInviteR , postGroupInviteR
, postGroupRemoveR , postGroupRemoveR
, getGroupChildrenR
, getGroupChildLocalLiveR
, getGroupChildRemoteLiveR
, getGroupParentsR
@ -58,12 +62,14 @@ import Data.Bitraversable
import Data.ByteString (ByteString) import Data.ByteString (ByteString)
import Data.Default.Class import Data.Default.Class
import Data.Foldable import Data.Foldable
import Data.List
import Data.Maybe (fromMaybe) import Data.Maybe (fromMaybe)
import Data.Text (Text) import Data.Text (Text)
import Data.Time.Clock import Data.Time.Clock
import Data.Traversable import Data.Traversable
import Database.Persist import Database.Persist
import Network.HTTP.Types.Method import Network.HTTP.Types.Method
import Optics.Core
import Text.Blaze.Html (Html) import Text.Blaze.Html (Html)
import Yesod.Auth (requireAuth) import Yesod.Auth (requireAuth)
import Yesod.Core import Yesod.Core
@ -383,6 +389,217 @@ postGroupRemoveR groupHash ctID = do
setMessage "Remove sent" setMessage "Remove sent"
redirect $ GroupMembersR groupHash redirect $ GroupMembersR groupHash
getGroupChildrenR :: KeyHashid Group -> Handler TypedContent
getGroupChildrenR groupHash = do
groupID <- decodeKeyHashid404 groupHash
(actor, group, children) <- runDB $ do
group <- get404 groupID
actor <- getJust $ groupActor group
children <- getChildren groupID
return (actor, group, children)
encodeRouteLocal <- getEncodeRouteLocal
encodeRouteHome <- getEncodeRouteHome
hashGroup <- getEncodeKeyHashid
h <- asksSite siteInstanceHost
let makeId (Left (childID, _)) =
encodeRouteHome $ GroupR $ hashGroup childID
makeId (Right (i, ro, _)) =
ObjURI (instanceHost i) (remoteObjectIdent ro)
makeItem (role, time, i) = AP.Relationship
{ AP.relationshipId = Nothing
, AP.relationshipExtraTypes = []
, AP.relationshipSubject = encodeRouteHome $ GroupR groupHash
, AP.relationshipProperty = Left AP.RelHasChild
, AP.relationshipObject = makeId i
, AP.relationshipAttributedTo = encodeRouteLocal $ GroupR groupHash
, AP.relationshipPublished = Just time
, AP.relationshipUpdated = Nothing
, AP.relationshipInstrument = Just role
}
childrenAP = Collection
{ collectionId = encodeRouteLocal $ GroupChildrenR groupHash
, collectionType = CollectionTypeUnordered
, collectionTotalItems = Just $ length children
, collectionCurrent = Nothing
, collectionFirst = Nothing
, collectionLast = Nothing
, collectionItems = map (Doc h . makeItem) children
, collectionContext =
Just $ encodeRouteLocal $ GroupR groupHash
}
provideHtmlAndAP childrenAP $ getHtml groupID group actor children
where
getChildren groupID = fmap (sortOn $ view _2) $ liftA2 (++)
(map (\ (E.Value role, E.Value time, E.Value child, Entity _ actor) ->
(role, time, Left (child, actor))
)
<$> getLocals groupID
)
(map (\ (E.Value role, E.Value time, Entity _ i, Entity _ ro, Entity _ ra) ->
(role, time, Right (i, ro, ra))
)
<$> getRemotes groupID
)
getLocals groupID =
E.select $ E.from $ \ (dest `E.InnerJoin` holder `E.InnerJoin` topic `E.InnerJoin` group `E.InnerJoin` actor `E.InnerJoin` accept `E.InnerJoin` deleg `E.InnerJoin` grant) -> do
E.on $ deleg E.^. DestThemSendDelegatorLocalGrant E.==. grant E.^. OutboxItemId
E.on $ accept E.^. DestUsAcceptId E.==. deleg E.^. DestThemSendDelegatorLocalDest
E.on $ dest E.^. DestId E.==. accept E.^. DestUsAcceptDest
E.on $ group E.^. GroupActor E.==. actor E.^. ActorId
E.on $ topic E.^. DestTopicGroupChild E.==. group E.^. GroupId
E.on $ holder E.^. DestHolderGroupId E.==. topic E.^. DestTopicGroupHolder
E.on $ dest E.^. DestId E.==. holder E.^. DestHolderGroupDest
E.where_ $ holder E.^. DestHolderGroupGroup E.==. E.val groupID
E.orderBy [E.asc $ grant E.^. OutboxItemPublished]
return
( dest E.^. DestRole
, grant E.^. OutboxItemPublished
, topic E.^. DestTopicGroupChild
, actor
)
getRemotes groupID =
E.select $ E.from $ \ (dest `E.InnerJoin` holder `E.InnerJoin` topic `E.InnerJoin` accept `E.InnerJoin` deleg `E.InnerJoin` grant `E.InnerJoin` ra `E.InnerJoin` ro `E.InnerJoin` i) -> do
E.on $ ro E.^. RemoteObjectInstance E.==. i E.^. InstanceId
E.on $ ra E.^. RemoteActorIdent E.==. ro E.^. RemoteObjectId
E.on $ topic E.^. DestTopicRemoteTopic E.==. ra E.^. RemoteActorId
E.on $ deleg E.^. DestThemSendDelegatorRemoteGrant E.==. grant E.^. RemoteActivityId
E.on $ accept E.^. DestUsAcceptId E.==. deleg E.^. DestThemSendDelegatorRemoteDest
E.on $ dest E.^. DestId E.==. accept E.^. DestUsAcceptDest
E.on $ dest E.^. DestId E.==. topic E.^. DestTopicRemoteDest
E.on $ dest E.^. DestId E.==. holder E.^. DestHolderGroupDest
E.where_ $ holder E.^. DestHolderGroupGroup E.==. E.val groupID
E.orderBy [E.asc $ grant E.^. RemoteActivityReceived]
return
( dest E.^. DestRole
, grant E.^. RemoteActivityReceived
, i
, ro
, ra
)
getHtml groupID group actor children = do
$(widgetFile "group/children")
getGroupChildLocalLiveR :: KeyHashid Group -> KeyHashid DestThemSendDelegatorLocal -> Handler ()
getGroupChildLocalLiveR groupHash delegHash = do
groupID <- decodeKeyHashid404 groupHash
delegID <- decodeKeyHashid404 delegHash
runDB $ do
_ <- get404 groupID
DestThemSendDelegatorLocal _ localID _ <- get404 delegID
DestTopicLocal destID <- getJust localID
Entity _ (DestHolderGroup _ g) <-
getBy404 $ UniqueDestHolderGroup destID
unless (g == groupID) notFound
getGroupChildRemoteLiveR :: KeyHashid Group -> KeyHashid DestThemSendDelegatorRemote -> Handler ()
getGroupChildRemoteLiveR groupHash delegHash = do
groupID <- decodeKeyHashid404 groupHash
delegID <- decodeKeyHashid404 delegHash
runDB $ do
_ <- get404 groupID
DestThemSendDelegatorRemote _ remoteID _ <- get404 delegID
DestTopicRemote destID _ <- getJust remoteID
Entity _ (DestHolderGroup _ g) <-
getBy404 $ UniqueDestHolderGroup destID
unless (g == groupID) notFound
getGroupParentsR :: KeyHashid Group -> Handler TypedContent
getGroupParentsR groupHash = do
groupID <- decodeKeyHashid404 groupHash
(actor, group, parents) <- runDB $ do
group <- get404 groupID
actor <- getJust $ groupActor group
parents <- getParents groupID
return (actor, group, parents)
encodeRouteHome <- getEncodeRouteHome
encodeRouteLocal <- getEncodeRouteLocal
hashGroup <- getEncodeKeyHashid
h <- asksSite siteInstanceHost
let makeId (Left (parentID, _)) =
encodeRouteHome $ GroupR $ hashGroup parentID
makeId (Right (i, ro, _)) =
ObjURI (instanceHost i) (remoteObjectIdent ro)
makeItem (role, time, i) = AP.Relationship
{ AP.relationshipId = Nothing
, AP.relationshipExtraTypes = []
, AP.relationshipSubject = encodeRouteHome $ GroupR groupHash
, AP.relationshipProperty = Left AP.RelHasParent
, AP.relationshipObject = makeId i
, AP.relationshipAttributedTo = encodeRouteLocal $ GroupR groupHash
, AP.relationshipPublished = Just time
, AP.relationshipUpdated = Nothing
, AP.relationshipInstrument = Just role
}
parentsAP = Collection
{ collectionId = encodeRouteLocal $ GroupParentsR groupHash
, collectionType = CollectionTypeUnordered
, collectionTotalItems = Just $ length parents
, collectionCurrent = Nothing
, collectionFirst = Nothing
, collectionLast = Nothing
, collectionItems = map (Doc h . makeItem) parents
, collectionContext =
Just $ encodeRouteLocal $ GroupR groupHash
}
provideHtmlAndAP parentsAP $ getHtml groupID group actor parents
where
getParents groupID = fmap (sortOn $ view _2) $ liftA2 (++)
(map (\ (E.Value role, E.Value time, E.Value parent, Entity _ actor) ->
(role, time, Left (parent, actor))
)
<$> getLocals groupID
)
(map (\ (E.Value role, E.Value time, Entity _ i, Entity _ ro, Entity _ ra) ->
(role, time, Right (i, ro, ra))
)
<$> getRemotes groupID
)
getLocals groupID =
E.select $ E.from $ \ (source `E.InnerJoin` holder `E.InnerJoin` topic `E.InnerJoin` group `E.InnerJoin` actor `E.InnerJoin` deleg `E.InnerJoin` grant) -> do
E.on $ deleg E.^. SourceUsSendDelegatorGrant E.==. grant E.^. OutboxItemId
E.on $ source E.^. SourceId E.==. deleg E.^. SourceUsSendDelegatorSource
E.on $ group E.^. GroupActor E.==. actor E.^. ActorId
E.on $ topic E.^. SourceTopicGroupParent E.==. group E.^. GroupId
E.on $ holder E.^. SourceHolderGroupId E.==. topic E.^. SourceTopicGroupHolder
E.on $ source E.^. SourceId E.==. holder E.^. SourceHolderGroupSource
E.where_ $ holder E.^. SourceHolderGroupGroup E.==. E.val groupID
E.orderBy [E.asc $ deleg E.^. SourceUsSendDelegatorId]
return
( source E.^. SourceRole
, grant E.^. OutboxItemPublished
, topic E.^. SourceTopicGroupParent
, actor
)
getRemotes groupID =
E.select $ E.from $ \ (source `E.InnerJoin` holder `E.InnerJoin` topic `E.InnerJoin` deleg `E.InnerJoin` grant `E.InnerJoin` ra `E.InnerJoin` ro `E.InnerJoin` i) -> do
E.on $ ro E.^. RemoteObjectInstance E.==. i E.^. InstanceId
E.on $ ra E.^. RemoteActorIdent E.==. ro E.^. RemoteObjectId
E.on $ topic E.^. SourceTopicRemoteTopic E.==. ra E.^. RemoteActorId
E.on $ deleg E.^. SourceUsSendDelegatorGrant E.==. grant E.^. OutboxItemId
E.on $ source E.^. SourceId E.==. deleg E.^. SourceUsSendDelegatorSource
E.on $ source E.^. SourceId E.==. topic E.^. SourceTopicRemoteSource
E.on $ source E.^. SourceId E.==. holder E.^. SourceHolderGroupSource
E.where_ $ holder E.^. SourceHolderGroupGroup E.==. E.val groupID
E.orderBy [E.asc $ deleg E.^. SourceUsSendDelegatorId]
return
( source E.^. SourceRole
, grant E.^. OutboxItemPublished
, i
, ro
, ra
)
getHtml groupID group actor parents = do
$(widgetFile "group/parents")

View file

@ -38,6 +38,11 @@ module Vervis.Handler.Project
, getProjectInviteCompR , getProjectInviteCompR
, postProjectInviteCompR , postProjectInviteCompR
, getProjectChildrenR
, getProjectParentsR
, getProjectParentLocalLiveR
, getProjectParentRemoteLiveR
) )
where where
@ -51,12 +56,14 @@ import Data.Bitraversable
import Data.ByteString (ByteString) import Data.ByteString (ByteString)
import Data.Default.Class import Data.Default.Class
import Data.Foldable import Data.Foldable
import Data.List
import Data.Maybe (fromMaybe) import Data.Maybe (fromMaybe)
import Data.Text (Text) import Data.Text (Text)
import Data.Time.Clock import Data.Time.Clock
import Data.Traversable import Data.Traversable
import Database.Persist import Database.Persist
import Network.HTTP.Types.Method import Network.HTTP.Types.Method
import Optics.Core
import Text.Blaze.Html (Html) import Text.Blaze.Html (Html)
import Yesod.Auth (requireAuth) import Yesod.Auth (requireAuth)
import Yesod.Core import Yesod.Core
@ -563,3 +570,215 @@ postProjectInviteCompR projectHash = do
Right inviteID -> do Right inviteID -> do
setMessage "Invite sent" setMessage "Invite sent"
redirect $ ProjectComponentsR projectHash redirect $ ProjectComponentsR projectHash
getProjectChildrenR :: KeyHashid Project -> Handler TypedContent
getProjectChildrenR projectHash = do
projectID <- decodeKeyHashid404 projectHash
(actor, project, children) <- runDB $ do
project <- get404 projectID
actor <- getJust $ projectActor project
children <- getChildren projectID
return (actor, project, children)
encodeRouteHome <- getEncodeRouteHome
encodeRouteLocal <- getEncodeRouteLocal
hashProject <- getEncodeKeyHashid
h <- asksSite siteInstanceHost
let makeId (Left (childID, _)) =
encodeRouteHome $ ProjectR $ hashProject childID
makeId (Right (i, ro, _)) =
ObjURI (instanceHost i) (remoteObjectIdent ro)
makeItem (role, time, i) = AP.Relationship
{ AP.relationshipId = Nothing
, AP.relationshipExtraTypes = []
, AP.relationshipSubject = encodeRouteHome $ ProjectR projectHash
, AP.relationshipProperty = Left AP.RelHasChild
, AP.relationshipObject = makeId i
, AP.relationshipAttributedTo = encodeRouteLocal $ ProjectR projectHash
, AP.relationshipPublished = Just time
, AP.relationshipUpdated = Nothing
, AP.relationshipInstrument = Just role
}
childrenAP = Collection
{ collectionId = encodeRouteLocal $ ProjectChildrenR projectHash
, collectionType = CollectionTypeUnordered
, collectionTotalItems = Just $ length children
, collectionCurrent = Nothing
, collectionFirst = Nothing
, collectionLast = Nothing
, collectionItems = map (Doc h . makeItem) children
, collectionContext =
Just $ encodeRouteLocal $ ProjectR projectHash
}
provideHtmlAndAP childrenAP $ getHtml projectID project actor children
where
getChildren projectID = fmap (sortOn $ view _2) $ liftA2 (++)
(map (\ (E.Value role, E.Value time, E.Value child, Entity _ actor) ->
(role, time, Left (child, actor))
)
<$> getLocals projectID
)
(map (\ (E.Value role, E.Value time, Entity _ i, Entity _ ro, Entity _ ra) ->
(role, time, Right (i, ro, ra))
)
<$> getRemotes projectID
)
getLocals projectID =
E.select $ E.from $ \ (source `E.InnerJoin` holder `E.InnerJoin` topic `E.InnerJoin` project `E.InnerJoin` actor `E.InnerJoin` deleg `E.InnerJoin` grant) -> do
E.on $ deleg E.^. SourceUsSendDelegatorGrant E.==. grant E.^. OutboxItemId
E.on $ source E.^. SourceId E.==. deleg E.^. SourceUsSendDelegatorSource
E.on $ project E.^. ProjectActor E.==. actor E.^. ActorId
E.on $ topic E.^. SourceTopicProjectChild E.==. project E.^. ProjectId
E.on $ holder E.^. SourceHolderProjectId E.==. topic E.^. SourceTopicProjectHolder
E.on $ source E.^. SourceId E.==. holder E.^. SourceHolderProjectSource
E.where_ $ holder E.^. SourceHolderProjectProject E.==. E.val projectID
E.orderBy [E.asc $ deleg E.^. SourceUsSendDelegatorId]
return
( source E.^. SourceRole
, grant E.^. OutboxItemPublished
, topic E.^. SourceTopicProjectChild
, actor
)
getRemotes projectID =
E.select $ E.from $ \ (source `E.InnerJoin` holder `E.InnerJoin` topic `E.InnerJoin` deleg `E.InnerJoin` grant `E.InnerJoin` ra `E.InnerJoin` ro `E.InnerJoin` i) -> do
E.on $ ro E.^. RemoteObjectInstance E.==. i E.^. InstanceId
E.on $ ra E.^. RemoteActorIdent E.==. ro E.^. RemoteObjectId
E.on $ topic E.^. SourceTopicRemoteTopic E.==. ra E.^. RemoteActorId
E.on $ deleg E.^. SourceUsSendDelegatorGrant E.==. grant E.^. OutboxItemId
E.on $ source E.^. SourceId E.==. deleg E.^. SourceUsSendDelegatorSource
E.on $ source E.^. SourceId E.==. topic E.^. SourceTopicRemoteSource
E.on $ source E.^. SourceId E.==. holder E.^. SourceHolderProjectSource
E.where_ $ holder E.^. SourceHolderProjectProject E.==. E.val projectID
E.orderBy [E.asc $ deleg E.^. SourceUsSendDelegatorId]
return
( source E.^. SourceRole
, grant E.^. OutboxItemPublished
, i
, ro
, ra
)
getHtml projectID project actor children = do
$(widgetFile "project/children")
getProjectParentsR :: KeyHashid Project -> Handler TypedContent
getProjectParentsR projectHash = do
projectID <- decodeKeyHashid404 projectHash
(actor, project, parents) <- runDB $ do
project <- get404 projectID
actor <- getJust $ projectActor project
parents <- getParents projectID
return (actor, project, parents)
encodeRouteHome <- getEncodeRouteHome
encodeRouteLocal <- getEncodeRouteLocal
hashProject <- getEncodeKeyHashid
h <- asksSite siteInstanceHost
let makeId (Left (parentID, _)) =
encodeRouteHome $ ProjectR $ hashProject parentID
makeId (Right (i, ro, _)) =
ObjURI (instanceHost i) (remoteObjectIdent ro)
makeItem (role, time, i) = AP.Relationship
{ AP.relationshipId = Nothing
, AP.relationshipExtraTypes = []
, AP.relationshipSubject = encodeRouteHome $ ProjectR projectHash
, AP.relationshipProperty = Left AP.RelHasParent
, AP.relationshipObject = makeId i
, AP.relationshipAttributedTo = encodeRouteLocal $ ProjectR projectHash
, AP.relationshipPublished = Just time
, AP.relationshipUpdated = Nothing
, AP.relationshipInstrument = Just role
}
parentsAP = Collection
{ collectionId = encodeRouteLocal $ ProjectParentsR projectHash
, collectionType = CollectionTypeUnordered
, collectionTotalItems = Just $ length parents
, collectionCurrent = Nothing
, collectionFirst = Nothing
, collectionLast = Nothing
, collectionItems = map (Doc h . makeItem) parents
, collectionContext =
Just $ encodeRouteLocal $ ProjectR projectHash
}
provideHtmlAndAP parentsAP $ getHtml projectID project actor parents
where
getParents projectID = fmap (sortOn $ view _2) $ liftA2 (++)
(map (\ (E.Value role, E.Value time, E.Value parent, Entity _ actor) ->
(role, time, Left (parent, actor))
)
<$> getLocals projectID
)
(map (\ (E.Value role, E.Value time, Entity _ i, Entity _ ro, Entity _ ra) ->
(role, time, Right (i, ro, ra))
)
<$> getRemotes projectID
)
getLocals projectID =
E.select $ E.from $ \ (dest `E.InnerJoin` holder `E.InnerJoin` topic `E.InnerJoin` project `E.InnerJoin` actor `E.InnerJoin` accept `E.InnerJoin` deleg `E.InnerJoin` grant) -> do
E.on $ deleg E.^. DestThemSendDelegatorLocalGrant E.==. grant E.^. OutboxItemId
E.on $ accept E.^. DestUsAcceptId E.==. deleg E.^. DestThemSendDelegatorLocalDest
E.on $ dest E.^. DestId E.==. accept E.^. DestUsAcceptDest
E.on $ project E.^. ProjectActor E.==. actor E.^. ActorId
E.on $ topic E.^. DestTopicProjectParent E.==. project E.^. ProjectId
E.on $ holder E.^. DestHolderProjectId E.==. topic E.^. DestTopicProjectHolder
E.on $ dest E.^. DestId E.==. holder E.^. DestHolderProjectDest
E.where_ $ holder E.^. DestHolderProjectProject E.==. E.val projectID
E.orderBy [E.asc $ grant E.^. OutboxItemPublished]
return
( dest E.^. DestRole
, grant E.^. OutboxItemPublished
, topic E.^. DestTopicProjectParent
, actor
)
getRemotes projectID =
E.select $ E.from $ \ (dest `E.InnerJoin` holder `E.InnerJoin` topic `E.InnerJoin` accept `E.InnerJoin` deleg `E.InnerJoin` grant `E.InnerJoin` ra `E.InnerJoin` ro `E.InnerJoin` i) -> do
E.on $ ro E.^. RemoteObjectInstance E.==. i E.^. InstanceId
E.on $ ra E.^. RemoteActorIdent E.==. ro E.^. RemoteObjectId
E.on $ topic E.^. DestTopicRemoteTopic E.==. ra E.^. RemoteActorId
E.on $ deleg E.^. DestThemSendDelegatorRemoteGrant E.==. grant E.^. RemoteActivityId
E.on $ accept E.^. DestUsAcceptId E.==. deleg E.^. DestThemSendDelegatorRemoteDest
E.on $ dest E.^. DestId E.==. accept E.^. DestUsAcceptDest
E.on $ dest E.^. DestId E.==. topic E.^. DestTopicRemoteDest
E.on $ dest E.^. DestId E.==. holder E.^. DestHolderProjectDest
E.where_ $ holder E.^. DestHolderProjectProject E.==. E.val projectID
E.orderBy [E.asc $ grant E.^. RemoteActivityReceived]
return
( dest E.^. DestRole
, grant E.^. RemoteActivityReceived
, i
, ro
, ra
)
getHtml projectID project actor parents = do
$(widgetFile "project/parents")
getProjectParentLocalLiveR :: KeyHashid Project -> KeyHashid DestThemSendDelegatorLocal -> Handler ()
getProjectParentLocalLiveR projectHash delegHash = do
projectID <- decodeKeyHashid404 projectHash
delegID <- decodeKeyHashid404 delegHash
runDB $ do
_ <- get404 projectID
DestThemSendDelegatorLocal _ localID _ <- get404 delegID
DestTopicLocal destID <- getJust localID
Entity _ (DestHolderProject _ j) <-
getBy404 $ UniqueDestHolderProject destID
unless (j == projectID) notFound
getProjectParentRemoteLiveR :: KeyHashid Project -> KeyHashid DestThemSendDelegatorRemote -> Handler ()
getProjectParentRemoteLiveR projectHash delegHash = do
projectID <- decodeKeyHashid404 projectHash
delegID <- decodeKeyHashid404 delegHash
runDB $ do
_ <- get404 projectID
DestThemSendDelegatorRemote _ remoteID _ <- get404 delegID
DestTopicRemote destID _ <- getJust remoteID
Entity _ (DestHolderProject _ j) <-
getBy404 $ UniqueDestHolderProject destID
unless (j == projectID) notFound

View file

@ -19,11 +19,13 @@ module Vervis.Widget.Tracker
, projectNavW , projectNavW
, componentLinkFedW , componentLinkFedW
, projectLinkFedW , projectLinkFedW
, groupLinkFedW
, actorLinkFedW , actorLinkFedW
, groupNavW , groupNavW
) )
where where
import Data.Bifunctor
import Database.Persist import Database.Persist
import Database.Persist.Types import Database.Persist.Types
import Yesod.Core.Widget import Yesod.Core.Widget
@ -101,22 +103,12 @@ componentLinkFedW (Right (inztance, object, actor)) =
projectLinkFedW projectLinkFedW
:: Either (ProjectId, Actor) (Instance, RemoteObject, RemoteActor) :: Either (ProjectId, Actor) (Instance, RemoteObject, RemoteActor)
-> Widget -> Widget
projectLinkFedW (Left (j, actor)) = do projectLinkFedW = actorLinkFedW . bimap (first LocalActorProject) id
h <- encodeKeyHashid j
[whamlet| groupLinkFedW
<a href=@{ProjectR h}> :: Either (GroupId, Actor) (Instance, RemoteObject, RemoteActor)
\$#{keyHashidText h} #{actorName actor} -> Widget
|] groupLinkFedW = actorLinkFedW . bimap (first LocalActorGroup) id
projectLinkFedW (Right (inztance, object, actor)) =
[whamlet|
<a href="#{renderObjURI uActor}">
$maybe name <- remoteActorName actor
#{name}
$nothing
#{renderAuthority $ instanceHost inztance}#{localUriPath $ remoteObjectIdent object}
|]
where
uActor = ObjURI (instanceHost inztance) (remoteObjectIdent object)
actorLinkW :: LocalActorBy Key -> Actor -> Widget actorLinkW :: LocalActorBy Key -> Actor -> Widget
actorLinkW (LocalActorPerson k) actor = do actorLinkW (LocalActorPerson k) actor = do

View file

@ -1120,7 +1120,7 @@ instance ActivityPub Note where
<> "mediaType" .= ("text/html" :: Text) <> "mediaType" .= ("text/html" :: Text)
data RelationshipProperty = data RelationshipProperty =
RelDependsOn | RelHasCollab | RelHasMember RelDependsOn | RelHasCollab | RelHasMember | RelHasChild | RelHasParent
deriving Eq deriving Eq
instance FromJSON RelationshipProperty where instance FromJSON RelationshipProperty where
@ -1130,6 +1130,8 @@ instance FromJSON RelationshipProperty where
| t == "dependsOn" = pure RelDependsOn | t == "dependsOn" = pure RelDependsOn
| t == "hasCollaborator" = pure RelHasCollab | t == "hasCollaborator" = pure RelHasCollab
| t == "hasMember" = pure RelHasMember | t == "hasMember" = pure RelHasMember
| t == "hasChild" = pure RelHasChild
| t == "hasParent" = pure RelHasParent
| otherwise = fail $ "Unrecognized relationship: " ++ T.unpack t | otherwise = fail $ "Unrecognized relationship: " ++ T.unpack t
instance ToJSON RelationshipProperty where instance ToJSON RelationshipProperty where
@ -1139,6 +1141,8 @@ instance ToJSON RelationshipProperty where
RelDependsOn -> "dependsOn" :: Text RelDependsOn -> "dependsOn" :: Text
RelHasCollab -> "hasCollaborator" RelHasCollab -> "hasCollaborator"
RelHasMember -> "hasMember" RelHasMember -> "hasMember"
RelHasChild -> "hasChild"
RelHasParent -> "hasParent"
data Relationship u = Relationship data Relationship u = Relationship
{ relationshipId :: Maybe (ObjURI u) { relationshipId :: Maybe (ObjURI u)

View file

@ -0,0 +1,28 @@
$# This file is part of Vervis.
$#
$# Written in 2016, 2019, 2022, 2023 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/>.
^{groupNavW (Entity groupID group) actor}
<h2>Children
<table>
<tr>
<th>Role
<th>Since
<th>Child
$forall (role, since, child) <- children
<tr>
<td>#{show role}
<td>#{showDate since}
<td>^{groupLinkFedW child}

View file

@ -0,0 +1,28 @@
$# This file is part of Vervis.
$#
$# Written in 2016, 2019, 2022, 2023 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/>.
^{groupNavW (Entity groupID group) actor}
<h2>Parents
<table>
<tr>
<th>Role
<th>Since
<th>Child
$forall (role, since, parent) <- parents
<tr>
<td>#{show role}
<td>#{showDate since}
<td>^{groupLinkFedW parent}

View file

@ -0,0 +1,28 @@
$# This file is part of Vervis.
$#
$# Written in 2016, 2019, 2022, 2023 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/>.
^{projectNavW (Entity projectID project) actor}
<h2>Children
<table>
<tr>
<th>Role
<th>Since
<th>Child
$forall (role, since, child) <- children
<tr>
<td>#{show role}
<td>#{showDate since}
<td>^{projectLinkFedW child}

View file

@ -0,0 +1,28 @@
$# This file is part of Vervis.
$#
$# Written in 2016, 2019, 2022, 2023 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/>.
^{projectNavW (Entity projectID project) actor}
<h2>Parents
<table>
<tr>
<th>Role
<th>Since
<th>Child
$forall (role, since, parent) <- parents
<tr>
<td>#{show role}
<td>#{showDate since}
<td>^{projectLinkFedW parent}

View file

@ -1405,7 +1405,7 @@ SourceThemAcceptRemote
-------------------------------- Source enable ------------------------------- -------------------------------- Source enable -------------------------------
-- Witnesses that, seeing their approval and our collaborator's gesture, I've -- Witnesses that, seeing their approval and our collaborator's gesture, I've
-- sent then a delegator-Grant and now officially considering them a source of -- sent them a delegator-Grant and now officially considering them a source of
-- us -- us
SourceUsSendDelegator SourceUsSendDelegator
source SourceId source SourceId

View file

@ -174,6 +174,11 @@
/groups/#GroupKeyHashid/invite GroupInviteR GET POST /groups/#GroupKeyHashid/invite GroupInviteR GET POST
/groups/#GroupKeyHashid/remove/#CollabTopicGroupId GroupRemoveR POST /groups/#GroupKeyHashid/remove/#CollabTopicGroupId GroupRemoveR POST
/groups/#GroupKeyHashid/children GroupChildrenR GET
/groups/#GroupKeyHashid/children/local/#DestThemSendDelegatorLocalKeyHashid/live GroupChildLocalLiveR GET
/groups/#GroupKeyHashid/children/remote/#DestThemSendDelegatorRemoteKeyHashid/live GroupChildRemoteLiveR GET
/groups/#GroupKeyHashid/parents GroupParentsR GET
---- Repo -------------------------------------------------------------------- ---- Repo --------------------------------------------------------------------
/repos/#RepoKeyHashid RepoR GET /repos/#RepoKeyHashid RepoR GET
@ -343,3 +348,8 @@
/projects/#ProjectKeyHashid/collabs/#CollabEnableKeyHashid/live ProjectCollabLiveR GET /projects/#ProjectKeyHashid/collabs/#CollabEnableKeyHashid/live ProjectCollabLiveR GET
/projects/#ProjectKeyHashid/invite-component ProjectInviteCompR GET POST /projects/#ProjectKeyHashid/invite-component ProjectInviteCompR GET POST
/projects/#ProjectKeyHashid/children ProjectChildrenR GET
/projects/#ProjectKeyHashid/parents ProjectParentsR GET
/projects/#ProjectKeyHashid/parents/local/#DestThemSendDelegatorLocalKeyHashid/live ProjectParentLocalLiveR GET
/projects/#ProjectKeyHashid/parents/remote/#DestThemSendDelegatorRemoteKeyHashid/live ProjectParentRemoteLiveR GET