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

[API] Search API using generics (WIP)

parent f1338ec8
......@@ -23,6 +23,7 @@ import Gargantext.Ends (url, Frontends)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Components.DocsTable (Category(..), CategoryQuery(..), favCategory, decodeCategory, putCategories)
import Gargantext.Components.Table as T
import Gargantext.Components.Search
import Gargantext.Routes (SessionRoute(Search, NodeAPI))
import Gargantext.Routes as Routes
import Gargantext.Sessions (Session, sessionId, post, deleteWithBody)
......@@ -32,29 +33,6 @@ import Gargantext.Utils.DecodeMaybe ((.|))
import Gargantext.Utils.Reactix as R2
------------------------------------------------------------------------
type TotalRecords = Int
-- Example:
-- [["machine","learning"],["artificial","intelligence"]]
-- This searches for documents with "machine learning" or "artificial intelligence"
type TextQuery = Array (Array String)
newtype SearchQuery = SearchQuery { query :: TextQuery }
instance encodeJsonSearchQuery :: EncodeJson SearchQuery where
encodeJson (SearchQuery {query})
-- = "query" := query !! 0 -- TODO anoe
= "query" := concat query
~> jsonEmptyObject
newtype SearchResults = SearchResults { results :: Array Response }
instance decodeSearchResults :: DecodeJson SearchResults where
decodeJson json = do
obj <- decodeJson json
results <- obj .: "results"
pure $ SearchResults {results}
type Props =
( chart :: R.Element
, container :: Record T.TableContainerProps -> R.Element
......@@ -107,26 +85,6 @@ derive instance genericDocumentsView :: Generic DocumentsView _
instance showDocumentsView :: Show DocumentsView where
show = genericShow
newtype Response = Response
{ id :: Int
, created :: String
, hyperdata :: Hyperdata
, category :: Category
, ngramCount :: Int
-- , date :: String
-- , score :: Int
-- , pairs :: Array Pair
}
newtype Hyperdata = Hyperdata
{ authors :: String
, title :: String
, source :: String
, publication_year :: Int
, publication_month :: Int
, publication_day :: Int
}
--instance decodeHyperdata :: DecodeJson Hyperdata where
-- decodeJson json = do
-- obj <- decodeJson json
......@@ -152,29 +110,6 @@ instance decodeHyperdata :: DecodeJson Hyperdata where
publication_day <- obj .: "publication_day"
pure $ Hyperdata { authors, title, source, publication_year, publication_month, publication_day }
{-
instance decodeResponse :: DecodeJson Response where
decodeJson json = do
obj <- decodeJson json
id <- obj .: "id"
-- date <- obj .: "date" -- TODO
date <- pure "2018"
score <- obj .: "score"
hyperdata <- obj .: "hyperdata"
pairs <- obj .: "pairs"
pure $ Response { id, date, score, hyperdata, pairs }
-}
instance decodeResponse :: DecodeJson Response where
decodeJson json = do
obj <- decodeJson json
id <- obj .: "id"
created <- obj .: "created"
hyperdata <- obj .: "hyperdata"
favorite <- obj .: "favorite"
--ngramCount <- obj .: "ngramCount"
let ngramCount = 1
pure $ Response { id, created, hyperdata, category: decodeCategory favorite, ngramCount}
-- | Main layout of the Documents Tab of a Corpus
docView :: Record Props -> R.Element
......@@ -270,14 +205,36 @@ initialPagePath :: {session :: Session, nodeId :: Int, listId :: Int, query :: T
initialPagePath {session, nodeId, listId, query} = {session, nodeId, listId, query, params: T.initialParams}
loadPage :: PagePath -> Aff (Array DocumentsView)
loadPage {session, nodeId, listId, query, params: {limit, offset, orderBy}} = do
loadPage {session, nodeId, listId, query, params: {limit, offset, orderBy, searchType}} = do
let p = Search { listId, offset, limit, orderBy: convOrderBy <$> orderBy } (Just nodeId)
SearchResults res <- post session p $ SearchQuery {query}
pure $ res2corpus <$> res.results
res <- post session p $ SearchQuery {query, expected:searchType}
pure $ res2corpus res
where
res2corpus :: Response -> DocumentsView
res2corpus (Response { id, created: date, ngramCount: score, category
, hyperdata: Hyperdata {authors, title, source, publication_year, publication_month, publication_day} }) =
convOrderBy (T.ASC (T.ColumnName "Date")) = DateAsc
convOrderBy (T.DESC (T.ColumnName "Date")) = DateDesc
convOrderBy (T.ASC (T.ColumnName "Title")) = TitleAsc
convOrderBy (T.DESC (T.ColumnName "Title")) = TitleDesc
convOrderBy (T.ASC (T.ColumnName "Source")) = SourceAsc
convOrderBy (T.DESC (T.ColumnName "Source")) = SourceDesc
convOrderBy _ = DateAsc -- TODO
res2corpus :: SearchResult -> Array DocumentsView
res2corpus :: Document -> DocumentsView
res2corpus (Document { id
, created: date
, score
, category
, hyperdata: HyperdataDocument { authors
, title
, source
, publication_year
, publication_month
, publication_day
}
}
) =
DocumentsView { id
, date
, title
......@@ -291,13 +248,11 @@ loadPage {session, nodeId, listId, query, params: {limit, offset, orderBy}} = do
, publication_month
, publication_day
}
convOrderBy (T.ASC (T.ColumnName "Date")) = DateAsc
convOrderBy (T.DESC (T.ColumnName "Date")) = DateDesc
convOrderBy (T.ASC (T.ColumnName "Title")) = TitleAsc
convOrderBy (T.DESC (T.ColumnName "Title")) = TitleDesc
convOrderBy (T.ASC (T.ColumnName "Source")) = SourceAsc
convOrderBy (T.DESC (T.ColumnName "Source")) = SourceDesc
convOrderBy _ = DateAsc -- TODO
-- TODO Contact 2 view
type PageLayoutProps =
( frontends :: Frontends
......
......@@ -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
......
module Gargantext.Components.Search where
------------------------------------------------------------------------
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)
-- Example:
-- [["machine","learning"],["artificial","intelligence"]]
-- This searches for documents with "machine learning" or "artificial intelligence"
type TextQuery = Array (Array String)
------------------------------------------------------------------------
data SearchType = SearchDoc | SearchContact
derive instance eqSearchType :: Eq SearchType
derive instance genericSearchType :: Generic SearchType _
instance showSearchType :: Show SearchType where
show = genericShow
instance decodeJsonSearchType :: Argonaut.DecodeJson SearchType where
decodeJson = genericSumDecodeJson
instance encodeJsonSearchType :: Argonaut.EncodeJson SearchType where
encodeJson = genericSumEncodeJson
------------------------------------------------------------------------
data SearchQuery =
SearchQuery { query :: String
, expected :: SearchType
}
derive instance eqSearchQuery :: Eq SearchQuery
derive instance genericSearchQuery :: Generic SearchQuery _
instance showSearchQuery :: Show SearchQuery where
show = genericShow
instance decodeJsonSearchQuery :: Argonaut.DecodeJson SearchQuery where
decodeJson = genericSumDecodeJson
instance encodeJsonSearchQuery :: Argonaut.EncodeJson SearchQuery where
encodeJson = genericSumEncodeJson
------------------------------------------------------------------------
data SearchResult = SearchResultDoc { docs :: Array Document}
| SearchResultContact { contacts :: Array Contact }
| SearchNoResult { message :: String }
derive instance eqSearchResult :: Eq SearchResult
derive instance genericSearchResult :: Generic SearchResult _
instance showSearchResult :: Show SearchResult where
show = genericShow
instance decodeJsonSearchResult :: Argonaut.DecodeJson SearchResult where
decodeJson = genericSumDecodeJson
instance encodeJsonSearchResult :: Argonaut.EncodeJson SearchResult where
encodeJson = genericSumEncodeJson
------------------------------------------------------------------------
data Document =
Document { id :: Int
, created :: String
, title :: String
, hyperdata :: HyperdataDocument
, favorite :: Int
, score :: Number
}
derive instance eqDocument :: Eq Document
derive instance genericDocument :: Generic Document _
instance showDocument :: Show Document where
show = genericShow
instance decodeJsonDocument :: Argonaut.DecodeJson Document where
decodeJson = genericSumDecodeJson
instance encodeJsonDocument :: Argonaut.EncodeJson Document where
encodeJson = genericSumEncodeJson
------------------------------------------------------------------------
data HyperdataDocument =
HyperdataDocument { bdd :: Maybe String
, doi :: Maybe String
, url :: Maybe String
, uniqId :: Maybe String
, uniqIdBdd :: Maybe String
, page :: Maybe Int
, title :: Maybe String
, authors :: Maybe String
, institutes :: Maybe String
, source :: Maybe String
, abstract :: Maybe String
, publication_date :: Maybe String
, publication_year :: Maybe Int
, publication_month :: Maybe Int
, publication_day :: Maybe Int
, publication_hour :: Maybe Int
, publication_minute :: Maybe Int
, publication_second :: Maybe Int
, language_iso2 :: Maybe String
}
derive instance eqHyperdataDocument :: Eq HyperdataDocument
derive instance genericHyperdataDocument :: Generic HyperdataDocument _
instance showHyperdataDocument :: Show HyperdataDocument where
show = genericShow
instance decodeJsonHyperdataDocument :: Argonaut.DecodeJson HyperdataDocument where
decodeJson = genericSumDecodeJson
instance encodeJsonHyperdataDocument :: Argonaut.EncodeJson HyperdataDocument where
encodeJson = genericSumEncodeJson
------------------------------------------------------------------------
------------------------------------------------------------------------
------------------------------------------------------------------------
data Contact =
Contact { id :: Int
, created :: String
, hyperdata :: HyperdataContact
, score :: Number
}
derive instance eqContact :: Eq Contact
derive instance genericContact :: Generic Contact _
instance showContact :: Show Contact where
show = genericShow
instance decodeJsonContact :: Argonaut.DecodeJson Contact where
decodeJson = genericSumDecodeJson
instance encodeJsonContact :: Argonaut.EncodeJson Contact where
encodeJson = genericSumEncodeJson
data HyperdataContact =
HyperdataContact { bdd :: Maybe String
, who :: Maybe ContactWho
, "where" :: Array ContactWhere
, title :: Maybe String
, source :: Maybe String
, lastValidation :: Maybe String
, uniqIdBdd :: Maybe String
, uniqId :: Maybe String
}
derive instance eqHyperdataContact :: Eq HyperdataContact
derive instance genericHyperdataContact :: Generic HyperdataContact _
instance showHyperdataContact :: Show HyperdataContact where
show = genericShow
instance decodeJsonHyperdataContact :: Argonaut.DecodeJson HyperdataContact where
decodeJson = genericSumDecodeJson
instance encodeJsonHyperdataContact :: Argonaut.EncodeJson HyperdataContact where
encodeJson = genericSumEncodeJson
-------
data ContactWho =
ContactWho { id :: Maybe String
, firstName :: Maybe String
, lastName :: Maybe String
, keywords :: Array String
, freetags :: Array String
}
derive instance eqContactWho :: Eq ContactWho
derive instance genericContactWho :: Generic ContactWho _
instance showContactWho :: Show ContactWho where
show = genericShow
instance decodeJsonContactWho :: Argonaut.DecodeJson ContactWho where
decodeJson = genericSumDecodeJson
instance encodeJsonContactWho :: Argonaut.EncodeJson ContactWho where
encodeJson = genericSumEncodeJson
data ContactWhere =
ContactWhere { organization :: Array String
, labTeamDepts :: Array String
, role :: Maybe String
, office :: Maybe String
, country :: Maybe String
, city :: Maybe String
, touch :: Maybe ContactTouch
, entry :: Maybe String
, exit :: Maybe String
}
derive instance eqContactWhere :: Eq ContactWhere
derive instance genericContactWhere :: Generic ContactWhere _
instance showContactWhere :: Show ContactWhere where
show = genericShow
instance decodeJsonContactWhere :: Argonaut.DecodeJson ContactWhere where
decodeJson = genericSumDecodeJson
instance encodeJsonContactWhere :: Argonaut.EncodeJson ContactWhere where
encodeJson = genericSumEncodeJson
data ContactTouch =
ContactTouch { mail :: Maybe String
, phone :: Maybe String
, url :: Maybe String
}
derive instance eqContactTouch :: Eq ContactTouch
derive instance genericContactTouch :: Generic ContactTouch _
instance showContactTouch :: Show ContactTouch where
show = genericShow
instance decodeJsonContactTouch :: Argonaut.DecodeJson ContactTouch where
decodeJson = genericSumDecodeJson
instance encodeJsonContactTouch :: Argonaut.EncodeJson ContactTouch where
encodeJson = genericSumEncodeJson
......@@ -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
......
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