[graphql] add node_children to graphql

Also, fixed breadcrumbs to accept AppRoute.
parent 6e07f6c5
Pipeline #5895 passed with stages
in 129 minutes and 43 seconds
...@@ -70,6 +70,7 @@ data Query m ...@@ -70,6 +70,7 @@ data Query m
, languages :: m [GQLNLP.LanguageTuple] , languages :: m [GQLNLP.LanguageTuple]
, nodes :: GQLNode.NodeArgs -> m [GQLNode.Node] , nodes :: GQLNode.NodeArgs -> m [GQLNode.Node]
, nodes_corpus :: GQLNode.CorpusArgs -> m [GQLNode.Corpus] , nodes_corpus :: GQLNode.CorpusArgs -> m [GQLNode.Corpus]
, node_children :: GQLNode.NodeChildrenArgs -> m [GQLNode.Node]
, node_parent :: GQLNode.NodeParentArgs -> m [GQLNode.Node] , node_parent :: GQLNode.NodeParentArgs -> m [GQLNode.Node]
, user_infos :: GQLUserInfo.UserInfoArgs -> m [GQLUserInfo.UserInfo] , user_infos :: GQLUserInfo.UserInfoArgs -> m [GQLUserInfo.UserInfo]
, users :: GQLUser.UserArgs -> m [GQLUser.User m] , users :: GQLUser.UserArgs -> m [GQLUser.User m]
...@@ -121,6 +122,7 @@ rootResolver authenticatedUser policyManager = ...@@ -121,6 +122,7 @@ rootResolver authenticatedUser policyManager =
, languages = GQLNLP.resolveLanguages , languages = GQLNLP.resolveLanguages
, nodes = GQLNode.resolveNodes authenticatedUser policyManager , nodes = GQLNode.resolveNodes authenticatedUser policyManager
, nodes_corpus = GQLNode.resolveNodesCorpus , nodes_corpus = GQLNode.resolveNodesCorpus
, node_children = GQLNode.resolveNodeChildren
, node_parent = GQLNode.resolveNodeParent , node_parent = GQLNode.resolveNodeParent
, user_infos = GQLUserInfo.resolveUserInfos authenticatedUser policyManager , user_infos = GQLUserInfo.resolveUserInfos authenticatedUser policyManager
, users = GQLUser.resolveUsers authenticatedUser policyManager , users = GQLUser.resolveUsers authenticatedUser policyManager
......
...@@ -14,22 +14,20 @@ Portability : POSIX ...@@ -14,22 +14,20 @@ Portability : POSIX
module Gargantext.API.GraphQL.Node where module Gargantext.API.GraphQL.Node where
import Data.Aeson import Data.Aeson ( fromJSON, Result(..), Value(..) )
import Data.Aeson.KeyMap qualified as KM import Data.Aeson.KeyMap qualified as KM
import Data.Morpheus.Types ( GQLType ) import Data.Morpheus.Types ( GQLType )
import Data.Text qualified as T import Gargantext.API.Admin.Auth.Types ( AuthenticatedUser )
import Gargantext.API.Admin.Auth.Types import Gargantext.API.Auth.PolicyCheck ( nodeChecks, AccessPolicyManager )
import Gargantext.API.Auth.PolicyCheck
import Gargantext.API.GraphQL.PolicyCheck (withPolicy) import Gargantext.API.GraphQL.PolicyCheck (withPolicy)
import Gargantext.API.GraphQL.Types import Gargantext.API.GraphQL.Types ( GqlM )
import Gargantext.Database.Admin.Types.Node (NodeType) import Gargantext.Database.Admin.Types.Node (NodeType)
import Gargantext.Database.Admin.Types.Node qualified as NN import Gargantext.Database.Admin.Types.Node qualified as NN
import Gargantext.Database.Prelude (CmdCommon) -- , JSONB) import Gargantext.Database.Prelude (CmdCommon) -- , JSONB)
import Gargantext.Database.Query.Table.Node (getClosestParentIdByType, getNode) import Gargantext.Database.Query.Table.Node (getClosestChildrenByType, getClosestParentIdByType, getNode)
import Gargantext.Database.Schema.Node qualified as N import Gargantext.Database.Schema.Node qualified as N
import Gargantext.Prelude import Gargantext.Prelude
import PUBMED.Types qualified as PUBMED import PUBMED.Types qualified as PUBMED
import Prelude qualified
data Corpus = Corpus data Corpus = Corpus
{ id :: Int { id :: Int
...@@ -87,7 +85,13 @@ dbNodesCorpus corpus_id = do ...@@ -87,7 +85,13 @@ dbNodesCorpus corpus_id = do
data NodeParentArgs data NodeParentArgs
= NodeParentArgs = NodeParentArgs
{ node_id :: Int { node_id :: Int
, parent_type :: Text , parent_type :: NodeType
} deriving (Generic, GQLType)
data NodeChildrenArgs
= NodeChildrenArgs
{ node_id :: Int
, child_type :: NodeType
} deriving (Generic, GQLType) } deriving (Generic, GQLType)
resolveNodeParent resolveNodeParent
...@@ -95,16 +99,21 @@ resolveNodeParent ...@@ -95,16 +99,21 @@ resolveNodeParent
=> NodeParentArgs -> GqlM e env [Node] => NodeParentArgs -> GqlM e env [Node]
resolveNodeParent NodeParentArgs { node_id, parent_type } = dbParentNodes node_id parent_type resolveNodeParent NodeParentArgs { node_id, parent_type } = dbParentNodes node_id parent_type
resolveNodeChildren
:: (CmdCommon env)
=> NodeChildrenArgs -> GqlM e env [Node]
resolveNodeChildren NodeChildrenArgs { node_id, child_type } = dbChildNodes node_id child_type
dbParentNodes dbParentNodes
:: (CmdCommon env) :: (CmdCommon env)
=> Int -> Text -> GqlM e env [Node] => Int -> NodeType -> GqlM e env [Node]
dbParentNodes node_id parent_type = do dbParentNodes node_id parentType = do
let mParentType = readEither (T.unpack parent_type) :: Either Prelude.String NodeType -- let mParentType = readEither (T.unpack parent_type) :: Either Prelude.String NodeType
case mParentType of -- case mParentType of
Left err -> do -- Left err -> do
lift $ printDebug "[dbParentNodes] error reading parent type" (T.pack err) -- lift $ printDebug "[dbParentNodes] error reading parent type" (T.pack err)
pure [] -- pure []
Right parentType -> do -- Right parentType -> do
mNodeId <- lift $ getClosestParentIdByType (NN.UnsafeMkNodeId node_id) parentType -- (fromNodeTypeId parent_type_id) mNodeId <- lift $ getClosestParentIdByType (NN.UnsafeMkNodeId node_id) parentType -- (fromNodeTypeId parent_type_id)
case mNodeId of case mNodeId of
Nothing -> pure [] Nothing -> pure []
...@@ -112,6 +121,20 @@ dbParentNodes node_id parent_type = do ...@@ -112,6 +121,20 @@ dbParentNodes node_id parent_type = do
node <- lift $ getNode id node <- lift $ getNode id
pure [toNode node] pure [toNode node]
dbChildNodes
:: (CmdCommon env)
=> Int -> NodeType -> GqlM e env [Node]
dbChildNodes node_id childType = do
-- let mChildType = readEither (T.unpack child_type) :: Either Prelude.String NodeType
-- case mChildType of
-- Left err -> do
-- lift $ printDebug "[dbChildNodes] error reading parent type" (T.pack err)
-- pure []
-- Right childType -> do
childIds <- lift $ getClosestChildrenByType (NN.UnsafeMkNodeId node_id) childType -- (fromNodeTypeId parent_type_id)
children <- lift $ mapM getNode childIds
pure $ toNode <$> children
toNode :: NN.Node json -> Node toNode :: NN.Node json -> Node
toNode N.Node { .. } = Node { id = NN.unNodeId _node_id toNode N.Node { .. } = Node { id = NN.unNodeId _node_id
, name = _node_name , name = _node_name
......
...@@ -3,11 +3,11 @@ module Gargantext.API.GraphQL.PolicyCheck where ...@@ -3,11 +3,11 @@ module Gargantext.API.GraphQL.PolicyCheck where
import Prelude import Prelude
import Control.Monad.Except import Control.Monad.Except (MonadError(..), MonadTrans(..))
import Gargantext.API.Admin.Auth.Types import Gargantext.API.Admin.Auth.Types ( AuthenticatedUser )
import Gargantext.API.Auth.PolicyCheck import Gargantext.API.Auth.PolicyCheck ( BoolExpr, AccessCheck, AccessPolicyManager(..), AccessResult(..))
import Gargantext.API.Errors.Types import Gargantext.API.Errors.Types ( BackendInternalError(..) )
import Gargantext.API.GraphQL.Types import Gargantext.API.GraphQL.Types (GqlM)
import Gargantext.Database.Prelude (HasConnectionPool, HasConfig) import Gargantext.Database.Prelude (HasConnectionPool, HasConfig)
withPolicy :: (HasConnectionPool env, HasConfig env) withPolicy :: (HasConnectionPool env, HasConfig env)
......
...@@ -15,18 +15,18 @@ Portability : POSIX ...@@ -15,18 +15,18 @@ Portability : POSIX
module Gargantext.API.GraphQL.TreeFirstLevel where module Gargantext.API.GraphQL.TreeFirstLevel where
import Data.Morpheus.Types (GQLType) import Data.Morpheus.Types (GQLType)
import Gargantext.API.Admin.Auth.Types import Gargantext.API.Admin.Auth.Types ( AuthenticatedUser )
import Gargantext.API.Auth.PolicyCheck import Gargantext.API.Auth.PolicyCheck (AccessPolicyManager, nodeChecks)
import Gargantext.API.GraphQL.PolicyCheck import Gargantext.API.GraphQL.PolicyCheck (withPolicy)
import Gargantext.API.GraphQL.Types import Gargantext.API.GraphQL.Types ( GqlM )
import Gargantext.Core (fromDBid) import Gargantext.Core (fromDBid)
import Gargantext.Core.Types (Tree, NodeTree, NodeType) -- import Gargantext.Core.Types (ContextId, CorpusId, ListId)
import Gargantext.Core.Types.Main ( Tree(TreeN), _tn_node, _tn_children, NodeTree(NodeTree, _nt_id, _nt_type), _nt_name ) import Gargantext.Core.Types.Main ( Tree(..), _tn_node, _tn_children, NodeTree(..), _nt_name )
import Gargantext.Database.Admin.Config () import Gargantext.Database.Admin.Config ()
import Gargantext.Database.Admin.Types.Node (allNodeTypes, NodeId (UnsafeMkNodeId)) import Gargantext.Database.Admin.Types.Node (allNodeTypes, NodeId(..), NodeType)
import Gargantext.Database.Admin.Types.Node qualified as NN import Gargantext.Database.Admin.Types.Node qualified as NN
import Gargantext.Database.Prelude (CmdCommon) import Gargantext.Database.Prelude (CmdCommon)
import Gargantext.Database.Query.Table.Node (getNode) import Gargantext.Database.Query.Table.Node (getNode, getChildrenByType, getClosestParentIdByType)
import Gargantext.Database.Query.Tree qualified as T import Gargantext.Database.Query.Tree qualified as T
import Gargantext.Database.Schema.Node (NodePoly(_node_parent_id)) import Gargantext.Database.Schema.Node (NodePoly(_node_parent_id))
import Gargantext.Database.Schema.Node qualified as N import Gargantext.Database.Schema.Node qualified as N
...@@ -52,9 +52,45 @@ data TreeFirstLevel m = TreeFirstLevel ...@@ -52,9 +52,45 @@ data TreeFirstLevel m = TreeFirstLevel
, children :: [TreeNode] , children :: [TreeNode]
} deriving (Generic, GQLType) } deriving (Generic, GQLType)
data AppRoute =
AnnuaireRoute { nodeId :: Int }
| ContactPageRoute { annuaireId :: Int
, nodeId :: Int }
| CorpusRoute { nodeId :: Int }
| CorpusCodeRoute { nodeId :: Int }
| CorpusDocumentRoute { corpusId :: Int
, documentId :: Int
, listId :: Int }
| DashboardRoute { nodeId :: Int }
| DocumentRoute { documentId :: Int
, listId :: Int }
| FolderRoute { nodeId :: Int }
| FolderPrivateRoute { nodeId :: Int }
| FolderPublicRoute { nodeId :: Int }
| FolderSharedRoute { nodeId :: Int }
| ListsRoute { nodeId :: Int }
| NodeTextsRoute { nodeId :: Int }
| PGraphExplorerRoute { nodeId :: Int }
| PhyloExplorerRoute { nodeId :: Int }
| RouteFileRoute { nodeId :: Int }
| RouteFrameCalcRoute { nodeId :: Int }
| RouteFrameCodeRoute { nodeId :: Int }
| RouteFrameVisioRoute { nodeId :: Int }
| RouteFrameWriteRoute { nodeId :: Int }
| TeamRoute { nodeId :: Int }
| TreeFlatRoute { nodeId :: Int
, query :: Text }
| UserPageRoute { nodeId :: Int }
| ForgotPasswordRoute
| HomeRoute
| LoginRoute
deriving (Generic, GQLType)
data BreadcrumbArgs = BreadcrumbArgs data BreadcrumbArgs = BreadcrumbArgs
{ {
node_id :: Int route :: AppRoute
} deriving (Generic, GQLType) } deriving (Generic, GQLType)
data BreadcrumbInfo = BreadcrumbInfo data BreadcrumbInfo = BreadcrumbInfo
...@@ -105,31 +141,96 @@ resolveParent Nothing = pure Nothing ...@@ -105,31 +141,96 @@ resolveParent Nothing = pure Nothing
nodeToTreeNode :: HasCallStack => NN.Node json -> Maybe TreeNode nodeToTreeNode :: HasCallStack => NN.Node json -> Maybe TreeNode
nodeToTreeNode N.Node {..} = if (fromDBid _node_typename /= NN.NodeFolderShared) && (fromDBid _node_typename /= NN.NodeTeam) nodeToTreeNode N.Node {..} =
then if (fromDBid _node_typename /= NN.NodeFolderShared) && (fromDBid _node_typename /= NN.NodeTeam)
Just TreeNode { id = NN.unNodeId _node_id then
, name = _node_name Just TreeNode { id = NN.unNodeId _node_id
, node_type = fromDBid _node_typename , name = _node_name
, parent_id = NN.unNodeId <$> _node_parent_id , node_type = fromDBid _node_typename
} , parent_id = NN.unNodeId <$> _node_parent_id
else }
Nothing else
Nothing
resolveBreadcrumb :: (CmdCommon env) => BreadcrumbArgs -> GqlM e env (BreadcrumbInfo)
resolveBreadcrumb BreadcrumbArgs { node_id } = dbRecursiveParents node_id resolveBreadcrumb :: (CmdCommon env) => BreadcrumbArgs -> GqlM e env BreadcrumbInfo
resolveBreadcrumb BreadcrumbArgs { route } = dbRecursiveParents route
convertDbTreeToTreeNode :: HasCallStack => T.DbTreeNode -> TreeNode convertDbTreeToTreeNode :: HasCallStack => T.DbTreeNode -> TreeNode
convertDbTreeToTreeNode T.DbTreeNode { _dt_name, _dt_nodeId, _dt_typeId, _dt_parentId } = TreeNode convertDbTreeToTreeNode T.DbTreeNode { _dt_name, _dt_nodeId, _dt_typeId, _dt_parentId } =
{ name = _dt_name TreeNode
, id = NN.unNodeId _dt_nodeId { name = _dt_name
, node_type = fromDBid _dt_typeId , id = NN.unNodeId _dt_nodeId
, parent_id = NN.unNodeId <$> _dt_parentId , node_type = fromDBid _dt_typeId
} , parent_id = NN.unNodeId <$> _dt_parentId
}
dbRecursiveParents :: (CmdCommon env) => Int -> GqlM e env (BreadcrumbInfo)
dbRecursiveParents node_id = do dbRecursiveParents :: (CmdCommon env) => AppRoute -> GqlM e env BreadcrumbInfo
let nId = UnsafeMkNodeId node_id dbRecursiveParents (AnnuaireRoute { .. }) = do
dbRecursiveParents' nodeId
dbRecursiveParents (ContactPageRoute { .. }) = do
dbRecursiveParents' annuaireId
dbRecursiveParents (CorpusRoute { .. }) = do
dbRecursiveParents' nodeId
dbRecursiveParents (CorpusCodeRoute { .. }) = do
dbRecursiveParents' nodeId
dbRecursiveParents (CorpusDocumentRoute { .. }) = do
docIds <- lift $ getChildrenByType (UnsafeMkNodeId corpusId) NN.NodeTexts
let docId = maybe corpusId NN._NodeId $ head docIds
dbRecursiveParents' docId
dbRecursiveParents (DashboardRoute { .. }) = do
dbRecursiveParents' nodeId
dbRecursiveParents (DocumentRoute { .. }) = do
mCorpusId <- lift $ getClosestParentIdByType (UnsafeMkNodeId listId) NN.NodeCorpus
let nodeId = maybe listId NN._NodeId mCorpusId
dbRecursiveParents' nodeId
dbRecursiveParents (FolderRoute { .. }) = do
dbRecursiveParents' nodeId
dbRecursiveParents (FolderPrivateRoute { .. }) = do
dbRecursiveParents' nodeId
dbRecursiveParents (FolderPublicRoute { .. }) = do
dbRecursiveParents' nodeId
dbRecursiveParents (FolderSharedRoute { .. }) = do
dbRecursiveParents' nodeId
dbRecursiveParents (ListsRoute { .. }) = do
dbRecursiveParents' nodeId
dbRecursiveParents (NodeTextsRoute { .. }) = do
dbRecursiveParents' nodeId
dbRecursiveParents (PGraphExplorerRoute { .. }) = do
dbRecursiveParents' nodeId
dbRecursiveParents (PhyloExplorerRoute { .. }) = do
dbRecursiveParents' nodeId
dbRecursiveParents (RouteFileRoute { .. }) = do
dbRecursiveParents' nodeId
dbRecursiveParents (RouteFrameCalcRoute { .. }) = do
dbRecursiveParents' nodeId
dbRecursiveParents (RouteFrameCodeRoute { .. }) = do
dbRecursiveParents' nodeId
dbRecursiveParents (RouteFrameVisioRoute { .. }) = do
dbRecursiveParents' nodeId
dbRecursiveParents (RouteFrameWriteRoute { .. }) = do
dbRecursiveParents' nodeId
dbRecursiveParents (TeamRoute { .. }) = do
dbRecursiveParents' nodeId
dbRecursiveParents (TreeFlatRoute { .. }) = do
dbRecursiveParents' nodeId
dbRecursiveParents (UserPageRoute { .. }) = do
dbRecursiveParents' nodeId
dbRecursiveParents ForgotPasswordRoute = do
pure $ BreadcrumbInfo { parents = [] }
dbRecursiveParents HomeRoute = do
pure $ BreadcrumbInfo { parents = [] }
dbRecursiveParents LoginRoute = do
pure $ BreadcrumbInfo { parents = [] }
-- let nId = UnsafeMkNodeId node_id
-- dbParents <- lift $ T.recursiveParents nId allNodeTypes
-- let treeNodes = map convertDbTreeToTreeNode dbParents
-- let breadcrumbInfo = BreadcrumbInfo { parents = treeNodes }
-- pure breadcrumbInfo
dbRecursiveParents' :: (CmdCommon env) => Int -> GqlM e env BreadcrumbInfo
dbRecursiveParents' nodeId = do
let nId = UnsafeMkNodeId nodeId
dbParents <- lift $ T.recursiveParents nId allNodeTypes dbParents <- lift $ T.recursiveParents nId allNodeTypes
let treeNodes = map convertDbTreeToTreeNode dbParents let treeNodes = map convertDbTreeToTreeNode dbParents
let breadcrumbInfo = BreadcrumbInfo { parents = treeNodes } pure $ BreadcrumbInfo { parents = treeNodes }
pure breadcrumbInfo
...@@ -173,15 +173,36 @@ getChildrenByType :: HasDBid NodeType ...@@ -173,15 +173,36 @@ getChildrenByType :: HasDBid NodeType
-> NodeType -> NodeType
-> DBCmd err [NodeId] -> DBCmd err [NodeId]
getChildrenByType nId nType = do getChildrenByType nId nType = do
result <- runPGSQuery query (PGS.Only nId) childrenFirstLevel <- getClosestChildrenByType nId nType
children_lst <- mapM (\(id, _) -> getChildrenByType id nType) result childrenLst <- mapM (\id -> getChildrenByType id nType) childrenFirstLevel
pure $ concat $ [fst <$> filter (\(_, pTypename) -> pTypename == toDBid nType) result] ++ children_lst pure $ childrenFirstLevel ++ concat childrenLst
-- result <- runPGSQuery query (PGS.Only nId)
-- children_lst <- mapM (\(id, _) -> getChildrenByType id nType) result
-- pure $ concat $ [fst <$> filter (\(_, pTypename) -> pTypename == toDBid nType) result] ++ children_lst
-- where
-- query :: PGS.Query
-- query = [sql|
-- SELECT n.id, n.typename
-- FROM nodes n
-- WHERE n.parent_id = ?;
-- |]
-- | Given a node id, find all it's children (only first level) of
-- given node type.
getClosestChildrenByType :: HasDBid NodeType
=> NodeId
-> NodeType
-> DBCmd err [NodeId]
getClosestChildrenByType nId nType = do
results <- runPGSQuery query (nId, toDBid nType)
pure $ (\(PGS.Only nodeId) -> nodeId) <$> results
where where
query :: PGS.Query query :: PGS.Query
query = [sql| query = [sql|
SELECT n.id, n.typename SELECT n.id
FROM nodes n FROM nodes n
WHERE n.parent_id = ?; WHERE n.parent_id = ?
AND n.typename = ?;
|] |]
------------------------------------------------------------------------ ------------------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment