diff --git a/package.json b/package.json index cc36cccc0b77322e24cfe1d1855a02adba1ef543..e860a5bcba2fc253647cffcf52331013d4040e90 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Gargantext", - "version": "0.0.6.9.9.9.9.1", + "version": "0.0.7.1", "scripts": { "build": "spago build", "bundle": "spago bundle --module Main --outfile dist/bundle.js", diff --git a/src/Gargantext/Components/App/Store.purs b/src/Gargantext/Components/App/Store.purs index 72f53ec8fe50df2d0456cfed2fc3ebb1b15caaaa..1c4c81b9666a1b4c5eeb9a82bf2936a35ebb653a 100644 --- a/src/Gargantext/Components/App/Store.purs +++ b/src/Gargantext/Components/App/Store.purs @@ -10,22 +10,24 @@ module Gargantext.Components.App.Store ) where +import Gargantext.Prelude + import Data.Map (Map) import Data.Map as Map import Data.Maybe (Maybe(..)) import Data.Set as Set +import Data.Tuple (Tuple) import Gargantext.AsyncTasks as GAT import Gargantext.Components.Lang as Lang import Gargantext.Components.Nodes.Lists.SidePanel as ListsSP import Gargantext.Components.Nodes.Texts.Types as TextsT import Gargantext.Components.Themes as Themes import Gargantext.Ends (Backend) -import Gargantext.Prelude import Gargantext.Routes (AppRoute(Home), Tile) import Gargantext.Sessions (Session, Sessions) import Gargantext.Sessions as Sessions import Gargantext.Sessions.Types (OpenNodes(..)) -import Gargantext.Types (FrontendError, Handed(RightHanded), SidePanelState(..)) +import Gargantext.Types (FrontendError, Handed(RightHanded), ID, SidePanelState(..)) import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Stores as Stores import Gargantext.Utils.Toestand as T2 @@ -45,6 +47,7 @@ type Store = , graphVersion :: T2.ReloadS , handed :: T.Box Handed , lang :: T.Box Lang.LandingLang + , loginRedirect :: T.Box (Maybe (Tuple String ID)) , pinnedTreeId :: T.Box (Map String Int) , reloadForest :: T2.ReloadS , reloadMainPage :: T2.ReloadS @@ -73,6 +76,7 @@ type State = , graphVersion :: T2.Reload , handed :: Handed , lang :: Lang.LandingLang + , loginRedirect :: Maybe (Tuple String ID) , pinnedTreeId :: Map String Int , reloadForest :: T2.Reload , reloadMainPage :: T2.Reload @@ -102,6 +106,7 @@ options = , graphVersion : T2.newReload , handed : RightHanded , lang : Lang.LL_EN + , loginRedirect : Nothing , pinnedTreeId : Map.empty , reloadForest : T2.newReload , reloadMainPage : T2.newReload diff --git a/src/Gargantext/Components/Forest/Breadcrumb.purs b/src/Gargantext/Components/Forest/Breadcrumb.purs index e541aa2a08033a8ca45fffe175a9c05b6d3945b6..1000eeeb32cfa252afc50197fab25c28a7c2a71f 100644 --- a/src/Gargantext/Components/Forest/Breadcrumb.purs +++ b/src/Gargantext/Components/Forest/Breadcrumb.purs @@ -5,16 +5,18 @@ module Gargantext.Components.Forest.Breadcrumb where import Data.Array as A +import Data.Either (Either(..), either) import Data.Int (fromString) -import Data.Maybe (Maybe(..), fromMaybe) +import Data.Maybe (Maybe(..), fromMaybe, maybe) import Data.String (Pattern(..), split) import Gargantext.Components.App.Store as Store import Gargantext.Components.Bootstrap as B -import Gargantext.Components.GraphQL.Endpoints (getBreadcrumb) +import Gargantext.Components.GraphQL.Endpoints (getBreadcrumb, getNodeChildren, getNodeParent) import Gargantext.Components.GraphQL.Tree (BreadcrumbInfo, TreeNode) import Gargantext.Config.REST (AffRESTError) +import Gargantext.Ends (Backend(..)) import Gargantext.Hooks.Loader (useLoader) -import Gargantext.Routes (AppRoute(Home), appPath, nodeTypeAppRoute) +import Gargantext.Routes (AppRoute(..), appPath, nodeTypeAppRoute) import Gargantext.Sessions.Types import Gargantext.Types (NodeType, SessionId) import Gargantext.Types as GT @@ -30,25 +32,17 @@ import Toestand as T here :: R2.Here here = R2.here "Gargantext.Components.Forest.Breadcrumb" -type PropsBoxes = ( boxes :: Store.Boxes ) -type Props = - ( nodeId :: Int - , session :: Maybe Session - , format :: String - ) - --- maybeToSession :: Maybe Session -> Session --- maybeToSession s = fromMaybe Nothing s - - -component :: R2.Leaf PropsBoxes +component :: R2.Leaf () component = R2.leaf componentCpt -componentCpt :: R.Component PropsBoxes +componentCpt :: R.Component () componentCpt = here.component "breadcrumb" cpt where - cpt { boxes: { session } } _ = do + cpt { } _ = do + { route, session } <- Store.use + -- | States -- | + route' <- T.useLive T.unequal route session' <- T.useLive T.unequal session -- R.provideContext SessionContext.context session' @@ -67,10 +61,10 @@ componentCpt = here.component "breadcrumb" cpt where case session' of Nothing -> pure $ H.div {} [] - Just _session'' -> do + Just session'' -> do - url <- R.unsafeHooksEffect GU.href - let nodeId = fromMaybe 0 $ fromString $ getLastUrlElement url + -- url <- R.unsafeHooksEffect GU.href + -- let nodeId = fromMaybe 0 $ fromString $ getLastUrlElement url -- breadcrumbData <- R2.useLayoutEffect1' $ getBreadcrumb session' currentNodeId pure $ @@ -91,10 +85,10 @@ componentCpt = here.component "breadcrumb" cpt where ] ] , - breadcrumbView { nodeId: nodeId - , session: session' - , format: "default" - } + breadcrumbView { format: "default" + , route: route' + , session: session'' + } ] -- , -- H.nav @@ -146,40 +140,42 @@ componentCpt = here.component "breadcrumb" cpt where -- ] ] +type BreadcrumbViewProps = + ( format :: String + , route :: AppRoute + , session :: Session + ) + -breadcrumbView :: R2.Leaf Props +breadcrumbView :: R2.Leaf BreadcrumbViewProps breadcrumbView = R2.leaf breadcrumbViewCpt -breadcrumbViewCpt :: R.Component Props +breadcrumbViewCpt :: R.Component BreadcrumbViewProps breadcrumbViewCpt = R2.hereComponent here "breadcrumbViewCpt" hCpt where - hCpt hp { nodeId, session, format } _ = do - - case session of - Nothing -> pure $ H.div {} [] - Just session' -> do - useLoader { errorHandler: Nothing - , herePrefix: hp - , loader: loadBreadcrumbData - , path: { nodeId: nodeId - , session: session' - -- , reload: reload' - } - , render: \items -> breadcrumbViewMain { items: items - , session: session' - -- , reload: reload - , format: format - } [] - } - -type BreadcrumbViewProps = - ( items :: BreadcrumbInfo + hCpt hp { format, route, session } _ = do + + useLoader { errorHandler: Nothing + , herePrefix: hp + , loader: loadBreadcrumbData + , path: { route + , session + } + , render: \items -> breadcrumbViewMain { format: format + , items + , session + -- , reload: reload + } [] + } + +type BreadcrumbViewMainProps = + ( format :: String + , items :: BreadcrumbInfo , session :: Session -- , reload :: T.Box T2.Reload - , format :: String ) -breadcrumbViewMain :: R2.Component BreadcrumbViewProps +breadcrumbViewMain :: R2.Component BreadcrumbViewMainProps breadcrumbViewMain = R.createElement breadcrumbViewMainCpt -breadcrumbViewMainCpt :: R.Component BreadcrumbViewProps +breadcrumbViewMainCpt :: R.Component BreadcrumbViewMainProps breadcrumbViewMainCpt = here.component "breadcrumbViewMainCpt" cpt where cpt { items: { parents }, session, format } _ = do @@ -234,8 +230,6 @@ breadcrumbItemCpt = here.component "breadcrumbItemCpt" cpt where boxes@{ forestOpen } <- Store.use - url <- R.unsafeHooksEffect GU.href - let sid = sessionId session let rootId = treeId session @@ -249,7 +243,7 @@ breadcrumbItemCpt = here.component "breadcrumbItemCpt" cpt where H.span { className: "node-path-item" } [ - if show nodeType == "NodeUser" + if nodeType == GT.NodeUser then H.text "" else @@ -260,10 +254,7 @@ breadcrumbItemCpt = here.component "breadcrumbItemCpt" cpt where H.li { className: "breadcrumb-item" } [ - if show nodeType == "NodeFolderPrivate" - || show nodeType == "NodeFolderPublic" - || show nodeType == "NodeFolderShared" - || show nodeType == "NodeUser" + if nodeType `A.elem` [ GT.FolderPrivate, GT.FolderPublic, GT.FolderShared, GT.NodeUser ] then H.span { className: "" } [ @@ -275,17 +266,17 @@ breadcrumbItemCpt = here.component "breadcrumbItemCpt" cpt where } ] , - if show nodeType == "NodeUser" + if nodeType == GT.NodeUser then - H.text $ getUserText url + H.text $ getUserText session else H.text text , H.span { className: "text-small" } [ - if show nodeType == "NodeUser" + if nodeType == GT.NodeUser then - H.text $ " (" <> getInstanceText url <> ")" + H.text $ " (" <> getInstanceText session <> ")" else H.text "" ] @@ -322,25 +313,86 @@ breadcrumbItemCpt = here.component "breadcrumbItemCpt" cpt where treeId :: Session -> Int treeId (Session {treeId: tId}) = tId -getLastUrlElement :: String -> String -getLastUrlElement str = fromMaybe "" $ A.last $ split (Pattern "/") str - -getFirstUrlElement :: String -> String -getFirstUrlElement str = fromMaybe "" $ A.head $ split (Pattern "/") str +getInstanceText :: Session -> String +getInstanceText (Session { backend }) = cleanBackendUrl backend -getInstanceText :: String -> String -getInstanceText str = getFirstUrlElement $ fromMaybe "" $ A.last $ split (Pattern "@") str +getUserText :: Session -> String +getUserText (Session { username }) = username + -- getLastUrlElement $ fromMaybe "" $ A.head $ split (Pattern "@") str -getUserText :: String -> String -getUserText str = getLastUrlElement $ fromMaybe "" $ A.head $ split (Pattern "@") str -type LoadProps = +type LoadRawProps = ( - session :: Session - , nodeId :: Int + nodeId :: Int + , session :: Session -- , reload :: T.Box T2.Reload ) +loadBreadcrumbDataRaw :: Record LoadRawProps -> AffRESTError BreadcrumbInfo +loadBreadcrumbDataRaw { nodeId, session } = getBreadcrumb session nodeId + + +type LoadProps = + ( route :: AppRoute + , session :: Session ) + loadBreadcrumbData :: Record LoadProps -> AffRESTError BreadcrumbInfo -loadBreadcrumbData {nodeId, session} = getBreadcrumb session nodeId +loadBreadcrumbData { route: Annuaire _s nodeId, session } = do + loadBreadcrumbDataRaw { nodeId, session } +loadBreadcrumbData { route: ContactPage _s nodeId annuaireId, session } = do + loadBreadcrumbDataRaw { nodeId: annuaireId, session } +loadBreadcrumbData { route: Corpus _s nodeId, session } = do + loadBreadcrumbDataRaw { nodeId, session } +loadBreadcrumbData { route: CorpusCode _s nodeId, session } = do + loadBreadcrumbDataRaw { nodeId, session } +loadBreadcrumbData { route: CorpusDocument _s corpusId listId documentId, session } = do + texts <- getNodeChildren session corpusId GT.NodeTexts + let docId = maybe corpusId _.id $ either (const Nothing) A.head texts + loadBreadcrumbDataRaw { nodeId: docId, session } +loadBreadcrumbData { route: Dashboard _s nodeId, session } = do + loadBreadcrumbDataRaw { nodeId, session } +loadBreadcrumbData { route: Document _s listId documentId, session } = do + corpora <- getNodeParent session listId GT.Corpus + let nodeId = maybe listId _.id $ either (const Nothing) A.head corpora + loadBreadcrumbDataRaw { nodeId, session } +loadBreadcrumbData { route: Folder _s nodeId, session } = do + loadBreadcrumbDataRaw { nodeId, session } +loadBreadcrumbData { route: FolderPrivate _s nodeId, session } = do + loadBreadcrumbDataRaw { nodeId, session } +loadBreadcrumbData { route: FolderPublic _s nodeId, session } = do + loadBreadcrumbDataRaw { nodeId, session } +loadBreadcrumbData { route: FolderShared _s nodeId, session } = do + loadBreadcrumbDataRaw { nodeId, session } +loadBreadcrumbData { route: Lists _s nodeId, session } = do + loadBreadcrumbDataRaw { nodeId, session } +loadBreadcrumbData { route: NodeTexts _s nodeId, session } = do + loadBreadcrumbDataRaw { nodeId, session } +loadBreadcrumbData { route: PGraphExplorer _s nodeId, session } = do + loadBreadcrumbDataRaw { nodeId, session } +loadBreadcrumbData { route: PhyloExplorer _s nodeId, session } = do + loadBreadcrumbDataRaw { nodeId, session } +loadBreadcrumbData { route: RouteFile _s nodeId, session } = do + loadBreadcrumbDataRaw { nodeId, session } +loadBreadcrumbData { route: RouteFrameCalc _s nodeId, session } = do + loadBreadcrumbDataRaw { nodeId, session } +loadBreadcrumbData { route: RouteFrameCode _s nodeId, session } = do + loadBreadcrumbDataRaw { nodeId, session } +loadBreadcrumbData { route: RouteFrameVisio _s nodeId, session } = do + loadBreadcrumbDataRaw { nodeId, session } +loadBreadcrumbData { route: RouteFrameWrite _s nodeId, session } = do + loadBreadcrumbDataRaw { nodeId, session } +loadBreadcrumbData { route: Team _s nodeId, session } = do + loadBreadcrumbDataRaw { nodeId, session } +loadBreadcrumbData { route: TreeFlat _s nodeId _q, session } = do + loadBreadcrumbDataRaw { nodeId, session } +loadBreadcrumbData { route: UserPage _s nodeId, session } = do + loadBreadcrumbDataRaw { nodeId, session } +loadBreadcrumbData { route: ForgotPassword _s } = do + pure $ Right { parents: [] } +loadBreadcrumbData { route: Home } = do + pure $ Right { parents: [] } +loadBreadcrumbData { route: Login } = do + pure $ Right { parents: [] } +loadBreadcrumbData { route: Share _t _i} = do + pure $ Right { parents: []} diff --git a/src/Gargantext/Components/Forest/Tree/Node/Action/Contact/Types.purs b/src/Gargantext/Components/Forest/Tree/Node/Action/Contact/Types.purs index 8b849b665c61eac0a0a1a88025c00ae1e5bf3944..5a6d11325ef1918224ff9ff0731f1745a4e2bd64 100644 --- a/src/Gargantext/Components/Forest/Tree/Node/Action/Contact/Types.purs +++ b/src/Gargantext/Components/Forest/Tree/Node/Action/Contact/Types.purs @@ -17,9 +17,11 @@ instance JSON.ReadForeign AddContactParams where readImpl = GUSJ.taggedSumRep instance JSON.WriteForeign AddContactParams where writeImpl (AddContactParams { firstname, lastname }) = JSON.writeImpl { type: "AddContactParams" - , values: { firstname, lastname } } + , firstname + , lastname } writeImpl (AddContactParamsAdvanced { firstname, lastname }) = JSON.writeImpl { type: "AddContactParamsAdvanced" - , values: { firstname, lastname } } + , firstname + , lastname } diff --git a/src/Gargantext/Components/Forest/Tree/Node/Action/Share.purs b/src/Gargantext/Components/Forest/Tree/Node/Action/Share.purs index 8357e25e183e5c9dd2b63591efe82082d105fc14..666b602f5fe2e741201ceaa9c7f2199f5f604328 100644 --- a/src/Gargantext/Components/Forest/Tree/Node/Action/Share.purs +++ b/src/Gargantext/Components/Forest/Tree/Node/Action/Share.purs @@ -20,7 +20,7 @@ import Gargantext.Hooks.Loader (useLoader) import Gargantext.Prelude import Gargantext.Routes as GR import Gargantext.Sessions (Session, get, post) -import Gargantext.Types (ID) +import Gargantext.Types (ID, NodeID, NodeType) import Gargantext.Types as GT import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.SimpleJSON as GUSJ @@ -44,8 +44,9 @@ getCompletionsReq { session } = ------------------------------------------------------------------------ -data ShareNodeParams = ShareTeamParams { username :: String } - | SharePublicParams { node_id :: Int } +data ShareNodeParams = + ShareTeamParams { username :: String } + | SharePublicParams { node_id :: Int } derive instance Eq ShareNodeParams derive instance Generic ShareNodeParams _ instance JSON.ReadForeign ShareNodeParams where readImpl = GUSJ.taggedSumRep @@ -144,6 +145,36 @@ publishNodeCpt = here.component "publishNode" cpt , session , subTreeParams } [] - -- footer , button ] +------------------------------------------------------------------------ +type ShareURL = + ( nodeType :: NodeType + , id :: ID + , session :: Session) + +shareURL :: R2.Component ShareURL +shareURL = R.createElement shareURLcpt + +shareURLcpt :: R.Component ShareURL +shareURLcpt = R2.hereComponent here "shareURL" hCpt + where + hCpt hp {nodeType, id, session} _ = do + useLoader { errorHandler: Just errorHandler + , herePrefix: hp + , loader: loadUrl + , path: {nodeType, id, session} + , render: \url -> shareURLInner {url} [] } + errorHandler err = here.warn2 "[ShareURL] RESTError" err + +shareURLInner :: R2.Component ( url :: String ) +shareURLInner = R.createElement shareURLInnercpt + +shareURLInnercpt :: R.Component ( url :: String ) +shareURLInnercpt = here.component "shareURLInner" cpt + where + cpt { url } _ = do + pure $ Tools.panel { mError: Nothing } [ H.div {} [ H.text url ] ] + +loadUrl :: { session :: Session, id :: NodeID, nodeType :: NodeType } -> AffRESTError String +loadUrl { session, id, nodeType } = get session $ GR.ShareURL id nodeType diff --git a/src/Gargantext/Components/Forest/Tree/Node/Box.purs b/src/Gargantext/Components/Forest/Tree/Node/Box.purs index 216d85f9c2e0d9163e8017256f743bc0b76682a3..f5e7b4edf435864057519e53d12a7e5ea95778ed 100644 --- a/src/Gargantext/Components/Forest/Tree/Node/Box.purs +++ b/src/Gargantext/Components/Forest/Tree/Node/Box.purs @@ -363,6 +363,7 @@ panelActionCpt = here.component "panelAction" cpt cpt { action: SearchBox, dispatch, id, session } _ = pure $ actionSearch { dispatch, id: Just id, session } [] cpt { action : Share, id, session } _ = pure $ Share.shareNode { id, session } [] + cpt { action: ShareURL, id, nodeType, session } _ = pure $ Share.shareURL { nodeType, id, session } [] cpt { action: Upload, dispatch, id, nodeType, session} _ = pure $ actionUpload { dispatch, id, nodeType, session } [] cpt { action: WriteNodesDocuments, dispatch, id, session } _ = diff --git a/src/Gargantext/Components/Forest/Tree/Node/Settings.purs b/src/Gargantext/Components/Forest/Tree/Node/Settings.purs index bb9aea2c05c2a99630d32537795a00fa3d61f485..644c20259cd18620357b823a9a2151a9dcc5d190 100644 --- a/src/Gargantext/Components/Forest/Tree/Node/Settings.purs +++ b/src/Gargantext/Components/Forest/Tree/Node/Settings.purs @@ -29,6 +29,7 @@ data NodeAction = Add (Array NodeType) | ReloadWithSettings | Reconstruct | SearchBox + | ShareURL | Share | Upload | WriteNodesDocuments -- https://gitlab.iscpif.fr/gargantext/purescript-gargantext/issues/331 @@ -51,6 +52,7 @@ instance Eq NodeAction where eq Refresh Refresh = true eq ReloadWithSettings ReloadWithSettings = true eq SearchBox SearchBox = true + eq ShareURL ShareURL = true eq Share Share = true eq Upload Upload = true eq WriteNodesDocuments WriteNodesDocuments = true @@ -73,6 +75,7 @@ instance Show NodeAction where show Refresh = "Refresh" show ReloadWithSettings = "Reload (with settings)" show SearchBox = "SearchBox" + show ShareURL = "Share URL" show Share = "Share" show Upload = "Upload" show WriteNodesDocuments = "WriteNodesDocuments" @@ -94,6 +97,7 @@ glyphiconNodeAction Reconstruct = "cogs" glyphiconNodeAction Refresh = "refresh" glyphiconNodeAction ReloadWithSettings = "reload-with-settings" glyphiconNodeAction SearchBox = "search" +glyphiconNodeAction ShareURL = "share-alt" glyphiconNodeAction Share = "user-plus" glyphiconNodeAction Upload = "upload" glyphiconNodeAction WriteNodesDocuments = "bars" @@ -160,6 +164,7 @@ settingsBoxLens Corpus = , Move moveParameters , Upload , SearchBox + , ShareURL , WriteNodesDocuments -- , Download , Link (linkParams Annuaire) @@ -180,6 +185,7 @@ settingsBoxLens Folder = -- , NodeFrameNotebook ] , Move moveParameters + , ShareURL , Delete ] settingsBoxLens FolderPrivate = @@ -203,6 +209,7 @@ settingsBoxLens Graph = , Config , Download -- TODO as GEXF or JSON -- , Publish publishParams + , ShareURL , Delete ] settingsBoxLens NodeFile = @@ -214,6 +221,7 @@ settingsBoxLens NodeFrameNotebook = -- , NodeFrameNotebook ] , Move moveFrameParameters + , ShareURL , Delete ] settingsBoxLens NodeFrameVisio = @@ -221,6 +229,7 @@ settingsBoxLens NodeFrameVisio = , Notes , Calc ] + , ShareURL , Delete ] settingsBoxLens NodeList = @@ -228,6 +237,7 @@ settingsBoxLens NodeList = , Config , Upload , Download + , ShareURL , Merge {subTreeParams : SubTreeParams { showtypes: [ FolderPrivate , FolderShared , Team @@ -259,6 +269,7 @@ settingsBoxLens NodeTexts = _buttons .~ [ ReloadWithSettings -- , Upload , Download + , ShareURL -- , Delete ] settingsBoxLens NodeUser = @@ -272,10 +283,12 @@ settingsBoxLens Notes = , Corpus ] , Move moveFrameParameters + , ShareURL , Delete ] settingsBoxLens Phylo = _buttons .~ [ Reconstruct + , ShareURL , Delete ] settingsBoxLens Team = @@ -290,6 +303,7 @@ settingsBoxLens Team = , NodeFrameVisio ] , Share + , ShareURL , ManageTeam , Delete ] diff --git a/src/Gargantext/Components/GraphQL.purs b/src/Gargantext/Components/GraphQL.purs index a27c899b0fcc43997ec0875e7bce389af2b3db71..816fb8f61ecd3128aadb6d6570be9f5cfacc0bb4 100644 --- a/src/Gargantext/Components/GraphQL.purs +++ b/src/Gargantext/Components/GraphQL.purs @@ -21,7 +21,9 @@ import Gargantext.Components.GraphQL.User (User, UserInfo, UserInfoM, UserPubmed import Gargantext.Config.REST as REST import Gargantext.Ends (Backend(..)) import Gargantext.Prelude +import Gargantext.Routes (AppRoute) import Gargantext.Sessions (Session(..)) +import Gargantext.Types (NodeType) import Gargantext.Utils.Reactix as R2 import GraphQL.Client.BaseClients.Urql (UrqlClient, createClient) import GraphQL.Client.Query (decodeGqlRes) --, mutationJson) @@ -149,7 +151,8 @@ type Schema , contexts_for_ngrams :: { corpus_id :: Int, ngrams_terms :: Array String } -> Array GQLCTX.Context , imt_schools :: {} -> Array GQLIMT.School , languages :: {} -> Array GQLNLP.Language - , node_parent :: { node_id :: Int, parent_type :: String } -> Array GQLNode.Node -- TODO: parent_type :: NodeType + , node_children :: { node_id :: Int, child_type :: NodeType } -> Array GQLNode.Node + , node_parent :: { node_id :: Int, parent_type :: NodeType } -> Array GQLNode.Node , nodes :: { node_id :: Int } -> Array GQLNode.Node , nodes_corpus :: { corpus_id :: Int } -> Array GQLNode.Corpus , user_infos :: { user_id :: Int } -> Array UserInfo diff --git a/src/Gargantext/Components/GraphQL/Endpoints.purs b/src/Gargantext/Components/GraphQL/Endpoints.purs index 1bbc8b66f871d1935fe6861640ebd8c5f387f955..121406bd9b34fa6b25a6e8eca1eb43181b509bb7 100644 --- a/src/Gargantext/Components/GraphQL/Endpoints.purs +++ b/src/Gargantext/Components/GraphQL/Endpoints.purs @@ -12,7 +12,7 @@ import Gargantext.Components.GraphQL.Contact (AnnuaireContact, annuaireContactQu import Gargantext.Components.GraphQL.Context as GQLCTX import Gargantext.Components.GraphQL.IMT as GQLIMT import Gargantext.Components.GraphQL.NLP as GQLNLP -import Gargantext.Components.GraphQL.Node (Corpus, Node, nodeParentQuery, nodesQuery, nodesCorpusQuery) +import Gargantext.Components.GraphQL.Node (Corpus, Node, nodeChildrenQuery, nodeParentQuery, nodesQuery, nodesCorpusQuery) import Gargantext.Components.GraphQL.Team (Team, teamQuery) import Gargantext.Components.GraphQL.Tree (TreeFirstLevel, treeFirstLevelQuery, BreadcrumbInfo, breadcrumbQuery) import Gargantext.Components.GraphQL.User (UserInfo, userInfoQuery, User, userQuery) @@ -20,6 +20,7 @@ import Gargantext.Components.Lang (Lang) import Gargantext.Config.REST (RESTError(..), AffRESTError) import Gargantext.Core.NgramsTable.Types (NgramsTerm(..)) import Gargantext.Prelude +import Gargantext.Routes (AppRoute(..)) import Gargantext.Sessions (Session(..)) import Gargantext.Types (CorpusId, NodeType) import Gargantext.Utils.Reactix as R2 @@ -64,11 +65,20 @@ getNodeParent :: Session -> Int -> NodeType -> AffRESTError (Array Node) getNodeParent session nodeId parentType = do eRes <- queryGql session "get node parent" $ nodeParentQuery `withVars` { id: nodeId - , parent_type: show parentType } -- TODO: remove "show" + , parent_type: parentType } -- liftEffect $ here.log2 "[getNodeParent] node_parent" node_parent --pure node_parent pure $ rmap _.node_parent eRes +getNodeChildren :: Session -> Int -> NodeType -> AffRESTError (Array Node) +getNodeChildren session nodeId childType = do + eRes <- queryGql session "get node child" $ + nodeChildrenQuery `withVars` { id: nodeId + , child_type: childType } + -- liftEffect $ here.log2 "[getNodeParent] node_parent" node_parent + --pure node_parent + pure $ rmap _.node_children eRes + getUser :: Session -> Int -> AffRESTError User getUser session id = do eRes <- queryGql session "get user" $ userQuery `withVars` { id } @@ -218,7 +228,7 @@ getContextNgrams session context_id list_id = do pure $ rmap (\{ context_ngrams } -> NormNgramsTerm <$> context_ngrams) eRes getBreadcrumb :: Session -> Int -> AffRESTError BreadcrumbInfo -getBreadcrumb session id = do - eRes <- queryGql session "get breadcrumb branch" $ breadcrumbQuery `withVars` { id } +getBreadcrumb session node_id = do + eRes <- queryGql session "get breadcrumb branch" $ breadcrumbQuery `withVars` { node_id } -- liftEffect $ here.log2 "[getBreadcrumb] breadcrumb" tree_branch pure $ rmap _.tree_branch eRes diff --git a/src/Gargantext/Components/GraphQL/Node.purs b/src/Gargantext/Components/GraphQL/Node.purs index 26351af03c2e05ed754eb05d3d6ba573a0640a15..63efa2dc0fc422c70633ba062acb90656cc51a5a 100644 --- a/src/Gargantext/Components/GraphQL/Node.purs +++ b/src/Gargantext/Components/GraphQL/Node.purs @@ -2,6 +2,7 @@ module Gargantext.Components.GraphQL.Node where import Gargantext.Prelude import Gargantext.Utils.GraphQL as GGQL +import Gargantext.Types (NodeType) import GraphQL.Client.Args (Args, (=>>)) import GraphQL.Client.Variable (Var(..)) import Type.Proxy (Proxy(..)) @@ -46,6 +47,11 @@ nodesCorpusQuery = { nodes_corpus: { corpus_id: Var :: _ "id" Int } =>> } nodeParentQuery = { node_parent: { node_id: Var :: _ "id" Int - , parent_type: Var :: _ "parent_type" String } =>> -- TODO parent_type :: NodeType + , parent_type: Var :: _ "parent_type" NodeType } =>> GGQL.getFieldsStandard (Proxy :: _ Node) } + +nodeChildrenQuery = { node_children: { node_id: Var :: _ "id" Int + , child_type: Var :: _ "child_type" NodeType } =>> + GGQL.getFieldsStandard (Proxy :: _ Node) + } diff --git a/src/Gargantext/Components/GraphQL/Tree.purs b/src/Gargantext/Components/GraphQL/Tree.purs index d6dacf9d768950c698e9ee096ac2dff533ab33b2..daa3b340208f2ed0bd49a5b29896a52704056a4f 100644 --- a/src/Gargantext/Components/GraphQL/Tree.purs +++ b/src/Gargantext/Components/GraphQL/Tree.purs @@ -3,6 +3,7 @@ module Gargantext.Components.GraphQL.Tree where import Gargantext.Prelude import Data.Maybe (Maybe) +import Gargantext.Routes (AppRoute) import Gargantext.Types (NodeType) import GraphQL.Client.Args ((=>>)) import GraphQL.Client.Variable (Var(..)) @@ -42,7 +43,7 @@ treeFirstLevelQuery = { tree: { root_id: Var :: _ "id" Int} =>> } } -breadcrumbQuery = { tree_branch: { node_id: Var :: _ "id" Int} =>> +breadcrumbQuery = { tree_branch: { node_id: Var :: _ "node_id" Int } =>> { parents: { name: unit , node_type: unit @@ -50,4 +51,4 @@ breadcrumbQuery = { tree_branch: { node_id: Var :: _ "id" Int} =>> , parent_id: unit } } -} \ No newline at end of file +} diff --git a/src/Gargantext/Components/Login.purs b/src/Gargantext/Components/Login.purs index 3d60dff26379e79dcfe91154948cb9c0e5e4a889..0430ce18809627eb0ba23184e560b2d632e2593e 100644 --- a/src/Gargantext/Components/Login.purs +++ b/src/Gargantext/Components/Login.purs @@ -21,20 +21,22 @@ import Data.Array (head) import Data.Foldable (intercalate) import Data.Maybe (Maybe(..), fromMaybe) import Data.String as DST +import Data.Tuple (Tuple) import Data.Tuple.Nested ((/\)) import Effect (Effect) import Effect.Aff (Milliseconds(..), delay, launchAff_) import Effect.Class (liftEffect) import Gargantext.Components.Bootstrap as B import Gargantext.Components.Bootstrap.Types (ComponentStatus(..), Elevation(..), ModalSizing(..), Position(..), TooltipPosition(..), Variant(..)) -import Gargantext.Components.Login.PasswordForm as PasswordForm import Gargantext.Components.Login.LoginForm as LoginForm +import Gargantext.Components.Login.PasswordForm as PasswordForm import Gargantext.Components.Login.Types (FormType(..)) import Gargantext.Components.NgramsTable.Loader as NTL import Gargantext.Ends (Backend(..)) import Gargantext.Hooks.Loader as GHL import Gargantext.Sessions (Session(..), Sessions, Action(Logout), unSessions) import Gargantext.Sessions as Sessions +import Gargantext.Types (ID) import Gargantext.Utils ((?)) import Gargantext.Utils.Reactix as R2 import Reactix as R @@ -51,10 +53,11 @@ here = R2.here "Gargantext.Components.Login" -- if not logged user can not save his work type Props = - ( backend :: T.Box (Maybe Backend) - , backends :: Array Backend - , sessions :: T.Box Sessions - , visible :: T.Box Boolean + ( backend :: T.Box (Maybe Backend) + , backends :: Array Backend + , sessions :: T.Box Sessions + , visible :: T.Box Boolean + , loginRedirect :: T.Box (Maybe (Tuple String ID)) ) login :: R2.Leaf Props @@ -82,7 +85,7 @@ loginContainer :: R2.Leaf Props loginContainer = R2.leaf loginContainerCpt loginContainerCpt :: R.Component Props loginContainerCpt = here.component "container" cpt where - cpt props@{ sessions, visible } _ = do + cpt props@{ sessions, visible, loginRedirect } _ = do -- | States -- | mBackend <- R2.useLive' props.backend @@ -109,6 +112,7 @@ loginContainerCpt = here.component "container" cpt where , formType , sessions , visible + , loginRedirect } ForgotPassword -> PasswordForm.component diff --git a/src/Gargantext/Components/Login/LoginForm.purs b/src/Gargantext/Components/Login/LoginForm.purs index 6c4caa648ea039123bc328f0cb842973c971be74..ab999f699bab61a9cf43b9037446f7fa0cd51757 100644 --- a/src/Gargantext/Components/Login/LoginForm.purs +++ b/src/Gargantext/Components/Login/LoginForm.purs @@ -6,8 +6,9 @@ import Gargantext.Prelude import Data.Either (Either(..)) import Data.Foldable (foldl, intercalate) -import Data.Maybe (Maybe(..)) +import Data.Maybe (Maybe(..), fromMaybe) import Data.String as String +import Data.Tuple (Tuple) import Data.Tuple.Nested ((/\)) import Effect (Effect) import Effect.Aff (Aff, launchAff_) @@ -18,9 +19,12 @@ import Gargantext.Components.Login.Types (AuthRequest(..), FormType(..)) import Gargantext.Ends (Backend) import Gargantext.Hooks.FormValidation (VForm, useFormValidation) import Gargantext.Hooks.FormValidation.Unboxed as FV +import Gargantext.Hooks.LinkHandler (useLinkHandler) import Gargantext.Hooks.StateRecord (useStateRecord) -import Gargantext.Sessions (Session, Sessions, postAuthRequest) +import Gargantext.Routes as GR +import Gargantext.Sessions (Session, Sessions, postAuthRequest, sessionId) import Gargantext.Sessions as Sessions +import Gargantext.Types (ID, NodeType(..)) import Gargantext.Utils ((?)) import Gargantext.Utils.Reactix as R2 import Reactix as R @@ -33,10 +37,11 @@ here :: R2.Here here = R2.here "Gargantext.Components.Login.Form" type Props = - ( backend :: Backend - , formType :: T.Box FormType - , sessions :: T.Box Sessions - , visible :: T.Box Boolean + ( backend :: Backend + , formType :: T.Box FormType + , sessions :: T.Box Sessions + , visible :: T.Box Boolean + , loginRedirect :: T.Box (Maybe (Tuple String ID)) ) component :: R2.Leaf Props @@ -47,6 +52,7 @@ componentCpt = here.component "main" cpt where , formType , sessions , visible + , loginRedirect } _ = do -- | States -- | @@ -56,6 +62,8 @@ componentCpt = here.component "main" cpt where onPending' /\ onPending <- R2.useBox' false + loginRedirect' <- R2.useLive' loginRedirect + -- | Hooks -- | { state @@ -65,6 +73,8 @@ componentCpt = here.component "main" cpt where fv <- useFormValidation + { goToRoute } <- useLinkHandler + -- | Behaviors -- | let @@ -96,6 +106,11 @@ componentCpt = here.component "main" cpt where Right session_ -> liftEffect $ Sessions.change (Sessions.Login session_) sessions *> T.write_ false visible + *> case loginRedirect' of + Just (nodeType /\ nodeId) -> do + T.write_ Nothing loginRedirect + goToRoute $ fromMaybe GR.Login $ GR.nodeTypeAppRoute (fromMaybe Node $ read nodeType) (sessionId session_) nodeId + Nothing -> pure unit T.write_ false onPending diff --git a/src/Gargantext/Components/Router.purs b/src/Gargantext/Components/Router.purs index a8db6593c022d19d8abb1be79887b4295d454e3d..2d2a4c83c2b4ab129d37a876ca0f433bcfa63440 100644 --- a/src/Gargantext/Components/Router.purs +++ b/src/Gargantext/Components/Router.purs @@ -1,13 +1,18 @@ -module Gargantext.Components.Router (router) where +module Gargantext.Components.Router + ( router + , shareCpt + ) + where import Gargantext.Prelude import DOM.Simple as DOM -import Data.Array (filter, length) +import Data.Array (filter, head, length) import Data.Array as A import Data.Foldable (intercalate) import Data.Map as M import Data.Maybe (Maybe(..), fromMaybe, maybe) +import Data.Tuple (Tuple(..)) import Data.UUID (UUID) import Data.UUID as UUID import Effect (Effect) @@ -16,7 +21,6 @@ import Gargantext.Components.ErrorsView as ErrorsView import Gargantext.Components.Forest (forestLayout) import Gargantext.Components.Forest.Breadcrumb as Breadcrumb import Gargantext.Components.ForgotPassword (forgotPasswordLayout) --- import Gargantext.Components.GraphQL.Node (Node) import Gargantext.Components.Login (login) import Gargantext.Components.Nodes.Annuaire (annuaireLayout) import Gargantext.Components.Nodes.Annuaire.User (userLayout) @@ -38,13 +42,14 @@ import Gargantext.Components.TreeSearch (treeSearch) import Gargantext.Config (defaultFrontends, defaultBackends) import Gargantext.Context.Session as SessionContext import Gargantext.Ends (Backend) +import Gargantext.Hooks.LinkHandler (useLinkHandler) import Gargantext.Hooks.Resize (ResizeType(..), useResizeHandler) import Gargantext.Hooks.Session (useSession) -import Gargantext.Routes (AppRoute, Tile) +import Gargantext.Routes (AppRoute(..), Tile) import Gargantext.Routes as GR -import Gargantext.Sessions (Session, sessionId) +import Gargantext.Sessions (Session, sessionId, unSessions) import Gargantext.Sessions as Sessions -import Gargantext.Types (CorpusId, Handed(..), ListId, NodeID, NodeType(..), SessionId, SidePanelState(..)) +import Gargantext.Types (CorpusId, Handed(..), ListId, NodeID, NodeType(..), SessionId, SidePanelState(..), ID) import Gargantext.Utils ((?)) import Gargantext.Utils.Reactix (getElementById) import Gargantext.Utils.Reactix as R2 @@ -177,8 +182,7 @@ mainPageCpt = here.component "mainPage" cpt where H.div { className: "router__body main-page" } [ - Breadcrumb.component - { boxes } + Breadcrumb.component { } , H.div { className: intercalate " " @@ -358,6 +362,7 @@ renderRouteCpt = R.memo' $ here.component "renderRoute" cpt where GR.NodeTexts s n -> texts (sessionNodeProps s n) [] GR.UserPage s n -> user (sessionNodeProps s n) [] GR.ForgotPassword p -> forgotPassword {boxes, params: p} [] + GR.Share t n -> share {boxes, nodeType: t, nodeId: n} [] ] -------------------------------------------------------------- @@ -481,7 +486,6 @@ type CorpusDocumentProps = corpusDocument :: R2.Component CorpusDocumentProps corpusDocument = R.createElement corpusDocumentCpt - corpusDocumentCpt :: R.Component CorpusDocumentProps corpusDocumentCpt = here.component "corpusDocument" cpt where cpt props@{ corpusId, listId, nodeId } _ = do @@ -490,16 +494,16 @@ corpusDocumentCpt = here.component "corpusDocument" cpt where authedProps = Record.merge - { content: - \session -> - Document.node - { mCorpusId: Just corpusId - , listId - , nodeId - , key: show (sessionId session) <> "-" <> show nodeId - } - } - sessionProps + { content: + \session -> + Document.node + { mCorpusId: Just corpusId + , listId + , nodeId + , key: show (sessionId session) <> "-" <> show nodeId + } + } + sessionProps pure $ authed authedProps [] @@ -524,7 +528,6 @@ type DocumentProps = document :: R2.Component DocumentProps document = R.createElement documentCpt - documentCpt :: R.Component DocumentProps documentCpt = here.component "document" cpt where cpt props@{ listId, nodeId } _ = do @@ -616,12 +619,13 @@ listsCpt = here.component "lists" cpt where -------------------------------------------------------------- login' :: Boxes -> R.Element -login' { backend, sessions, showLogin: visible } = +login' { backend, sessions, showLogin: visible, loginRedirect } = login { backend , backends: A.fromFoldable defaultBackends , sessions , visible + , loginRedirect } -------------------------------------------------------------- @@ -767,3 +771,32 @@ forgotPasswordCpt = here.component "forgotPassword" cpt where let uuid = fromMaybe "" $ M.lookup "uuid" params pure $ forgotPasswordLayout { server, uuid } [] + +-------------------------------------------------------------- + +type ShareProps = (nodeType :: String, nodeId :: ID | Props) + +share :: R2.Component ShareProps +share = R.createElement shareCpt + +shareCpt :: R.Component ShareProps +shareCpt = here.component "share" cpt where + cpt { nodeType, nodeId, boxes} _ = do + { goToRoute } <- useLinkHandler + sessions' <- T.useLive T.unequal boxes.sessions + + case unSessions sessions' of + [] -> do + R.useEffect' $ T.write_ true boxes.showLogin + R.useEffect' $ T.write_ (Just (Tuple nodeType nodeId)) boxes.loginRedirect + R.useEffect' $ goToRoute Login + pure $ H.text "no session" + s -> case head s of + Just s' -> do + R.useEffect' $ goToRoute $ fromMaybe Login $ GR.nodeTypeAppRoute (fromMaybe Node $ read nodeType) (sessionId s') nodeId + pure $ H.text $ "session route: " <> (show $ fromMaybe Login $ GR.nodeTypeAppRoute (fromMaybe Node $ read nodeType) (sessionId s') nodeId) + Nothing -> do + R.useEffect' $ T.write_ true boxes.showLogin + R.useEffect' $ T.write_ (Just (Tuple nodeType nodeId)) boxes.loginRedirect + R.useEffect' $ goToRoute Login + pure $ H.text "no session" diff --git a/src/Gargantext/Components/TreeSearch.purs b/src/Gargantext/Components/TreeSearch.purs index 07e4293341016d8f6b8b588826054a46e2f51b0f..8e31b66c93f7e22fc2931f03ca7df76a9c7c1ccf 100644 --- a/src/Gargantext/Components/TreeSearch.purs +++ b/src/Gargantext/Components/TreeSearch.purs @@ -169,14 +169,15 @@ treeSearchRenderContainerCpt = here.component "treeSearchRenderContainer" cpt wh treeSearchRender :: R2.Leaf RenderProps treeSearchRender = R2.leaf treeSearchRenderCpt - treeSearchRenderCpt :: R.Component RenderProps treeSearchRenderCpt = here.component "treeSearchRenderCpt" cpt where cpt { visible, session, searchData, goToRoute } _ = do + { route } <- AppStore.use + route' <- T.useLive T.unequal route - pure $ H.div {className: "search-modal__results"} (results searchData) + pure $ H.div {className: "search-modal__results"} (results route' searchData) where - results s = map searchResult s + results route' s = map searchResult s where searchResult sd = H.div { className: "result py-1"} @@ -195,9 +196,9 @@ treeSearchRenderCpt = here.component "treeSearchRenderCpt" cpt where , H.div {} [ H.text " Path: " - , breadcrumbView { nodeId: sd.id - , session: Just session - , format: "text" + , breadcrumbView { format: "text" + , route: route' + , session } ] ] @@ -218,10 +219,10 @@ treeSearchRenderCpt = here.component "treeSearchRenderCpt" cpt where H.span { className: "node-path small" } [ H.text " — " - , breadcrumbView { nodeId: sd.id - , session: Just session - , format: "text" - } + , breadcrumbView { format: "text" + , route: route' + , session: session + } ] ] diff --git a/src/Gargantext/Ends.purs b/src/Gargantext/Ends.purs index db3e7fceb1f07ead60ba3c1fef269257cba1c7ad..a09d7dc48eb10e85d353b12a3841e2b195076f79 100644 --- a/src/Gargantext/Ends.purs +++ b/src/Gargantext/Ends.purs @@ -217,6 +217,7 @@ sessionPath (R.ChartHash { chartType, listId, tabType } i) = -- sessionPath (R.NodeAPI (NodeContact s a i) i) = sessionPath $ "annuaire/" <> show a <> "/contact/" <> show i sessionPath (R.PhyloAPI nId) = "node/" <> show nId <> "/phylo" sessionPath R.Members = "members" +sessionPath (R.ShareURL i t) = "shareurl?type=" <> show t <> "&id=" <> show i ------- misc routing stuff diff --git a/src/Gargantext/Router.purs b/src/Gargantext/Router.purs index c27232a2d47564a57dfabaf15d217ee54fac6237..a258986f9f8f4189dbd8268064edbfed037f5f0c 100644 --- a/src/Gargantext/Router.purs +++ b/src/Gargantext/Router.purs @@ -39,6 +39,7 @@ router = oneOf , RouteFrameCode <$> (route "code" *> sid) <*> int , RouteFrameVisio <$> (route "visio" *> sid) <*> int , RouteFile <$> (route "file" *> sid) <*> int + , Share <$> (route "share" *> str) <*> int , Home <$ lit "" ] where diff --git a/src/Gargantext/Routes.purs b/src/Gargantext/Routes.purs index c5679e2114ef43589b500791c08c19d744bb284f..203a65f48b5eedd795ad13b06b6f8bad793b11c0 100644 --- a/src/Gargantext/Routes.purs +++ b/src/Gargantext/Routes.purs @@ -2,11 +2,16 @@ module Gargantext.Routes where import Prelude +import Data.Argonaut as Argonaut import Data.Maybe (Maybe(..)) import Data.UUID (UUID) import Data.Map as M import Gargantext.Types (ChartOpts, ChartType, CorpusMetricOpts, CTabNgramType, Id, Limit, ListId, DocId, NgramsGetOpts, NgramsGetTableAllOpts, NodeType, Offset, OrderBy, SearchOpts, SessionId, TabSubType, TabType, TermList) import Gargantext.Types as GT +import Gargantext.Utils.SimpleJSON (encodeJsonArgonaut) +import GraphQL.Client.Args (class ArgGql) +import GraphQL.Client.Variables.TypeName (class VarTypeName) +import Simple.JSON as JSON data AppRoute = Annuaire SessionId Int @@ -25,7 +30,6 @@ data AppRoute | Lists SessionId Int | Login | NodeTexts SessionId Int - | TreeFlat SessionId Int String | PGraphExplorer SessionId Int | PhyloExplorer SessionId Int | RouteFile SessionId Int @@ -34,7 +38,9 @@ data AppRoute | RouteFrameVisio SessionId Int | RouteFrameWrite SessionId Int | Team SessionId Int + | TreeFlat SessionId Int String | UserPage SessionId Int + | Share String Int derive instance Eq AppRoute @@ -65,6 +71,7 @@ instance Show AppRoute where show (RouteFrameCode s i) = "code" <> show i <> " (" <> show s <> ")" show (RouteFrameVisio s i) = "visio" <> show i <> " (" <> show s <> ")" show (RouteFile s i) = "file" <> show i <> " (" <> show s <> ")" + show (Share n i) = "share" <> show n <> show i appPath :: AppRoute -> String @@ -94,6 +101,7 @@ appPath (RouteFrameCalc s i) = "calc/" <> show s <> "/" <> show i appPath (RouteFrameCode s i) = "code/" <> show s <> "/" <> show i appPath (RouteFrameVisio s i) = "visio/" <> show s <> "/" <> show i appPath (RouteFile s i) = "file/" <> show s <> "/" <> show i +appPath (Share n i) = "share/" <> show n <> "/" <> show i nodeTypeAppRoute :: NodeType -> SessionId -> Int -> Maybe AppRoute nodeTypeAppRoute GT.Annuaire s i = Just $ Annuaire s i @@ -117,6 +125,7 @@ nodeTypeAppRoute GT.NodeFrameVisio s i = Just $ RouteFrameVisio s i nodeTypeAppRoute _ _ _ = Nothing + data SessionRoute = Tab TabType (Maybe Id) | Children NodeType Offset Limit (Maybe OrderBy) (Maybe Id) @@ -141,6 +150,7 @@ data SessionRoute -- | AnnuaireContact AnnuaireId DocId | PhyloAPI Id | Members + | ShareURL Id NodeType ------------------------------------------------------ diff --git a/src/Gargantext/Sessions/Types.purs b/src/Gargantext/Sessions/Types.purs index d7a7a65a8f5e016a226d92f657f2fdb5438c1109..ca9fd9b698196c59d6fb276f45de38335423c9f2 100644 --- a/src/Gargantext/Sessions/Types.purs +++ b/src/Gargantext/Sessions/Types.purs @@ -62,9 +62,7 @@ instance JSON.WriteForeign Session where JSON.writeImpl { backend, caches: caches', token, treeId, username, userId } where caches' = JSON.writeImpl $ Object.fromFoldable (GUT.first show <$> Map.toUnfoldable caches :: Array (Tuple String NT.CacheState)) - instance Eq Session where eq = genericEq - instance Show Session where show (Session {backend, username}) = username <> "@" <> (cleanBackendUrl backend) @@ -74,7 +72,6 @@ cleanBackendUrl (Backend {baseUrl}) = $ DST.replace (DST.Pattern "https://") (DST.Replacement "") baseUrl instance ToUrl Session SessionRoute where toUrl (Session {backend}) r = backendUrl backend (sessionPath r) - instance ToUrl Session NodePath where toUrl (Session {backend}) np = backendUrl backend (nodePath np) instance ToUrl Session String where toUrl = sessionUrl diff --git a/src/Gargantext/Types.purs b/src/Gargantext/Types.purs index 206f3e63c05562cabd295541c0b87ae5b3685bea..8a35302a50d923856898ad1e4a86750a97148e6e 100644 --- a/src/Gargantext/Types.purs +++ b/src/Gargantext/Types.purs @@ -2,6 +2,7 @@ module Gargantext.Types where import Gargantext.Prelude +import Data.Argonaut as Argonaut import Data.Array as A import Data.Eq.Generic (genericEq) import Data.Generic.Rep (class Generic) @@ -16,6 +17,7 @@ import Foreign as F import Gargantext.Components.Lang (class Translate, Lang(..)) import Gargantext.Config.REST (RESTError, AffRESTError) import Gargantext.Utils.Glyphicon (classNamePrefix, glyphiconToCharCode) +import Gargantext.Utils.SimpleJSON (encodeJsonArgonaut) import GraphQL.Client.Args (class ArgGql) import GraphQL.Client.Variables.TypeName (class VarTypeName) import Prim.Row (class Union) @@ -169,6 +171,8 @@ instance JSON.ReadForeign NodeType where Nothing -> F.fail $ F.ErrorAtProperty s $ F.ForeignError "unknown property" Just nt -> pure nt instance JSON.WriteForeign NodeType where writeImpl = JSON.writeImpl <<< show +instance Argonaut.EncodeJson NodeType where encodeJson = encodeJsonArgonaut +instance ArgGql String NodeType instance ArgGql NodeType NodeType instance VarTypeName NodeType where varTypeName _ = "NodeType!" @@ -237,32 +241,31 @@ prettyNodeType Url_Document = "Document" instance Read NodeType where - read "NodeUser" = Just NodeUser + read "Calc" = Just Calc + read "Context" = Just Context + read "Document" = Just Url_Document + read "Individu" = Just Individu + read "Node" = Just Node + read "NodeAnnuaire" = Just Annuaire + read "NodeContact" = Just NodeContact + read "NodeCorpus" = Just Corpus + read "NodeDashboard" = Just Dashboard + read "NodeFile" = Just NodeFile read "NodeFolder" = Just Folder read "NodeFolderPrivate" = Just FolderPrivate - read "NodeFolderShared" = Just FolderShared read "NodeFolderPublic" = Just FolderPublic - read "NodeAnnuaire" = Just Annuaire - read "NodeDashboard" = Just Dashboard - read "Document" = Just Url_Document + read "NodeFolderShared" = Just FolderShared + read "NodeFrameNotebook" = Just NodeFrameNotebook + read "NodeFrameVisio" = Just NodeFrameVisio read "NodeGraph" = Just Graph + read "NodeList" = Just NodeList read "NodePhylo" = Just Phylo - read "Individu" = Just Individu - read "Node" = Just Node - read "Nodes" = Just Nodes - read "Context" = Just Context - read "NodeCorpus" = Just Corpus - read "NodeContact" = Just NodeContact - read "Tree" = Just Tree read "NodeTeam" = Just Team - read "NodeList" = Just NodeList read "NodeTexts" = Just NodeTexts - read "Annuaire" = Just Annuaire - read "Notes" = Just Notes - read "Calc" = Just Calc - read "NodeFrameNotebook" = Just NodeFrameNotebook - read "NodeFrameVisio" = Just NodeFrameVisio - read "NodeFile" = Just NodeFile + read "NodeUser" = Just NodeUser + read "Nodes" = Just Nodes + read "Notes" = Just Notes + read "Tree" = Just Tree -- TODO NodePublic read ? read _ = Nothing diff --git a/src/Gargantext/Utils/SimpleJSON.purs b/src/Gargantext/Utils/SimpleJSON.purs index 222f08b5124a197e5bb54e421bf9ed76d48191c9..03e2a4af8db53fbd153f9167482e46dc234cfd0d 100644 --- a/src/Gargantext/Utils/SimpleJSON.purs +++ b/src/Gargantext/Utils/SimpleJSON.purs @@ -4,6 +4,8 @@ import Prelude import Control.Alt ((<|>)) import Control.Monad.Except (throwError, withExcept) +import Data.Argonaut as Argonaut +import Data.Either (fromRight) import Data.Generic.Rep as GR import Data.List as L import Data.List.Types (NonEmptyList(..)) @@ -96,3 +98,8 @@ instance untaggedSumRepArgument :: throwJSONError :: forall a. Foreign.ForeignError -> Foreign.F a throwJSONError err = throwError $ NonEmptyList $ NonEmpty err L.Nil + + +-- A SimpleJSON.ReadForeign instance should is also compatible with argonaut +encodeJsonArgonaut :: forall a. JSON.WriteForeign a => a -> Argonaut.Json +encodeJsonArgonaut x = fromRight Argonaut.jsonEmptyObject $ Argonaut.jsonParser $ JSON.writeJSON x