Commit bd44a928 authored by Alexandre Delanoë's avatar Alexandre Delanoë

Merge branch 'dev-community' into dev-merge

parents 50bd539c e6f129de
-- TODO: this module should be replaced by FacetsTable
module Gargantext.Components.Category where
import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, jsonEmptyObject, (.:), (:=), (~>), encodeJson)
import Data.Array as A
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Eq (genericEq)
import Data.Generic.Rep.Show (genericShow)
import Data.Lens ((^.))
import Data.Lens.At (at)
import Data.Lens.Record (prop)
import Data.List as L
import Data.Map (Map)
import Data.Map as Map
import Data.Maybe (Maybe(..), fromMaybe, isJust)
import Data.Ord.Down (Down(..))
import Data.Set (Set)
import Data.Set as Set
import Data.String as Str
import Data.Symbol (SProxy(..))
import Data.Tuple (Tuple(..), fst)
import Data.Tuple.Nested ((/\))
import DOM.Simple.Event as DE
import Effect (Effect)
import Effect.Aff (Aff, launchAff)
import Effect.Class (liftEffect)
import Reactix as R
import Reactix.DOM.HTML as H
------------------------------------------------------------------------
import Gargantext.Prelude
import Gargantext.Ends (Frontends, url)
import Gargantext.Hooks.Loader (useLoaderWithCacheAPI, HashedResponse(..))
import Gargantext.Utils.List (sortWith) as L
import Gargantext.Utils.Reactix as R2
import Gargantext.Routes as Routes
import Gargantext.Routes (SessionRoute(NodeAPI))
import Gargantext.Sessions (Session, sessionId, get, delete, put)
import Gargantext.Types (NodeType(..), OrderBy(..), TableResult, TabType, showTabType')
import Gargantext.Utils.CacheAPI as GUC
------------------------------------------------------------------------
data Category = Trash | UnRead | Checked | Topic | Favorite
categories :: Array Category
categories = [Trash, UnRead, Checked, Topic, Favorite]
derive instance genericFavorite :: Generic Category _
instance showCategory :: Show Category where
show = genericShow
instance eqCategory :: Eq Category where
eq = genericEq
instance decodeJsonCategory :: DecodeJson Category where
decodeJson json = do
obj <- decodeJson json
pure $ decodeCategory obj
instance encodeJsonCategory :: EncodeJson Category where
encodeJson cat = encodeJson (cat2score cat)
favCategory :: Category -> Category
favCategory Favorite = Topic
favCategory _ = Favorite
trashCategory :: Category -> Category
trashCategory _ = Trash
-- TODO: ?
--trashCategory Trash = UnRead
decodeCategory :: Int -> Category
decodeCategory 0 = Trash
decodeCategory 1 = UnRead
decodeCategory 2 = Checked
decodeCategory 3 = Topic
decodeCategory 4 = Favorite
decodeCategory _ = UnRead
cat2score :: Category -> Int
cat2score Trash = 0
cat2score UnRead = 1
cat2score Checked = 2
cat2score Topic = 3
cat2score Favorite = 4
-- caroussel :: Category -> R.Element
caroussel session nodeId setLocalCategories r cat = H.div {className:"flex"} divs
where
divs = map (\c -> if cat == c
then
H.div { className : icon c (cat == c) } []
else
H.div { className : icon c (cat == c)
, on: { click: onClick c}
} []
) (caroussel' cat)
caroussel' :: Category -> Array Category
caroussel' Trash = A.take 2 categories
caroussel' c = A.take 3 $ A.drop (cat2score c - 1 ) categories
onClick c = \_-> do
setLocalCategories $ Map.insert r._id c
void $ launchAff $ putCategories session nodeId $ CategoryQuery {nodeIds: [r._id], category: c}
icon :: Category -> Boolean -> String
icon cat b = btn b $ "glyphicon glyphicon-" <> (color $ size b $ icon' cat b)
where
icon' :: Category -> Boolean -> String
icon' Trash false = "remove"
icon' Trash true = "remove-sign"
icon' UnRead true = "question-sign"
icon' UnRead false = "question-sign"
icon' Checked true = "ok-sign"
icon' Checked false = "ok"
icon' Topic true = "star"
icon' Topic false = "star-empty"
icon' Favorite true = "heart"
icon' Favorite false = "heart-empty"
size :: Boolean -> String -> String
size true s = s <> " btn-lg"
size false s = s <> " btn-xs"
color :: String -> String
color x = x <> " text-primary"
btn :: Boolean -> String -> String
btn true s = s
btn false s = "btn " <> s
newtype CategoryQuery = CategoryQuery {
nodeIds :: Array Int
, category :: Category
}
instance encodeJsonCategoryQuery :: EncodeJson CategoryQuery where
encodeJson (CategoryQuery post) =
"ntc_nodesId" := post.nodeIds
~> "ntc_category" := encodeJson post.category
~> jsonEmptyObject
categoryRoute :: Int -> SessionRoute
categoryRoute nodeId = NodeAPI Node (Just nodeId) "category"
putCategories :: Session -> Int -> CategoryQuery -> Aff (Array Int)
putCategories session nodeId = put session $ categoryRoute nodeId
......@@ -28,7 +28,7 @@ import Reactix as R
import Reactix.DOM.HTML as H
------------------------------------------------------------------------
import Gargantext.Prelude
import Gargantext.Components.Category
import Gargantext.Components.Table as T
import Gargantext.Ends (Frontends, url)
import Gargantext.Hooks.Loader (useLoaderWithCacheAPI, HashedResponse(..))
......@@ -41,117 +41,6 @@ import Gargantext.Types (NodeType(..), OrderBy(..), TableResult, TabType, showTa
import Gargantext.Utils.CacheAPI as GUC
------------------------------------------------------------------------
data Category = Trash | UnRead | Checked | Topic | Favorite
categories :: Array Category
categories = [Trash, UnRead, Checked, Topic, Favorite]
derive instance genericFavorite :: Generic Category _
instance showCategory :: Show Category where
show = genericShow
instance eqCategory :: Eq Category where
eq = genericEq
instance decodeJsonCategory :: DecodeJson Category where
decodeJson json = do
obj <- decodeJson json
pure $ decodeCategory obj
instance encodeJsonCategory :: EncodeJson Category where
encodeJson cat = encodeJson (cat2score cat)
favCategory :: Category -> Category
favCategory Favorite = Topic
favCategory _ = Favorite
trashCategory :: Category -> Category
trashCategory _ = Trash
-- TODO: ?
--trashCategory Trash = UnRead
decodeCategory :: Int -> Category
decodeCategory 0 = Trash
decodeCategory 1 = UnRead
decodeCategory 2 = Checked
decodeCategory 3 = Topic
decodeCategory 4 = Favorite
decodeCategory _ = UnRead
cat2score :: Category -> Int
cat2score Trash = 0
cat2score UnRead = 1
cat2score Checked = 2
cat2score Topic = 3
cat2score Favorite = 4
-- caroussel :: Category -> R.Element
caroussel session nodeId setLocalCategories r cat = H.div {className:"flex"} divs
where
divs = map (\c -> if cat == c
then
H.div { className : icon c (cat == c) } []
else
H.div { className : icon c (cat == c)
, on: { click: onClick c}
} []
) (caroussel' cat)
caroussel' :: Category -> Array Category
caroussel' Trash = A.take 2 categories
caroussel' c = A.take 3 $ A.drop (cat2score c - 1 ) categories
onClick c = \_-> do
setLocalCategories $ Map.insert r._id c
void $ launchAff $ putCategories session nodeId $ CategoryQuery {nodeIds: [r._id], category: c}
icon :: Category -> Boolean -> String
icon cat b = btn b $ "glyphicon glyphicon-" <> (color $ size b $ icon' cat b)
where
icon' :: Category -> Boolean -> String
icon' Trash false = "remove"
icon' Trash true = "remove-sign"
icon' UnRead true = "question-sign"
icon' UnRead false = "question-sign"
icon' Checked true = "ok-sign"
icon' Checked false = "ok"
icon' Topic true = "star"
icon' Topic false = "star-empty"
icon' Favorite true = "heart"
icon' Favorite false = "heart-empty"
size :: Boolean -> String -> String
size true s = s <> " btn-lg"
size false s = s <> " btn-xs"
color :: String -> String
color x = x <> " text-primary"
btn :: Boolean -> String -> String
btn true s = s
btn false s = "btn " <> s
newtype CategoryQuery = CategoryQuery {
nodeIds :: Array Int
, category :: Category
}
instance encodeJsonCategoryQuery :: EncodeJson CategoryQuery where
encodeJson (CategoryQuery post) =
"ntc_nodesId" := post.nodeIds
~> "ntc_category" := encodeJson post.category
~> jsonEmptyObject
categoryRoute :: Int -> SessionRoute
categoryRoute nodeId = NodeAPI Node (Just nodeId) "category"
putCategories :: Session -> Int -> CategoryQuery -> Aff (Array Int)
putCategories session nodeId = put session $ categoryRoute nodeId
type TotalRecords = Int
type LayoutProps =
......@@ -198,10 +87,16 @@ newtype DocumentsView
, url :: String
}
{-
derive instance genericDocumentsView :: Generic DocumentsView _
instance showDocumentsView :: Show DocumentsView where
show = genericShow
instance decodeJsonSearchType :: Argonaut.DecodeJson SearchType where
decodeJson = genericSumDecodeJson
instance encodeJsonSearchType :: Argonaut.EncodeJson SearchType where
encodeJson = genericSumEncodeJson
-}
instance decodeDocumentsView :: DecodeJson DocumentsView where
decodeJson json = do
obj <- decodeJson json
......@@ -230,6 +125,7 @@ newtype Response = Response
, hyperdata :: Hyperdata
, category :: Category
, ngramCount :: Int
, title :: String
}
......@@ -252,10 +148,11 @@ instance decodeResponse :: DecodeJson Response where
decodeJson json = do
obj <- decodeJson json
cid <- obj .: "id"
favorite <- obj .: "favorite"
category <- obj .: "category"
ngramCount <- obj .: "id"
title <- obj .: "title"
hyperdata <- obj .: "hyperdata"
pure $ Response { cid, category: decodeCategory favorite, ngramCount, hyperdata }
pure $ Response { cid, title, category: decodeCategory category, ngramCount, hyperdata }
docViewLayout :: Record LayoutProps -> R.Element
......
This diff is collapsed.
......@@ -23,7 +23,8 @@ import Gargantext.Components.Forest.Tree.Node.Action.Move (moveNodeReq)
import Gargantext.Components.Forest.Tree.Node.Action.Merge (mergeNodeReq)
import Gargantext.Components.Forest.Tree.Node.Action.Link (linkNodeReq)
import Gargantext.Components.Forest.Tree.Node.Action.Rename (RenameValue(..), rename)
import Gargantext.Components.Forest.Tree.Node.Action.Share as Share
import Gargantext.Components.Forest.Tree.Node.Action.Share as Share
import Gargantext.Components.Forest.Tree.Node.Action.Contact as Contact
import Gargantext.Components.Forest.Tree.Node.Action.Update (updateRequest)
import Gargantext.Components.Forest.Tree.Node.Action.Upload (uploadFile)
import Gargantext.Components.Forest.Tree.Node.Tools.FTree (FTree, LNode(..), NTree(..))
......@@ -289,6 +290,7 @@ performAction (ShareTeam username) p@{ reload: (_ /\ setReload)
do
void $ Share.shareReq session id $ Share.ShareTeamParams {username}
performAction (SharePublic {params}) p@{ session
, openNodes: (_ /\ setOpenNodes)
} =
......@@ -299,6 +301,15 @@ performAction (SharePublic {params}) p@{ session
liftEffect $ setOpenNodes (Set.insert (mkNodeId session out))
performAction RefreshTree p
performAction (AddContact params) p@{ reload: (_ /\ setReload)
, session
, tree: (NTree (LNode {id}) _)
} =
void $ Contact.contactReq session id params
-------
performAction (AddNode name nodeType) p@{ openNodes: (_ /\ setOpenNodes)
, reload: (_ /\ setReload)
......
......@@ -9,7 +9,7 @@ import Gargantext.Components.Forest.Tree.Node.Tools.SubTree.Types (SubTreeOut, S
import Gargantext.Components.Forest.Tree.Node.Settings (NodeAction(..), glyphiconNodeAction)
import Gargantext.Components.Forest.Tree.Node.Action.Upload.Types (FileType, UploadFileContents)
import Gargantext.Components.Forest.Tree.Node.Action.Update.Types (UpdateNodeParams)
import Gargantext.Components.Forest.Tree.Node.Action.Contact.Types (AddContactParams)
type Props =
( dispatch :: Action -> Aff Unit
......@@ -29,6 +29,7 @@ data Action = AddNode String GT.NodeType
| RefreshTree
| ShareTeam String
| AddContact AddContactParams
| SharePublic {params :: Maybe SubTreeOut}
| MoveNode {params :: Maybe SubTreeOut}
| MergeNode {params :: Maybe SubTreeOut}
......@@ -58,6 +59,7 @@ instance showShow :: Show Action where
show (RenameNode _ )= "RenameNode"
show (UpdateNode _ )= "UpdateNode"
show (ShareTeam _ )= "ShareTeam"
show (AddContact _ )= "AddContact"
show (SharePublic _ )= "SharePublic"
show (DoSearch _ )= "SearchQuery"
show (UploadFile _ _ _ _)= "UploadFile"
......@@ -74,15 +76,16 @@ icon (AddNode _ _) = glyphiconNodeAction (Add [])
icon (DeleteNode _) = glyphiconNodeAction Delete
icon (RenameNode _) = glyphiconNodeAction Config
icon (UpdateNode _) = glyphiconNodeAction Refresh
icon (ShareTeam _) = glyphiconNodeAction Share
icon (ShareTeam _) = glyphiconNodeAction Share
icon (AddContact _) = glyphiconNodeAction Share
icon (SharePublic _ ) = glyphiconNodeAction (Publish { subTreeParams : SubTreeParams {showtypes:[], valitypes:[] }})
icon (DoSearch _) = glyphiconNodeAction SearchBox
icon (UploadFile _ _ _ _) = glyphiconNodeAction Upload
icon RefreshTree = glyphiconNodeAction Refresh
icon DownloadNode = glyphiconNodeAction Download
icon (MoveNode _ ) = glyphiconNodeAction (Move { subTreeParams : SubTreeParams {showtypes:[], valitypes:[] }})
icon (MoveNode _ ) = glyphiconNodeAction (Move { subTreeParams : SubTreeParams {showtypes:[], valitypes:[] }})
icon (MergeNode _ ) = glyphiconNodeAction (Merge { subTreeParams : SubTreeParams {showtypes:[], valitypes:[] }})
icon (LinkNode _ ) = glyphiconNodeAction (Link { subTreeParams : SubTreeParams {showtypes:[], valitypes:[] }})
icon (LinkNode _ ) = glyphiconNodeAction (Link { subTreeParams : SubTreeParams {showtypes:[], valitypes:[] }})
icon NoAction = "hand-o-right"
......@@ -94,6 +97,7 @@ text (DeleteNode _ )= "Delete !"
text (RenameNode _ )= "Rename !"
text (UpdateNode _ )= "Update !"
text (ShareTeam _ )= "Share with team !"
text (AddContact _ )= "Add contact !"
text (SharePublic _ )= "Publish !"
text (DoSearch _ )= "Launch search !"
text (UploadFile _ _ _ _)= "Upload File !"
......
module Gargantext.Components.Forest.Tree.Node.Action.Contact where
import Data.Maybe (Maybe(..))
import Data.Tuple.Nested ((/\))
import Effect.Aff (Aff, launchAff)
import Effect.Uncurried (mkEffectFn1)
import Gargantext.Components.Forest.Tree.Node.Action (Action)
import Gargantext.Components.Forest.Tree.Node.Action.Contact.Types (AddContactParams(..))
-- import Gargantext.Components.Forest.Tree.Node.Tools.SubTree (subTreeView, SubTreeParamsIn)
import Gargantext.Prelude (Unit, bind, const, discard, pure, (<<<), (<>))
import Gargantext.Routes as GR
import Gargantext.Sessions (Session, post)
import Gargantext.Types (ID)
import Gargantext.Types as GT
import Gargantext.Utils.Reactix as R2
import Prelude (($))
import Reactix as R
import Reactix.DOM.HTML as H
------------------------------------------------------------------------
contactReq :: Session -> ID -> AddContactParams -> Aff ID
contactReq session nodeId =
post session $ GR.NodeAPI GT.Annuaire (Just nodeId) "contact"
------------------------------------------------------------------------
type TextInputBoxProps =
( id :: ID
, dispatch :: Action -> Aff Unit
, params :: Record AddContactProps
, isOpen :: R.State Boolean
, boxName :: String
, boxAction :: AddContactParams -> Action
)
type AddContactProps = ( firstname :: String, lastname :: String)
textInputBox :: Record TextInputBoxProps -> R.Element
textInputBox p@{ boxName, boxAction, dispatch, isOpen: (true /\ setIsOpen), params } = R.createElement el p []
where
{firstname, lastname} = params
el = R.hooksComponent (boxName <> "Box") cpt
cpt {id, params:params'} _ = do
let {firstname, lastname} = params'
stateFirstname <- R.useState' firstname
stateLastname <- R.useState' lastname
pure $ H.div {className: "from-group row-no-padding"}
[ textInput stateFirstname firstname
, textInput stateLastname lastname
, submitBtn stateFirstname stateLastname
, cancelBtn
]
where
textInput (_ /\ set) default =
H.div {className: "col-md-8"}
[ H.input { type: "text"
, placeholder: (boxName <> " Node")
, defaultValue: default
, className: "form-control"
, onInput: mkEffectFn1 $ set
<<< const
<<< R2.unsafeEventValue
}
]
submitBtn (val1 /\ _) (val2 /\ _) =
H.a {className: "btn glyphitem glyphicon glyphicon-ok col-md-2 pull-left"
, type: "button"
, onClick: mkEffectFn1 $ \_ -> do
setIsOpen $ const false
launchAff $ dispatch ( boxAction (AddContactParams {firstname:val1, lastname:val2} ))
, title: "Submit"
} []
cancelBtn =
H.a {className: "btn text-danger glyphitem glyphicon glyphicon-remove col-md-2 pull-left"
, type: "button"
, onClick: mkEffectFn1 $ \_ -> setIsOpen $ const false
, title: "Cancel"
} []
textInputBox p@{ boxName, isOpen: (false /\ _) } = R.createElement el p []
where
el = R.hooksComponent (boxName <> "Box") cpt
cpt {} _ = pure $ H.div {} []
module Gargantext.Components.Forest.Tree.Node.Action.Contact.Types where
import Data.Argonaut (class EncodeJson, jsonEmptyObject, (:=), (~>))
import Data.Maybe (Maybe(..))
import Effect.Aff (Aff)
import Prelude (($))
import Reactix as R
import Gargantext.Types as GT
import Gargantext.Types (ID)
import Gargantext.Routes as GR
import Gargantext.Sessions (Session, post)
import Data.Maybe (Maybe(..))
import Data.Tuple.Nested ((/\))
import Effect.Aff (Aff)
import Gargantext.Prelude
import Gargantext.Sessions (Session, put_)
import Gargantext.Types as GT
import Reactix as R
import Reactix.DOM.HTML as H
import Data.Argonaut as Argonaut
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)
import Gargantext.Utils.Argonaut (genericSumDecodeJson, genericSumEncodeJson, genericEnumDecodeJson, genericEnumEncodeJson)
import Data.Maybe (Maybe(..))
import Gargantext.Prelude (class Eq, class Read, class Show)
------------------------------------------------------------------------
data AddContactParams =
AddContactParams { firstname :: String
, lastname :: String
}
derive instance eqAddContactParams :: Eq AddContactParams
derive instance genericAddContactParams :: Generic AddContactParams _
instance showAddContactParams :: Show AddContactParams where
show = genericShow
instance decodeJsonAddContactParams :: Argonaut.DecodeJson AddContactParams where
decodeJson = genericSumDecodeJson
instance encodeJsonAddContactParams :: Argonaut.EncodeJson AddContactParams where
encodeJson = genericSumEncodeJson
------------------------------------------------------------------------
......@@ -16,7 +16,7 @@ import Reactix.DOM.HTML as H
linkNodeReq :: Session -> GT.ID -> GT.ID -> Aff (Array GT.ID)
linkNodeReq session fromId toId =
put_ session $ NodeAPI GT.Node (Just fromId) ("link/" <> show toId)
put_ session $ NodeAPI GT.Node (Just fromId) ("pairWith/" <> show toId)
linkNode :: Record SubTreeParamsIn -> R.Element
linkNode p = R.createElement linkNodeCpt p []
......
......@@ -24,7 +24,7 @@ newtype RenameValue = RenameValue
instance encodeJsonRenameValue :: EncodeJson RenameValue where
encodeJson (RenameValue {text})
= "r_name" := text
= "name" := text
~> jsonEmptyObject
------------------------------------------------------------------------
module Gargantext.Components.Forest.Tree.Node.Action.Share where
import Data.Argonaut (class EncodeJson, jsonEmptyObject, (:=), (~>))
import Data.Maybe (Maybe(..))
import Effect.Aff (Aff)
import Prelude (($))
import Reactix as R
import Gargantext.Components.Forest.Tree.Node.Action (Action)
import Gargantext.Components.Forest.Tree.Node.Action as Action
import Gargantext.Types as GT
import Gargantext.Types (ID)
import Gargantext.Routes as GR
import Gargantext.Sessions (Session, post)
import Gargantext.Components.Forest.Tree.Node.Tools as Tools
import Data.Argonaut as Argonaut
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)
import Data.Maybe (Maybe(..))
import Data.Tuple.Nested ((/\))
import Effect.Aff (Aff)
import Gargantext.Components.Forest.Tree.Node.Action (Action)
import Gargantext.Components.Forest.Tree.Node.Action as Action
import Gargantext.Components.Forest.Tree.Node.Tools (submitButton, panel)
import Gargantext.Components.Forest.Tree.Node.Tools as Tools
import Gargantext.Components.Forest.Tree.Node.Tools.SubTree (subTreeView, SubTreeParamsIn)
import Gargantext.Prelude
import Gargantext.Routes (SessionRoute(..))
import Gargantext.Sessions (Session, put_)
import Gargantext.Prelude (class Eq, class Show, bind, pure)
import Gargantext.Routes as GR
import Gargantext.Sessions (Session, post)
import Gargantext.Types (ID)
import Gargantext.Types as GT
import Gargantext.Utils.Argonaut (genericSumDecodeJson, genericSumEncodeJson)
import Prelude (($))
import Reactix as R
import Reactix.DOM.HTML as H
import Data.Argonaut as Argonaut
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)
import Gargantext.Utils.Argonaut (genericSumDecodeJson, genericSumEncodeJson, genericEnumDecodeJson, genericEnumEncodeJson)
import Data.Maybe (Maybe(..))
import Gargantext.Prelude (class Eq, class Read, class Show)
------------------------------------------------------------------------
shareReq :: Session -> ID -> ShareNodeParams -> Aff ID
shareReq session nodeId =
......@@ -76,11 +62,11 @@ shareNodeCpt = R.hooksComponent "G.C.F.T.N.A.M.shareNode" cpt
let button = case valAction of
Action.SharePublic {params} -> case params of
Just val -> submitButton (Action.SharePublic {params: Just val}) dispatch
Just val -> Tools.submitButton (Action.SharePublic {params: Just val}) dispatch
Nothing -> H.div {} []
_ -> H.div {} []
pure $ panel [ subTreeView { action
pure $ Tools.panel [ subTreeView { action
, dispatch
, id
, nodeType
......
......@@ -34,6 +34,11 @@ actionUpload NodeList id session dispatch =
actionUpload Corpus id session dispatch =
pure $ uploadFileView {dispatch, id, nodeType: Corpus, session}
{-
actionUpload Annuaire id session dispatch =
pure $ uploadFileView {dispatch, id, nodeType: Annuaire, session}
-}
actionUpload _ _ _ _ =
pure $ fragmentPT $ "Soon, upload for this NodeType."
......@@ -276,7 +281,11 @@ uploadFile session nodeType id fileType {mName, contents: UploadFileContents con
where
q = FileUploadQuery { fileType: fileType }
--p = NodeAPI GT.Corpus (Just id) $ "add/file/async/nobody" <> Q.print (toQuery q)
p = GR.NodeAPI nodeType (Just id) $ GT.asyncTaskTypePath GT.Form
p = case nodeType of
Corpus -> GR.NodeAPI nodeType (Just id) $ GT.asyncTaskTypePath GT.Form
Annuaire -> GR.NodeAPI nodeType (Just id) "annuaire"
_ -> GR.NodeAPI nodeType (Just id) ""
bodyParams = [ Tuple "_wf_data" (Just contents)
, Tuple "_wf_filetype" (Just $ show fileType)
, Tuple "_wf_name" mName
......
......@@ -11,7 +11,7 @@ import Reactix as R
import Reactix.DOM.HTML as H
import Gargantext.Prelude
import Gargantext.Components.Forest.Tree.Node.Action (Action)
import Gargantext.Components.Forest.Tree.Node.Action (Action(..))
import Gargantext.Components.Forest.Tree.Node.Action.Add (NodePopup(..), addNodeView)
import Gargantext.Components.Forest.Tree.Node.Action.Delete (actionDelete)
import Gargantext.Components.Forest.Tree.Node.Action.Documentation (actionDoc)
......@@ -19,7 +19,8 @@ import Gargantext.Components.Forest.Tree.Node.Action.Download (actionDownload)
import Gargantext.Components.Forest.Tree.Node.Action.Rename (renameAction)
import Gargantext.Components.Forest.Tree.Node.Action.Search (actionSearch)
import Gargantext.Components.Forest.Tree.Node.Action.Search.SearchField (defaultSearch)
import Gargantext.Components.Forest.Tree.Node.Action.Share as Share
import Gargantext.Components.Forest.Tree.Node.Action.Share as Share
import Gargantext.Components.Forest.Tree.Node.Action.Contact as Contact
import Gargantext.Components.Forest.Tree.Node.Action.Update (update)
import Gargantext.Components.Forest.Tree.Node.Action.Upload (actionUpload)
import Gargantext.Components.Forest.Tree.Node.Action.Move (moveNode)
......@@ -298,6 +299,18 @@ panelActionCpt = R.hooksComponent "G.C.F.T.N.B.panelAction" cpt
}
]
cpt {action : AddingContact, dispatch, id, name } _ = do
isOpen <- R.useState' true
pure $ Contact.textInputBox { id
, dispatch
, isOpen
, boxName:"addContact"
, params : {firstname:"First Name", lastname: "Last Name"}
, boxAction: \p -> AddContact p
}
cpt {action : Publish {subTreeParams}, dispatch, id, nodeType, session } _ = do
pure $ Share.shareNode {dispatch, id, nodeType, session, subTreeParams}
......
......@@ -26,6 +26,7 @@ data NodeAction = Documentation NodeType
| Move { subTreeParams :: SubTreeParams }
| Link { subTreeParams :: SubTreeParams }
| Clone
| AddingContact
------------------------------------------------------------------------
instance eqNodeAction :: Eq NodeAction where
......@@ -43,6 +44,7 @@ instance eqNodeAction :: Eq NodeAction where
eq (Merge x) (Merge y) = x == y
eq Config Config = true
eq (Publish x) (Publish y) = x == y
eq AddingContact AddingContact = true
eq _ _ = false
instance showNodeAction :: Show NodeAction where
......@@ -60,6 +62,7 @@ instance showNodeAction :: Show NodeAction where
show (Add xs) = foldl (\a b -> a <> show b) "Add " xs
show (Merge t) = "Merge with subtree" <> show t
show (Publish x) = "Publish" <> show x
show AddingContact = "AddingContact"
glyphiconNodeAction :: NodeAction -> String
glyphiconNodeAction (Documentation _) = "question-circle"
......@@ -73,6 +76,7 @@ glyphiconNodeAction (Merge _) = "random"
glyphiconNodeAction Refresh = "refresh"
glyphiconNodeAction Config = "wrench"
glyphiconNodeAction Share = "user-plus"
glyphiconNodeAction AddingContact = "user-plus"
glyphiconNodeAction (Move _) = "share-square-o"
glyphiconNodeAction (Publish _) = fldr FolderPublic true
glyphiconNodeAction _ = ""
......@@ -184,7 +188,7 @@ settingsBox Texts =
, buttons : [ Refresh
, Upload
, Download
-- , Delete
, Delete
]
}
......@@ -265,6 +269,7 @@ settingsBox Annuaire =
, edit : true
, doc : Documentation Annuaire
, buttons : [ Upload
, AddingContact
, Move moveParameters
, Delete
]
......
......@@ -3,7 +3,7 @@ module Gargantext.Components.GraphExplorer.Sidebar
where
import Control.Parallel (parTraverse)
import Data.Array (head, last)
import Data.Array (head, last, concat)
import Data.Int (fromString)
import Data.Map as Map
import Data.Maybe (Maybe(..), fromJust)
......@@ -14,6 +14,7 @@ import Data.Tuple.Nested ((/\))
import Effect (Effect)
import Effect.Aff (Aff, launchAff_)
import Effect.Class (liftEffect)
import Gargantext.Components.Search (SearchType(..), SearchQuery(..))
import Gargantext.Components.GraphExplorer.Types as GET
import Gargantext.Components.GraphExplorer.Types (SidePanelState(..), SideTab(..))
import Gargantext.Components.GraphExplorer.Legend as Legend
......@@ -102,7 +103,8 @@ sideTab (Opened SideTabData) props =
]
, RH.div { className: "col-md-12", id: "query" }
[ query props.frontends
[ query SearchDoc
props.frontends
props.metaData
props.session
nodesMap
......@@ -149,11 +151,19 @@ sideTab (Opened SideTabData) props =
snd props'.selectedNodeIds $ const SigmaxT.emptyNodeIds
sideTab (Opened SideTabCommunity) props =
RH.div { className: "col-md-12", id: "query" }
[ query SearchContact
props.frontends
props.metaData
props.session
(SigmaxT.nodesGraphMap props.graph)
props.selectedNodeIds
]
sideTab _ _ = H.div {} []
-------------------------------------------
badge :: R.State SigmaxT.NodeIds -> Record SigmaxT.Node -> R.Element
badge (_ /\ setNodeIds) {id, label} =
......@@ -192,7 +202,11 @@ deleteNodes { graphId, metaData, nodes, session, termList, treeReload } = do
Just (NTC.Versioned patch) -> do
liftEffect $ snd treeReload $ (+) 1
deleteNode :: TermList -> Session -> GET.MetaData -> Record SigmaxT.Node -> Aff NTC.VersionedNgramsPatches
deleteNode :: TermList
-> Session
-> GET.MetaData
-> Record SigmaxT.Node
-> Aff NTC.VersionedNgramsPatches
deleteNode termList session (GET.MetaData metaData) node = NTC.putNgramsPatches coreParams versioned
where
nodeId :: Int
......@@ -222,17 +236,26 @@ deleteNode termList session (GET.MetaData metaData) node = NTC.putNgramsPatches
patch_list :: NTC.Replace TermList
patch_list = NTC.Replace { new: termList, old: MapTerm }
query :: Frontends -> GET.MetaData -> Session -> SigmaxT.NodesMap -> R.State SigmaxT.NodeIds -> R.Element
query _ _ _ _ (selectedNodeIds /\ _) | Set.isEmpty selectedNodeIds = RH.div {} []
query frontends (GET.MetaData metaData) session nodesMap (selectedNodeIds /\ _) =
query :: SearchType
-> Frontends
-> GET.MetaData
-> Session
-> SigmaxT.NodesMap
-> R.State SigmaxT.NodeIds
-> R.Element
query _ _ _ _ _ (selectedNodeIds /\ _) | Set.isEmpty selectedNodeIds = RH.div {} []
query searchType frontends (GET.MetaData metaData) session nodesMap (selectedNodeIds /\ _) =
query' (head metaData.corpusId)
where
query' Nothing = RH.div {} []
query' (Just corpusId) = CGT.tabs { frontends
, session
, query: toQuery <$> Set.toUnfoldable selectedNodeIds
, sides: [side corpusId]
}
query' (Just corpusId) =
CGT.tabs { frontends
, session
, query: SearchQuery { query : concat $ toQuery <$> Set.toUnfoldable selectedNodeIds
, expected: searchType
}
, sides: [side corpusId]
}
toQuery id = case Map.lookup id nodesMap of
Nothing -> []
......@@ -255,5 +278,3 @@ query frontends (GET.MetaData metaData) session nodesMap (selectedNodeIds /\ _)
]
-}
module Gargantext.Components.Nodes.Annuaire where
import Prelude (bind, const, identity, pure, ($), (<$>), (<>))
import Data.Argonaut (class DecodeJson, decodeJson, (.:), (.:?))
import Data.Array as A
import Data.List as L
......@@ -8,17 +7,17 @@ import Data.Maybe (Maybe(..), maybe, fromMaybe)
import Data.Tuple (fst, snd)
import Data.Tuple.Nested ((/\))
import Effect.Aff (Aff)
import Reactix as R
import Reactix.DOM.HTML as H
import Gargantext.Components.Nodes.Annuaire.User.Contacts.Types as CT
import Gargantext.Components.Table as T
import Gargantext.Ends (url, Frontends)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Routes (SessionRoute(..))
import Gargantext.Routes as Routes
import Gargantext.Sessions (Session, sessionId, get)
import Gargantext.Types (NodeType(..), AffTableResult, TableResult)
import Gargantext.Hooks.Loader (useLoader)
import Prelude (bind, const, identity, pure, ($), (<$>), (<>))
import Reactix as R
import Reactix.DOM.HTML as H
newtype IndividuView =
CorpusView
......@@ -102,7 +101,7 @@ type PageProps =
, frontends :: Frontends
, pagePath :: R.State PagePath
-- , info :: AnnuaireInfo
, table :: TableResult CT.Contact
, table :: TableResult CT.NodeContact
)
page :: Record PageProps -> R.Element
......@@ -123,7 +122,7 @@ pageCpt = R.hooksComponent "LoadedAnnuairePage" cpt
, session }
, delete: false }) <$> L.fromFoldable docs
container = T.defaultContainer { title: "Annuaire" } -- TODO
colNames = T.ColumnName <$> [ "", "Name", "Company", "Service", "Role"]
colNames = T.ColumnName <$> [ "", "First Name", "Last Name", "Company", "Lab", "Role"]
wrapColElts = const identity
setParams f = snd pagePath $ \pp@{params: ps} ->
pp {params = f ps}
......@@ -132,9 +131,8 @@ pageCpt = R.hooksComponent "LoadedAnnuairePage" cpt
type AnnuaireId = Int
type ContactCellsProps =
(
annuaireId :: AnnuaireId
, contact :: CT.Contact
( annuaireId :: AnnuaireId
, contact :: CT.NodeContact
, frontends :: Frontends
, session :: Session
)
......@@ -146,33 +144,42 @@ contactCellsCpt :: R.Component ContactCellsProps
contactCellsCpt = R.hooksComponent "G.C.N.A.contactCells" cpt
where
cpt { annuaireId
, contact: (CT.Contact { id, hyperdata: (CT.HyperdataUser {shared: Nothing}) })
, contact: (CT.NodeContact { id, hyperdata: (CT.HyperdataContact {who : Nothing}) })
, frontends
, session } _ =
pure $ T.makeRow [
H.text ""
, H.span {} [ H.text "name" ]
--, H.a { href, target: "blank" } [ H.text $ fromMaybe "name" contact.title ]
, H.text "No ContactWhere"
, H.text "No ContactWhereDept"
, H.div {className: "nooverflow"}
[ H.text "No ContactWhereRole" ]
]
pure $ T.makeRow [ H.text ""
, H.span {} [ H.text "Name" ]
--, H.a { href, target: "blank" } [ H.text $ fromMaybe "name" contact.title ]
, H.text "No ContactWhere"
, H.text "No ContactWhereDept"
, H.div { className: "nooverflow"}
[ H.text "No ContactWhereRole" ]
]
cpt { annuaireId
, contact: (CT.Contact { id
, hyperdata: (CT.HyperdataUser {shared: Just (CT.HyperdataContact contact@{who, ou})}) })
, contact: (CT.NodeContact { id
, hyperdata: ( CT.HyperdataContact { who : Just (CT.ContactWho { firstName
, lastName
}
)
}
)
}
)
, frontends
, session } _ =
, session } _ = do
pure $ T.makeRow [
H.text ""
, H.a { href } [ H.text $ fromMaybe "name" contact.title ]
, H.text $ fromMaybe "First Name" firstName
, H.text $ fromMaybe "First Name" lastName
, H.text "CNRS"
-- , H.a { href } [ H.text $ fromMaybe "name" contact.title ]
--, H.a { href, target: "blank" } [ H.text $ fromMaybe "name" contact.title ]
, H.text $ maybe "No ContactWhere" contactWhereOrg (A.head $ ou)
, H.text $ maybe "No ContactWhereDept" contactWhereDept (A.head $ ou)
, H.div {className: "nooverflow"} [
H.text $ maybe "No ContactWhereRole" contactWhereRole (A.head $ ou)
--, H.text $ maybe "No ContactWhere" contactWhereOrg (A.head $ ou)
-- , H.text $ maybe "No ContactWhereDept" contactWhereDept (A.head $ ou)
-- , H.div {className: "nooverflow"} [
-- H.text $ maybe "No ContactWhereRole" contactWhereRole (A.head $ ou)
]
]
where
--nodepath = NodePath (sessionId session) NodeContact (Just id)
nodepath = Routes.ContactPage (sessionId session) annuaireId id
......@@ -238,7 +245,7 @@ instance decodeAnnuaireInfo :: DecodeJson AnnuaireInfo where
------------------------------------------------------------------------
loadPage :: Session -> PagePath -> AffTableResult CT.Contact
loadPage :: Session -> PagePath -> AffTableResult CT.NodeContact
loadPage session {nodeId, params: { offset, limit, orderBy }} =
get session children
-- TODO orderBy
......
......@@ -4,26 +4,25 @@ module Gargantext.Components.Nodes.Annuaire.User.Contacts
, userLayout )
where
import DOM.Simple.Console (log2)
import Data.Lens as L
import Data.Maybe (Maybe(..), fromMaybe)
import Data.Tuple (Tuple(..), fst, snd)
import Data.Tuple.Nested ((/\))
import DOM.Simple.Console (log2)
import Effect (Effect)
import Effect.Class (liftEffect)
import Effect.Aff (Aff, launchAff_)
import Reactix as R
import Reactix.DOM.HTML as H
import Gargantext.Prelude (Unit, bind, const, discard, pure, show, unit, ($), (+), (<$>), (<<<), (<>), (==))
import Gargantext.Components.Nodes.Annuaire.User.Contacts.Types (Contact(..), ContactData, ContactTouch(..), ContactWhere(..), ContactWho(..), HyperdataContact(..), HyperdataUser(..), _city, _country, _firstName, _labTeamDeptsJoinComma, _lastName, _mail, _office, _organizationJoinComma, _ouFirst, _phone, _role, _shared, _touch, _who, defaultContactTouch, defaultContactWhere, defaultContactWho, defaultHyperdataContact, defaultHyperdataUser)
import Effect.Class (liftEffect)
import Gargantext.Components.Nodes.Annuaire.User.Contacts.Tabs as Tabs
import Gargantext.Components.Nodes.Annuaire.User.Contacts.Types (Contact(..), ContactData, ContactTouch(..), ContactWhere(..), ContactWho(..), HyperdataContact(..), HyperdataUser(..), _city, _country, _firstName, _labTeamDeptsJoinComma, _lastName, _mail, _office, _organizationJoinComma, _ouFirst, _phone, _role, _shared, _touch, _who, defaultContactTouch, defaultContactWhere, defaultContactWho, defaultHyperdataContact, defaultHyperdataUser)
import Gargantext.Ends (Frontends)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Prelude (Unit, bind, const, discard, pure, show, unit, ($), (+), (<$>), (<<<), (<>), (==))
import Gargantext.Routes as Routes
import Gargantext.Ends (Frontends)
import Gargantext.Sessions (Session, get, put)
import Gargantext.Types (NodeType(..))
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
display :: String -> Array R.Element -> R.Element
display title elems =
......@@ -68,8 +67,7 @@ contactInfoItems =
type HyperdataUserLens = L.ALens' HyperdataUser String
type ContactInfoItemProps =
(
hyperdata :: HyperdataUser
( hyperdata :: HyperdataUser
, label :: String
, lens :: HyperdataUserLens
, onUpdateHyperdata :: HyperdataUser -> Effect Unit
......
module Gargantext.Components.Nodes.Annuaire.User.Contacts.Types where
import Prelude
import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, encodeJson, (.:), (.:!), (.:?), (:=), (~>), jsonEmptyObject)
import Prelude (bind, pure, ($))
import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, (.:), (.:!), (.:?), (:=), (~>), jsonEmptyObject)
import Data.Array as A
import Data.Lens
import Data.Maybe (Maybe(..), fromMaybe)
import Data.Map (Map)
import Data.String as S
import Data.Tuple (Tuple(..))
import Gargantext.Utils.DecodeMaybe ((.?|))
import Data.Newtype (class Newtype)
-- TODO: should it be a NodePoly HyperdataContact ?
newtype NodeContact =
NodeContact
{ id :: Int
, date :: Maybe String
, hyperdata :: HyperdataContact
, name :: Maybe String
, parentId :: Maybe Int
, typename :: Maybe Int
, userId :: Maybe Int
}
instance decodeNodeContact :: DecodeJson NodeContact where
decodeJson json = do
obj <- decodeJson json
date <- obj .?| "date"
hyperdata <- obj .: "hyperdata"
id <- obj .: "id"
name <- obj .:! "name"
parentId <- obj .?| "parentId"
typename <- obj .?| "typename"
userId <- obj .:! "userId"
pure $ NodeContact { id
, date
, hyperdata
, name
, parentId
, typename
, userId
}
derive instance newtypeNodeContact :: Newtype NodeContact _
newtype Contact =
Contact
{ id :: Int
......@@ -24,6 +56,8 @@ newtype Contact =
, userId :: Maybe Int
}
instance decodeUser :: DecodeJson Contact where
decodeJson json = do
obj <- decodeJson json
......@@ -35,15 +69,14 @@ instance decodeUser :: DecodeJson Contact where
typename <- obj .?| "typename"
userId <- obj .:! "userId"
pure $ Contact {
id
, date
, hyperdata
, name
, parentId
, typename
, userId
}
pure $ Contact { id
, date
, hyperdata
, name
, parentId
, typename
, userId
}
derive instance newtypeContact :: Newtype Contact _
......@@ -53,7 +86,8 @@ newtype ContactWho =
, firstName :: Maybe String
, lastName :: Maybe String
, keywords :: (Array String)
, freetags :: (Array String) }
, freetags :: (Array String)
}
derive instance newtypeContactWho :: Newtype ContactWho _
......@@ -214,7 +248,7 @@ instance decodeHyperdataContact :: DecodeJson HyperdataContact
title <- obj .:? "title"
uniqId <- obj .:? "uniqId"
uniqIdBdd <- obj .:? "uniqIdBdd"
who <- obj .:? "who"
who <- obj .:! "who"
let ou' = fromMaybe [] ou
......@@ -235,17 +269,15 @@ instance encodeHyperdataContact :: EncodeJson HyperdataContact
defaultHyperdataContact :: HyperdataContact
defaultHyperdataContact =
HyperdataContact {
bdd: Nothing
, who: Nothing
, ou: []
, title: Nothing
, source: Nothing
, lastValidation: Nothing
, uniqId: Nothing
, uniqIdBdd: Nothing
}
HyperdataContact { bdd: Nothing
, who: Nothing
, ou: []
, title: Nothing
, source: Nothing
, lastValidation: Nothing
, uniqId: Nothing
, uniqIdBdd: Nothing
}
newtype HyperdataUser =
HyperdataUser {
......@@ -256,8 +288,8 @@ derive instance newtypeHyperdataUser :: Newtype HyperdataUser _
instance decodeHyperdataUser :: DecodeJson HyperdataUser
where
decodeJson json = do
obj <- decodeJson json
shared <- obj .:? "shared"
obj <- decodeJson json
shared <- obj .:? "shared"
pure $ HyperdataUser { shared }
instance encodeHyperdataUser :: EncodeJson HyperdataUser
......
......@@ -13,6 +13,7 @@ import Reactix as R
import Thermite (PerformAction, Render, Spec, simpleSpec, createClass)
import Gargantext.Components.AutoUpdate (autoUpdateElt)
import Gargantext.Components.Search (SearchType(..))
import Gargantext.Components.Node (NodePoly(..))
import Gargantext.Components.NgramsTable.Core
( CoreState, NgramsPatch(..), NgramsTerm, Replace, Versioned(..)
......@@ -389,7 +390,7 @@ loadData {session, nodeId, listIds, tabType} = do
{ session
, nodeId
, listIds
, params: { offset : 0, limit : 100, orderBy: Nothing}
, params: { offset : 0, limit : 100, orderBy: Nothing, searchType: SearchDoc}
, tabType
, searchQuery: ""
, termListFilter: Nothing
......
......@@ -5,7 +5,8 @@ import Data.Array (fromFoldable)
import Data.Tuple (Tuple(..), fst)
import Reactix as R
import Gargantext.Components.GraphExplorer.Types (GraphSideCorpus(..))
import Gargantext.Components.FacetsTable (TextQuery, docView)
import Gargantext.Components.FacetsTable (docView)
import Gargantext.Components.Search (SearchQuery)
import Gargantext.Components.Table as T
import Gargantext.Components.Tab as Tab
import Gargantext.Ends (Frontends)
......@@ -13,9 +14,9 @@ import Gargantext.Sessions (Session)
type Props =
( frontends :: Frontends
, query :: TextQuery
, session :: Session
, sides :: Array GraphSideCorpus
, query :: SearchQuery
, session :: Session
, sides :: Array GraphSideCorpus
)
tabs :: Record Props -> R.Element
......@@ -31,7 +32,7 @@ tabsCpt = R.hooksComponent "G.P.Corpus.Graph.Tabs.tabs" cpt
where
tabs' = fromFoldable $ tab frontends session query <$> sides
tab :: Frontends -> Session -> TextQuery -> GraphSideCorpus -> Tuple String R.Element
tab :: Frontends -> Session -> SearchQuery -> GraphSideCorpus -> Tuple String R.Element
tab frontends session query (GraphSideCorpus {corpusId: nodeId, corpusLabel, listId}) =
Tuple corpusLabel (docView dvProps)
where
......
This diff is collapsed.
......@@ -13,6 +13,7 @@ import Reactix as R
import Reactix.DOM.HTML as H
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Reactix (effectLink)
import Gargantext.Components.Search
type TableContainerProps =
( pageSizeControl :: R.Element
......@@ -27,7 +28,11 @@ type Rows = L.List Row
type OrderBy = Maybe (OrderByDirection ColumnName)
type Params = { offset :: Int, limit :: Int, orderBy :: OrderBy }
type Params = { offset :: Int
, limit :: Int
, orderBy :: OrderBy
, searchType :: SearchType
}
newtype ColumnName = ColumnName String
......@@ -64,16 +69,17 @@ type State =
{ page :: Int
, pageSize :: PageSizes
, orderBy :: OrderBy
, searchType :: SearchType
}
paramsState :: Params -> State
paramsState {offset, limit, orderBy} = {pageSize, page, orderBy}
paramsState {offset, limit, orderBy, searchType} = {pageSize, page, orderBy, searchType}
where
pageSize = int2PageSizes limit
page = offset / limit + 1
stateParams :: State -> Params
stateParams {pageSize, page, orderBy} = {offset, limit, orderBy}
stateParams {pageSize, page, orderBy, searchType} = {offset, limit, orderBy, searchType}
where
limit = pageSizes2Int pageSize
offset = limit * (page - 1)
......@@ -87,7 +93,7 @@ type TableHeaderLayoutProps =
)
initialParams :: Params
initialParams = stateParams {page: 1, pageSize: PS10, orderBy: Nothing}
initialParams = stateParams {page: 1, pageSize: PS10, orderBy: Nothing, searchType: SearchDoc}
-- TODO: Not sure this is the right place for this
tableHeaderLayout :: Record TableHeaderLayoutProps -> R.Element
......
......@@ -42,13 +42,13 @@ data SessionRoute
| GetNgramsTableVersion { listId :: ListId, tabType :: TabType } (Maybe Id)
| PutNgrams TabType (Maybe ListId) (Maybe TermList) (Maybe Id)
-- ^ This name is not good. In particular this URL is used both in PUT and POST.
| RecomputeNgrams (TabSubType CTabNgramType) Id ListId
| RecomputeListChart ChartType CTabNgramType Id ListId
| NodeAPI NodeType (Maybe Id) String
| GraphAPI Id String
| ListsRoute ListId
| RecomputeNgrams (TabSubType CTabNgramType) Id ListId
| RecomputeListChart ChartType CTabNgramType Id ListId
| NodeAPI NodeType (Maybe Id) String
| GraphAPI Id String
| ListsRoute ListId
| ListDocument (Maybe ListId) (Maybe Id)
| Search SearchOpts (Maybe Id)
| Search SearchOpts (Maybe Id)
| CorpusMetrics CorpusMetricOpts (Maybe Id)
| CorpusMetricsHash { listId :: ListId, tabType :: TabType } (Maybe Id)
| Chart ChartOpts (Maybe Id)
......
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