Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
purescript-gargantext
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
137
Issues
137
List
Board
Labels
Milestones
Merge Requests
4
Merge Requests
4
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
gargantext
purescript-gargantext
Commits
6ad8d99d
Commit
6ad8d99d
authored
May 22, 2023
by
Alexandre Delanoë
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dev' into testing
parents
c979e19b
7f7ac4ad
Pipeline
#4032
failed with stage
Changes
19
Pipelines
2
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
579 additions
and
345 deletions
+579
-345
logo.png
dist/images/logo.png
+0
-0
package.json
package.json
+1
-1
spago.dhall
spago.dhall
+1
-0
Field.purs
src/Gargantext/Components/Annotation/Field.purs
+11
-14
Menu.purs
src/Gargantext/Components/Annotation/Menu.purs
+0
-1
Category.purs
src/Gargantext/Components/Category.purs
+36
-25
Types.purs
src/Gargantext/Components/Category/Types.purs
+91
-53
DocsTable.purs
src/Gargantext/Components/DocsTable.purs
+173
-90
Types.purs
src/Gargantext/Components/DocsTable/Types.purs
+7
-7
Layout.purs
src/Gargantext/Components/Document/Layout.purs
+0
-1
FacetsTable.purs
src/Gargantext/Components/FacetsTable.purs
+1
-0
SearchField.purs
...omponents/Forest/Tree/Node/Action/Search/SearchField.purs
+127
-83
Types.purs
...text/Components/Forest/Tree/Node/Action/Search/Types.purs
+85
-62
Upload.purs
...Gargantext/Components/Forest/Tree/Node/Action/Upload.purs
+2
-1
GraphQL.purs
src/Gargantext/Components/GraphQL.purs
+4
-3
Endpoints.purs
src/Gargantext/Components/GraphQL/Endpoints.purs
+10
-1
Node.purs
src/Gargantext/Components/GraphQL/Node.purs
+22
-0
NgramsTable.purs
src/Gargantext/Components/NgramsTable.purs
+7
-2
TopBar.purs
src/Gargantext/Components/TopBar.purs
+1
-1
No files found.
dist/images/logo.png
View replaced file @
c979e19b
View file @
6ad8d99d
19.8 KB
|
W:
|
H:
17.1 KB
|
W:
|
H:
2-up
Swipe
Onion skin
package.json
View file @
6ad8d99d
{
{
"name"
:
"Gargantext"
,
"name"
:
"Gargantext"
,
"version"
:
"0.0.6.9.9.
3.3
"
,
"version"
:
"0.0.6.9.9.
5
"
,
"scripts"
:
{
"scripts"
:
{
"generate-purs-packages-nix"
:
"./nix/generate-purs-packages.nix"
,
"generate-purs-packages-nix"
:
"./nix/generate-purs-packages.nix"
,
"generate-psc-packages-nix"
:
"./nix/generate-packages-json.bash"
,
"generate-psc-packages-nix"
:
"./nix/generate-packages-json.bash"
,
...
...
spago.dhall
View file @
6ad8d99d
...
@@ -33,6 +33,7 @@ to generate this file without the comments in this block.
...
@@ -33,6 +33,7 @@ to generate this file without the comments in this block.
, "dom-simple"
, "dom-simple"
, "effect"
, "effect"
, "either"
, "either"
, "enums"
, "exceptions"
, "exceptions"
, "ffi-simple"
, "ffi-simple"
, "foldable-traversable"
, "foldable-traversable"
...
...
src/Gargantext/Components/Annotation/Field.purs
View file @
6ad8d99d
...
@@ -13,18 +13,18 @@ module Gargantext.Components.Annotation.Field where
...
@@ -13,18 +13,18 @@ module Gargantext.Components.Annotation.Field where
import Gargantext.Prelude
import Gargantext.Prelude
import DOM.Simple.Event as DE
import Data.Array as A
import Data.Array as A
import Data.List (List(..), (:))
import Data.List (List(..), (:))
import Data.Maybe (Maybe(..), maybe)
import Data.Maybe (Maybe(..), maybe)
import Data.String.Common (joinWith)
import Data.String.Common (joinWith)
import Data.Tuple (Tuple(..), snd)
import Data.Tuple (Tuple(..), snd)
import Data.Tuple.Nested ((/\))
import Data.Tuple.Nested ((/\))
import DOM.Simple.Event as DE
import Effect (Effect)
import Effect (Effect)
import Gargantext.Components.Annotation.Menu (annotationMenu, AnnotationMenu)
import Gargantext.Components.Annotation.Menu (annotationMenu, AnnotationMenu)
import Gargantext.Components.Annotation.Types (MenuType(..), ModeType(..), termClass)
import Gargantext.Components.Annotation.Types (MenuType(..), ModeType(..), termClass)
import Gargantext.Core.NgramsTable.Functions (findNgramTermList, highlightNgrams, normNgram)
import Gargantext.Core.NgramsTable.Functions (findNgramTermList, highlightNgrams, normNgram)
import Gargantext.Core.NgramsTable.Types (NgramsTable, NgramsTerm)
import Gargantext.Core.NgramsTable.Types (NgramsTable, NgramsTerm
(..)
)
import Gargantext.Types (CTabNgramType(..), TermList)
import Gargantext.Types (CTabNgramType(..), TermList)
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Selection as Sel
import Gargantext.Utils.Selection as Sel
...
@@ -35,7 +35,7 @@ import Record as Record
...
@@ -35,7 +35,7 @@ import Record as Record
import Toestand as T
import Toestand as T
here :: R2.Here
here :: R2.Here
here = R2.here "Gargantext.Components.Annotation.
Annotated
Field"
here = R2.here "Gargantext.Components.Annotation.Field"
-- @NOTE #386: add parameter "type" ("Authors", "Terms")
-- @NOTE #386: add parameter "type" ("Authors", "Terms")
type Props =
type Props =
...
@@ -52,7 +52,6 @@ type MouseEvent = E.SyntheticEvent DE.MouseEvent
...
@@ -52,7 +52,6 @@ type MouseEvent = E.SyntheticEvent DE.MouseEvent
annotatedField :: R2.Leaf Props
annotatedField :: R2.Leaf Props
annotatedField = R2.leaf annotatedFieldCpt
annotatedField = R2.leaf annotatedFieldCpt
annotatedFieldCpt :: R.Component Props
annotatedFieldCpt :: R.Component Props
annotatedFieldCpt = here.component "annotatedField" cpt where
annotatedFieldCpt = here.component "annotatedField" cpt where
cpt props _ = do
cpt props _ = do
...
@@ -71,7 +70,6 @@ type InnerProps =
...
@@ -71,7 +70,6 @@ type InnerProps =
annotatedFieldInner :: R2.Leaf InnerProps
annotatedFieldInner :: R2.Leaf InnerProps
annotatedFieldInner = R2.leaf annotatedFieldInnerCpt
annotatedFieldInner = R2.leaf annotatedFieldInnerCpt
annotatedFieldInnerCpt :: R.Component InnerProps
annotatedFieldInnerCpt :: R.Component InnerProps
annotatedFieldInnerCpt = here.component "annotatedFieldInner" cpt where
annotatedFieldInnerCpt = here.component "annotatedFieldInner" cpt where
cpt { menuRef
cpt { menuRef
...
@@ -159,16 +157,16 @@ onAnnotationSelect
...
@@ -159,16 +157,16 @@ onAnnotationSelect
s <- Sel.getSelection
s <- Sel.getSelection
case s of
case s of
Just sel -> do
Just sel -> do
case
Sel.selectionToString sel
of
case
(normNgram CTabTerms $ Sel.selectionToString sel)
of
"" -> hideMenu { menuRef, redrawMenu }
NormNgramsTerm
"" -> hideMenu { menuRef, redrawMenu }
sel' -> do
sel' -> do
showMenu { event
showMenu { event
, getList: findNgramTermList ngrams
, getList: findNgramTermList ngrams
, menuRef
, menuRef
, menuType: NewNgram
, menuType: NewNgram
, ngram:
normNgram CTabTerms sel'
, ngram: sel' --
normNgram CTabTerms sel'
, redrawMenu
, redrawMenu
, setTermList }
, setTermList }
Nothing -> hideMenu { menuRef, redrawMenu }
Nothing -> hideMenu { menuRef, redrawMenu }
onAnnotationSelect
onAnnotationSelect
...
@@ -241,7 +239,6 @@ type RunProps =
...
@@ -241,7 +239,6 @@ type RunProps =
annotateRun :: R2.Leaf RunProps
annotateRun :: R2.Leaf RunProps
annotateRun = R2.leaf annotatedRunCpt
annotateRun = R2.leaf annotatedRunCpt
annotatedRunCpt :: R.Component RunProps
annotatedRunCpt :: R.Component RunProps
annotatedRunCpt = here.component "annotatedRun" cpt where
annotatedRunCpt = here.component "annotatedRun" cpt where
cpt { list, onSelect, text } _ = pure $ case list of
cpt { list, onSelect, text } _ = pure $ case list of
...
...
src/Gargantext/Components/Annotation/Menu.purs
View file @
6ad8d99d
...
@@ -36,7 +36,6 @@ type AnnotationMenu =
...
@@ -36,7 +36,6 @@ type AnnotationMenu =
annotationMenu :: R2.Leaf Props
annotationMenu :: R2.Leaf Props
annotationMenu = R2.leaf annotationMenuCpt
annotationMenu = R2.leaf annotationMenuCpt
annotationMenuCpt :: R.Component Props
annotationMenuCpt :: R.Component Props
annotationMenuCpt = here.component "main" cpt where
annotationMenuCpt = here.component "main" cpt where
cpt { menuRef } _ = do
cpt { menuRef } _ = do
...
...
src/Gargantext/Components/Category.purs
View file @
6ad8d99d
...
@@ -4,6 +4,7 @@ module Gargantext.Components.Category where
...
@@ -4,6 +4,7 @@ module Gargantext.Components.Category where
import Gargantext.Prelude
import Gargantext.Prelude
import Data.Array as A
import Data.Array as A
import Data.Enum (fromEnum)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep (class Generic)
import Data.Map as Map
import Data.Map as Map
import Data.Maybe (Maybe(..), fromMaybe)
import Data.Maybe (Maybe(..), fromMaybe)
...
@@ -12,8 +13,8 @@ import Effect.Aff (launchAff_)
...
@@ -12,8 +13,8 @@ import Effect.Aff (launchAff_)
import Effect.Class (liftEffect)
import Effect.Class (liftEffect)
import Gargantext.Components.Bootstrap as B
import Gargantext.Components.Bootstrap as B
import Gargantext.Components.Bootstrap.Types (Variant(..))
import Gargantext.Components.Bootstrap.Types (Variant(..))
import Gargantext.Components.Category.Types (Category(..), Star(..), cat2score, cat
egories, clickAgain, decodeStar, star2score
, stars)
import Gargantext.Components.Category.Types (Category(..), Star(..), cat2score, cat
2star, categories, categoryNextState, decodeCategory
, stars)
import Gargantext.Components.DocsTable.Types (DocumentsView(..), LocalCategories
, LocalUserScore
)
import Gargantext.Components.DocsTable.Types (DocumentsView(..), LocalCategories)
import Gargantext.Components.GraphQL.Context (NodeContext)
import Gargantext.Components.GraphQL.Context (NodeContext)
import Gargantext.Components.GraphQL.Endpoints (getNodeContext, updateNodeContextCategory)
import Gargantext.Components.GraphQL.Endpoints (getNodeContext, updateNodeContextCategory)
import Gargantext.Config.REST (AffRESTError, RESTError(..))
import Gargantext.Config.REST (AffRESTError, RESTError(..))
...
@@ -36,9 +37,9 @@ type RatingProps =
...
@@ -36,9 +37,9 @@ type RatingProps =
( chartReload :: T2.ReloadS
( chartReload :: T2.ReloadS
, nodeId :: NodeID
, nodeId :: NodeID
, row :: DocumentsView
, row :: DocumentsView
, score ::
Star
, score ::
Category
, session :: Session
, session :: Session
, setLocalCategories :: R.Setter LocalUserScore
-- , setLocalCategories :: R.Setter LocalCategories
)
)
rating :: R2.Component RatingProps
rating :: R2.Component RatingProps
...
@@ -50,11 +51,11 @@ ratingCpt = here.component "rating" cpt where
...
@@ -50,11 +51,11 @@ ratingCpt = here.component "rating" cpt where
, row: DocumentsView r
, row: DocumentsView r
, score
, score
, session
, session
, setLocalCategories
--
, setLocalCategories
} _ = do
} _ = do
pure $ renderRatingSimple { docId: r._id
pure $ renderRatingSimple { docId: r._id
, corpusId: nodeId
, corpusId: nodeId
, category: s
tar2score s
core
, category: score
, session } []
, session } []
-- -- | Behaviors
-- -- | Behaviors
...
@@ -86,14 +87,17 @@ ratingCpt = here.component "rating" cpt where
...
@@ -86,14 +87,17 @@ ratingCpt = here.component "rating" cpt where
-- , className: ratingClassName score s
-- , className: ratingClassName score s
-- }
-- }
ratingIcon Star_0 Star_0 = "recycle"
ratingIcon :: Category -> Star -> String
ratingIcon Trash Star_0 = "recycle"
ratingIcon _ Star_0 = "trash"
ratingIcon _ Star_0 = "trash"
ratingIcon c s =
star2score c < star2score
s ? "star-o" $ "star"
ratingIcon c s =
fromEnum (cat2star c) < fromEnum
s ? "star-o" $ "star"
ratingVariant :: Star -> Star -> Variant
ratingVariant Star_0 Star_0 = Dark
ratingVariant Star_0 Star_0 = Dark
ratingVariant _ Star_0 = Dark
ratingVariant _ Star_0 = Dark
ratingVariant _ _ = Dark
ratingVariant _ _ = Dark
ratingClassName :: Star -> Star -> String
ratingClassName Star_0 Star_0 = "rating-group__action"
ratingClassName Star_0 Star_0 = "rating-group__action"
ratingClassName _ Star_0 = "rating-group__action"
ratingClassName _ Star_0 = "rating-group__action"
ratingClassName _ _ = "rating-group__star"
ratingClassName _ _ = "rating-group__star"
...
@@ -118,10 +122,12 @@ ratingSimpleLoaderCpt = here.component "ratingSimpleLoader" cpt where
...
@@ -118,10 +122,12 @@ ratingSimpleLoaderCpt = here.component "ratingSimpleLoader" cpt where
useLoader { errorHandler
useLoader { errorHandler
, loader: loadDocumentContext session
, loader: loadDocumentContext session
, path: { docId, corpusId }
, path: { docId, corpusId }
, render: \{ nc_category } -> renderRatingSimple { docId
, render: \{ nc_category } -> do
, corpusId
let category = fromMaybe UnRead $ decodeCategory <$> nc_category
, category: fromMaybe 0 nc_category
renderRatingSimple { docId
, session } [] }
, corpusId
, category
, session } [] }
where
where
errorHandler err = do
errorHandler err = do
here.warn2 "[pageLayout] RESTError" err
here.warn2 "[pageLayout] RESTError" err
...
@@ -139,7 +145,7 @@ loadDocumentContext session { docId, corpusId } = getNodeContext session docId c
...
@@ -139,7 +145,7 @@ loadDocumentContext session { docId, corpusId } = getNodeContext session docId c
type RenderRatingSimpleProps =
type RenderRatingSimpleProps =
( docId :: NodeID
( docId :: NodeID
, corpusId :: NodeID
, corpusId :: NodeID
, category ::
Int
, category ::
Category
, session :: Session )
, session :: Session )
renderRatingSimple :: R2.Component RenderRatingSimpleProps
renderRatingSimple :: R2.Component RenderRatingSimpleProps
...
@@ -151,17 +157,17 @@ renderRatingSimpleCpt = here.component "renderRatingSimple" cpt where
...
@@ -151,17 +157,17 @@ renderRatingSimpleCpt = here.component "renderRatingSimple" cpt where
, category
, category
, session
, session
} _ = do
} _ = do
score <- T.useBox $ decodeStar
category
categoryS <- T.useBox
category
pure $ ratingSimple { docId
pure $ ratingSimple { docId
, corpusId
, corpusId
,
score
,
category: categoryS
, session } []
, session } []
type RatingSimpleProps =
type RatingSimpleProps =
( docId :: NodeID
( docId :: NodeID
, corpusId :: NodeID
, corpusId :: NodeID
,
score :: T.Box Star
,
category :: T.Box Category
, session :: Session )
, session :: Session )
ratingSimple :: R2.Component RatingSimpleProps
ratingSimple :: R2.Component RatingSimpleProps
...
@@ -170,19 +176,21 @@ ratingSimpleCpt :: R.Component RatingSimpleProps
...
@@ -170,19 +176,21 @@ ratingSimpleCpt :: R.Component RatingSimpleProps
ratingSimpleCpt = here.component "ratingSimple" cpt where
ratingSimpleCpt = here.component "ratingSimple" cpt where
cpt { docId
cpt { docId
, corpusId
, corpusId
,
score
,
category
, session
, session
} _ = do
} _ = do
score' <- T.useLive T.unequal score
category' <- T.useLive T.unequal category
let star' = cat2star category'
let
let
onClick c _ = do
onClick c _ = do
let c' = score' == c ? clickAgain c $ c
-- let c' = score' == c ? clickAgain c $ c
let c' = categoryNextState category' c
-- setLocalCategories $ Map.insert r._id c'
-- setLocalCategories $ Map.insert r._id c'
launchAff_ do
launchAff_ do
_ <- updateNodeContextCategory session docId corpusId $
star
2score c'
_ <- updateNodeContextCategory session docId corpusId $
cat
2score c'
liftEffect $ T.write_ c'
score
liftEffect $ T.write_ c'
category
pure unit
pure unit
pure $
pure $
...
@@ -190,17 +198,17 @@ ratingSimpleCpt = here.component "ratingSimple" cpt where
...
@@ -190,17 +198,17 @@ ratingSimpleCpt = here.component "ratingSimple" cpt where
{ className: "rating-group" } $
{ className: "rating-group" } $
stars <#> \s ->
stars <#> \s ->
B.iconButton
B.iconButton
{ name: ratingIcon
score
' s
{ name: ratingIcon
category
' s
, callback: onClick s
, callback: onClick s
, overlay: false
, overlay: false
, variant: ratingVariant s
core
' s
, variant: ratingVariant s
tar
' s
, className: ratingClassName s
core
' s
, className: ratingClassName s
tar
' s
}
}
newtype RatingQuery =
newtype RatingQuery =
RatingQuery { nodeIds :: Array Int
RatingQuery { nodeIds :: Array Int
, rating ::
Star
, rating ::
Category
}
}
derive instance Generic RatingQuery _
derive instance Generic RatingQuery _
instance JSON.WriteForeign RatingQuery where
instance JSON.WriteForeign RatingQuery where
...
@@ -267,6 +275,9 @@ icon cat b = btn b $ "fa fa-" <> (color $ size b $ icon' cat b)
...
@@ -267,6 +275,9 @@ icon cat b = btn b $ "fa fa-" <> (color $ size b $ icon' cat b)
icon' Favorite false = "heart-o"
icon' Favorite false = "heart-o"
icon' Favorite true = "heart"
icon' Favorite true = "heart"
icon' ToCite false = "quote-left-o"
icon' ToCite true = "quote-left"
size :: Boolean -> String -> String
size :: Boolean -> String -> String
size true s = s <> " btn-lg"
size true s = s <> " btn-lg"
size false s = s <> " btn-sm"
size false s = s <> " btn-sm"
...
...
src/Gargantext/Components/Category/Types.purs
View file @
6ad8d99d
module Gargantext.Components.Category.Types where
module Gargantext.Components.Category.Types where
import Data.Generic.Rep (class Generic)
import Data.Bounded.Generic (genericTop, genericBottom)
import Data.Enum (class Enum, class BoundedEnum, succ, pred, fromEnum, toEnumWithDefaults)
import Data.Enum.Generic (genericPred, genericSucc, genericCardinality, genericFromEnum, genericToEnum)
import Data.Eq.Generic (genericEq)
import Data.Eq.Generic (genericEq)
import Data.Generic.Rep (class Generic)
import Data.Maybe (fromMaybe)
import Data.Ord.Generic (genericCompare)
import Data.Show.Generic (genericShow)
import Data.Show.Generic (genericShow)
import Simple.JSON as JSON
import Simple.JSON as JSON
import Gargantext.Prelude
import Gargantext.Prelude
------------------------------------------------------------------------
------------------------------------------------------------------------
data Star = Star_0 | Star_1 | Star_2 | Star_3 | Star_4
data Category = Trash | UnRead | Checked | Topic | Favorite | ToCite
{-
stars :: Array Star
- `UnRead` is assigned initially for new docs
stars = [Star_0, Star_1, Star_2, Star_3, Star_4]
- After reading a doc, `Checked` should be assigned automatically
- Both `Trash` and `UnRead` map to 0 stars in the doc list
derive instance Generic Star _
-}
instance Show Star where show = genericShow
instance Eq Star where eq = genericEq
instance JSON.ReadForeign Star where
readImpl f = do
inst <- JSON.readImpl f
pure $ decodeStar inst
instance JSON.WriteForeign Star where writeImpl = JSON.writeImpl <<< star2score
decodeStar :: Int -> Star
decodeStar 0 = Star_0
decodeStar 1 = Star_1
decodeStar 2 = Star_2
decodeStar 3 = Star_3
decodeStar 4 = Star_4
decodeStar _ = Star_4
star2score :: Star -> Int
star2score Star_0 = 0
star2score Star_1 = 1
star2score Star_2 = 2
star2score Star_3 = 3
star2score Star_4 = 4
clickAgain :: Star -> Star
clickAgain Star_0 = Star_1
clickAgain s = decodeStar (star2score s - 1)
------------------------------------------------------------------------
data Category = Trash | UnRead | Checked | Topic | Favorite
categories :: Array Category
categories :: Array Category
categories = [Trash, UnRead, Checked, Topic, Favorite]
categories = [Trash, UnRead, Checked, Topic, Favorite
, ToCite
]
derive instance Generic Category _
derive instance Generic Category _
instance Ord Category where compare = genericCompare
instance Enum Category where
pred = genericPred
succ = genericSucc
instance Bounded Category where
bottom = genericBottom
top = genericTop
instance BoundedEnum Category where
cardinality = genericCardinality
fromEnum = genericFromEnum
toEnum = genericToEnum
instance Show Category where show = genericShow
instance Show Category where show = genericShow
instance Eq Category where eq = genericEq
instance Eq Category where eq = genericEq
instance JSON.ReadForeign Category where
instance JSON.ReadForeign Category where
...
@@ -58,26 +43,79 @@ instance JSON.ReadForeign Category where
...
@@ -58,26 +43,79 @@ instance JSON.ReadForeign Category where
pure $ decodeCategory inst
pure $ decodeCategory inst
instance JSON.WriteForeign Category where writeImpl = JSON.writeImpl <<< cat2score
instance JSON.WriteForeign Category where writeImpl = JSON.writeImpl <<< cat2score
catSucc :: Category -> Category
catSucc c = fromMaybe ToCite $ succ c
catPred :: Category -> Category
catPred c = fromMaybe Trash $ pred c
clickAgain :: Category -> Category
clickAgain _ = UnRead
-- | `categoryNextState :: current -> clicked -> new State`
categoryNextState :: Category -> Star -> Category
categoryNextState Trash Star_0 = UnRead
categoryNextState _ Star_0 = Trash
categoryNextState current clicked =
if (cat2star current) == clicked then
clickAgain current
else
star2catSimple clicked
favCategory :: Category -> Category
favCategory :: Category -> Category
favCategory Favorite = Topic
favCategory Favorite = Topic
favCategory _ = Favorite
favCategory _ = Favorite
trashCategory :: Category -> Category
trashCategory :: Category -> Category
trashCategory _ = Trash
trashCategory = const Trash
-- TODO: ?
--trashCategory Trash = UnRead
decodeCategory :: Int -> Category
decodeCategory :: Int -> Category
decodeCategory 0 = Trash
decodeCategory = toEnumWithDefaults UnRead UnRead
decodeCategory 1 = UnRead
decodeCategory 2 = Checked
decodeCategory 3 = Topic
decodeCategory 4 = Favorite
decodeCategory _ = UnRead
cat2score :: Category -> Int
cat2score :: Category -> Int
cat2score Trash = 0
cat2score = fromEnum
cat2score UnRead = 1
cat2score Checked = 2
------------------------------------------------------------------------
cat2score Topic = 3
-- | This is just a helper to visualize categories.
cat2score Favorite = 4
data Star = Star_0 | Star_1 | Star_2 | Star_3 | Star_4
stars :: Array Star
stars = [Star_0, Star_1, Star_2, Star_3, Star_4]
derive instance Generic Star _
instance Show Star where show = genericShow
instance Eq Star where eq = genericEq
instance Ord Star where compare = genericCompare
instance Enum Star where
pred = genericPred
succ = genericSucc
instance Bounded Star where
bottom = genericBottom
top = genericTop
instance BoundedEnum Star where
cardinality = genericCardinality
fromEnum = genericFromEnum
toEnum = genericToEnum
cat2star :: Category -> Star
cat2star Trash = Star_0
cat2star UnRead = Star_0
cat2star Checked = Star_1
cat2star Topic = Star_2
cat2star Favorite = Star_3
cat2star ToCite = Star_4
-- | This is a "reverse" of `cat2star`
star2catSimple :: Star -> Category
star2catSimple Star_0 = UnRead
star2catSimple Star_1 = Checked
star2catSimple Star_2 = Topic
star2catSimple Star_3 = Favorite
star2catSimple Star_4 = ToCite
markCategoryChecked :: Category -> Category
markCategoryChecked UnRead = Checked
markCategoryChecked s = s
src/Gargantext/Components/DocsTable.purs
View file @
6ad8d99d
...
@@ -26,10 +26,11 @@ import Effect.Timer (setTimeout)
...
@@ -26,10 +26,11 @@ import Effect.Timer (setTimeout)
import Gargantext.Components.App.Store (Boxes)
import Gargantext.Components.App.Store (Boxes)
import Gargantext.Components.Bootstrap as B
import Gargantext.Components.Bootstrap as B
import Gargantext.Components.Bootstrap.Types (ComponentStatus(..), ModalSizing(..), Variant(..))
import Gargantext.Components.Bootstrap.Types (ComponentStatus(..), ModalSizing(..), Variant(..))
import Gargantext.Components.Category (rating)
import Gargantext.Components.Category (rating
, ratingSimple
)
import Gargantext.Components.Category.Types (
Star(..)
)
import Gargantext.Components.Category.Types (
Category(..), Star(..), cat2score, markCategoryChecked
)
import Gargantext.Components.DocsTable.DocumentFormCreation as DFC
import Gargantext.Components.DocsTable.DocumentFormCreation as DFC
import Gargantext.Components.DocsTable.Types (DocumentsView(..), Hyperdata(..), LocalUserScore, Query, Response(..), Year, sampleData, showSource)
import Gargantext.Components.DocsTable.Types (DocumentsView(..), Hyperdata(..), LocalCategories, Query, Response(..), Year, sampleData, showSource)
import Gargantext.Components.GraphQL.Endpoints (updateNodeContextCategory)
import Gargantext.Components.Nodes.Lists.Types as NT
import Gargantext.Components.Nodes.Lists.Types as NT
import Gargantext.Components.Nodes.Texts.Types as TextsT
import Gargantext.Components.Nodes.Texts.Types as TextsT
import Gargantext.Components.Reload (textsReloadContext)
import Gargantext.Components.Reload (textsReloadContext)
...
@@ -192,7 +193,7 @@ docViewCpt = here.component "docView" cpt where
...
@@ -192,7 +193,7 @@ docViewCpt = here.component "docView" cpt where
, H.div { className: "col d-flex mt-5 mb-2" }
, H.div { className: "col d-flex mt-5 mb-2" }
[ H.div { className: "doc-add-action" }
[ H.div { className: "doc-add-action" }
[ H.button
[ H.button
{ className: "btn btn-light text-primary border-primary"
{ className: "btn btn-light text-primary border-primary"
, on: { click: toggleModal } }
, on: { click: toggleModal } }
[ H.i { className: "fa fa-plus mr-1" } []
[ H.i { className: "fa fa-plus mr-1" } []
...
@@ -304,9 +305,9 @@ searchBarCpt = here.component "searchBar" cpt
...
@@ -304,9 +305,9 @@ searchBarCpt = here.component "searchBar" cpt
, placeholder: "Search in documents"
, placeholder: "Search in documents"
, type: "text" }
, type: "text" }
, H.div {className: "input-group-append"}
, H.div {className: "input-group-append"}
[
[
if query' /= ""
if query' /= ""
then
then
R.fragment
R.fragment
[ clearButton query
[ clearButton query
, searchButton query queryText'
, searchButton query queryText'
...
@@ -450,7 +451,7 @@ pageLayoutCpt = here.component "pageLayout" cpt where
...
@@ -450,7 +451,7 @@ pageLayoutCpt = here.component "pageLayout" cpt where
, spinnerClass: Nothing
, spinnerClass: Nothing
}
}
NT.CacheOff -> do
NT.CacheOff -> do
localCategories <- T.useBox (Map.empty :: Local
UserScore
)
localCategories <- T.useBox (Map.empty :: Local
Categories
)
paramsS <- T.useBox params
paramsS <- T.useBox params
paramsS' <- T.useLive T.unequal paramsS
paramsS' <- T.useLive T.unequal paramsS
let loader p = do
let loader p = do
...
@@ -501,7 +502,7 @@ pagePaintCpt = here.component "pagePaintCpt" cpt
...
@@ -501,7 +502,7 @@ pagePaintCpt = here.component "pagePaintCpt" cpt
cpt { documents, layout, params } _ = do
cpt { documents, layout, params } _ = do
params' <- T.useLive T.unequal params
params' <- T.useLive T.unequal params
localCategories <- T.useBox (Map.empty :: Local
UserScore
)
localCategories <- T.useBox (Map.empty :: Local
Categories
)
pure $ pagePaintRaw { documents: A.fromFoldable (filteredRows params')
pure $ pagePaintRaw { documents: A.fromFoldable (filteredRows params')
, layout
, layout
, localCategories
, localCategories
...
@@ -522,7 +523,7 @@ pagePaintCpt = here.component "pagePaintCpt" cpt
...
@@ -522,7 +523,7 @@ pagePaintCpt = here.component "pagePaintCpt" cpt
type PagePaintRawProps =
type PagePaintRawProps =
( documents :: Array DocumentsView
( documents :: Array DocumentsView
, layout :: Record PageLayoutProps
, layout :: Record PageLayoutProps
, localCategories :: T.Box Local
UserScore
, localCategories :: T.Box Local
Categories
, params :: T.Box TT.Params
, params :: T.Box TT.Params
)
)
...
@@ -557,80 +558,153 @@ pagePaintRawCpt = here.component "pagePaintRaw" cpt where
...
@@ -557,80 +558,153 @@ pagePaintRawCpt = here.component "pagePaintRaw" cpt where
{ colNames
{ colNames
, container: TT.defaultContainer
, container: TT.defaultContainer
, params
, params
, rows: rows reload chartReload localCategories' mCurrentDocId'
, rows: rows { boxes
, reload
, chartReload
, frontends
, listId
, localCategories: localCategories'
, mCorpusId
, mCurrentDocId
, nodeId
, session
, sidePanel }
, syncResetButton : [ H.div {} [] ]
, syncResetButton : [ H.div {} [] ]
, totalRecords
, totalRecords
, wrapColElts
, wrapColElts
}
}
where
where
colNames = TT.ColumnName <$> [ "Show", "Tag", "Date", "Title", "Source", "Score" ]
wrapColElts = const identity
rows { boxes
, chartReload
, frontends
, listId
, localCategories
, mCorpusId
, mCurrentDocId
, nodeId
, reload
, session
, sidePanel } =
(\documentsView -> { row: tableRow { boxes
, chartReload
, documentsView
, frontends
, listId
, localCategories
, mCorpusId
, mCurrentDocId
, nodeId
, session
, sidePanel } []
, delete: true } ) <$> A.toUnfoldable documents
trashClassName :: Category -> Boolean -> String
trashClassName Trash _ = "page-paint-row page-paint-row--trash"
trashClassName _ true = "page-paint-row page-paint-row--active"
trashClassName _ false = ""
type TableRowProps =
( boxes :: Boxes
, chartReload :: T2.ReloadS
, documentsView :: DocumentsView
, frontends :: Frontends
, listId :: Int
, localCategories :: LocalCategories
, mCorpusId :: Maybe Int
, mCurrentDocId :: T.Box (Maybe Int)
, nodeId :: Int
, session :: Session
, sidePanel :: T.Box (Maybe (Record TextsT.SidePanel)) )
tableRow :: R2.Component TableRowProps
tableRow = R.createElement tableRowCpt
tableRowCpt :: R.Component TableRowProps
tableRowCpt = here.component "tableRow" cpt where
cpt { boxes
, chartReload
, documentsView: dv@(DocumentsView r@{ _id, category })
, frontends
, listId
, localCategories
, mCorpusId
, mCurrentDocId
, nodeId
, session
, sidePanel } _ = do
mCurrentDocId' <- T.useLive T.unequal mCurrentDocId
let cat :: Category
cat = fromMaybe category (localCategories ^. at _id)
selected = mCurrentDocId' == Just r._id
sid = sessionId session
sid = sessionId session
trashClassName Star_0 _ = "page-paint-row page-paint-row--trash"
trashClassName _ true = "page-paint-row page-paint-row--active"
trashClassName _ false = ""
corpusDocument
corpusDocument
| Just cid <- mCorpusId = Routes.CorpusDocument sid cid listId
| Just cid <- mCorpusId = Routes.CorpusDocument sid cid listId
| otherwise = Routes.Document sid listId
| otherwise = Routes.Document sid listId
colNames = TT.ColumnName <$> [ "Show", "Tag", "Date", "Title", "Source", "Score" ]
wrapColElts = const identity
categoryS <- T.useBox cat
rows reload chartReload localCategories' mCurrentDocId' = row <$> A.toUnfoldable documents
categoryS' <- T.useLive T.unequal categoryS
where
row dv@(DocumentsView r@{ _id, category }) =
let tClassName = trashClassName categoryS' selected
{ row:
TT.makeRow'
pure $ TT.makeRow' { className: "page-paint-raw " <>
{ className: "page-paint-raw " <>
(selected ?
(selected ?
"page-paint-raw--selected" $
"page-paint-raw--selected" $
""
""
)
)
}
}
[ -- H.div {} [ H.a { className, style, on: {click: click Favorite} } [] ]
[ -- H.div {} [ H.a { className, style, on: {click: click Favorite} } [] ]
H.div { className: "" }
H.div { className: "" }
[ docChooser { boxes
[ docChooser { boxes
, category: categoryS
, listId
, docId: r._id
, mCorpusId
, listId
, nodeId: r._id
, mCorpusId
, sidePanel } []
, nodeId: r._id
]
, session
--, H.div { className: "column-tag flex" } [ caroussel { category: cat, nodeId, row: dv, session, setLocalCategories } [] ]
, sidePanel } []
, H.div { className: "column-tag flex" }
]
[ rating { chartReload
--, H.div { className: "column-tag flex" } [ caroussel { category: cat, nodeId, row: dv, session, setLocalCategories } [] ]
, nodeId
, H.div { className: "column-tag flex" }
, row: dv
[ ratingSimple { -- chartReload
, score: cat
docId: _id
, setLocalCategories: \lc -> T.modify_ lc localCategories
, category: categoryS
, session } [] ]
, corpusId: nodeId
--, H.input { type: "checkbox", defaultValue: checked, on: {click: click Trash} }
-- , row: dv
-- TODO show date: Year-Month-Day only
, session
, H.div { className: tClassName } [ R2.showText r.date ]
-- , setLocalCategories: \lc -> T.modify_ lc localCategories
,
} [] ]
H.div
--, H.input { type: "checkbox", defaultValue: checked, on: {click: click Trash} }
{ className: tClassName }
-- TODO show date: Year-Month-Day only
[
, H.div { className: tClassName } [ R2.showText r.date ]
H.a
,
{ href: url frontends $ corpusDocument r._id
H.div
, target: "_blank"
{ className: tClassName }
, className: "text-primary"
[
}
H.a
[ H.text r.title
{ href: url frontends $ corpusDocument r._id
, H.i { className: "fa fa-external-link mx-1 small" } []
, target: "_blank"
]
, className: "text-primary"
]
}
, H.div { className: tClassName } [ H.text $ showSource r.source ]
[ H.text r.title
, H.div {} [ H.text $ maybe "-" show r.ngramCount ]
, H.i { className: "fa fa-external-link mx-1 small" } []
]
]
, delete: true }
]
where
, H.div { className: tClassName } [ H.text $ showSource r.source ]
cat = fromMaybe category (localCategories' ^. at _id)
, H.div {} [ H.text $ maybe "-" show r.ngramCount ]
-- checked = Star_1 == cat
]
selected = mCurrentDocId' == Just r._id
tClassName = trashClassName cat selected
type DocChooser = (
type DocChooser = (
boxes :: Boxes
boxes :: Boxes
, listId :: ListId
, category :: T.Box Category
, mCorpusId :: Maybe NodeID
, docId :: Int
, nodeId :: NodeID
, listId :: ListId
, sidePanel :: T.Box (Maybe (Record TextsT.SidePanel))
, mCorpusId :: Maybe NodeID
, nodeId :: NodeID
, session :: Session
, sidePanel :: T.Box (Maybe (Record TextsT.SidePanel))
)
)
docChooser :: R2.Component DocChooser
docChooser :: R2.Component DocChooser
...
@@ -642,19 +716,45 @@ docChooserCpt = here.component "docChooser" cpt
...
@@ -642,19 +716,45 @@ docChooserCpt = here.component "docChooser" cpt
pure $ H.div {} []
pure $ H.div {} []
cpt { boxes: { sidePanelState }
cpt { boxes: { sidePanelState }
, category
, docId
, listId
, listId
, mCorpusId: Just corpusId
, mCorpusId: Just corpusId
, nodeId
, nodeId
, session
, sidePanel } _ = do
, sidePanel } _ = do
mCurrentDocId <- T.useFocused
mCurrentDocId <- T.useFocused
(maybe Nothing _.mCurrentDocId)
(maybe Nothing _.mCurrentDocId)
(\val -> maybe Nothing (\sp -> Just $ sp { mCurrentDocId = val })) sidePanel
(\val -> maybe Nothing (\sp -> Just $ sp { mCurrentDocId = val })) sidePanel
mCurrentDocId' <- T.useLive T.unequal mCurrentDocId
mCurrentDocId' <- T.useLive T.unequal mCurrentDocId
category' <- T.useLive T.unequal category
let selected = mCurrentDocId' == Just nodeId
let selected = mCurrentDocId' == Just nodeId
eyeClass = selected ? "eye" $ "eye-slash"
eyeClass = selected ? "eye" $ "eye-slash"
variant = selected ? Info $ Dark
variant = selected ? Info $ Dark
onClick selected _ = do
-- here.log2 "[docChooser] onClick, listId" listId
-- here.log2 "[docChooser] onClick, corpusId" corpusId
-- here.log2 "[docChooser] onClick, nodeId" nodeId
-- R2.callTrigger triggerAnnotatedDocIdChange { corpusId, listId, nodeId }
-- T2.reload tableReload
if selected then do
T.write_ Nothing sidePanel
T.write_ Closed sidePanelState
else do
T.write_ (Just { corpusId: corpusId
, listId: listId
, mCurrentDocId: Just nodeId
, nodeId: nodeId }) sidePanel
T.write_ Opened sidePanelState
let categoryMarked = markCategoryChecked category'
launchAff_ $ do
_ <- updateNodeContextCategory session docId corpusId $ cat2score categoryMarked
pure unit
T.write_ categoryMarked category
-- here.log2 "[docChooser] sidePanel opened" sidePanelState
pure $
pure $
H.div
H.div
{ className: "doc-chooser" }
{ className: "doc-chooser" }
...
@@ -666,23 +766,6 @@ docChooserCpt = here.component "docChooser" cpt
...
@@ -666,23 +766,6 @@ docChooserCpt = here.component "docChooser" cpt
, callback: onClick selected
, callback: onClick selected
}
}
]
]
where
onClick selected _ = do
-- here.log2 "[docChooser] onClick, listId" listId
-- here.log2 "[docChooser] onClick, corpusId" corpusId
-- here.log2 "[docChooser] onClick, nodeId" nodeId
-- R2.callTrigger triggerAnnotatedDocIdChange { corpusId, listId, nodeId }
-- T2.reload tableReload
if selected then do
T.write_ Nothing sidePanel
T.write_ Closed sidePanelState
else do
T.write_ (Just { corpusId: corpusId
, listId: listId
, mCurrentDocId: Just nodeId
, nodeId: nodeId }) sidePanel
T.write_ Opened sidePanelState
here.log2 "[docChooser] sidePanel opened" sidePanelState
newtype SearchQuery = SearchQuery {
newtype SearchQuery = SearchQuery {
...
...
src/Gargantext/Components/DocsTable/Types.purs
View file @
6ad8d99d
...
@@ -7,14 +7,14 @@ import Data.Generic.Rep (class Generic)
...
@@ -7,14 +7,14 @@ import Data.Generic.Rep (class Generic)
import Data.Map (Map)
import Data.Map (Map)
import Data.Maybe (Maybe(..), fromMaybe)
import Data.Maybe (Maybe(..), fromMaybe)
import Data.Tuple (Tuple(..))
import Data.Tuple (Tuple(..))
import Gargantext.Components.Category.Types (Category
, Star(..), decodeStar
)
import Gargantext.Components.Category.Types (Category
(..), Star(..), decodeCategory
)
import Simple.JSON as JSON
import Simple.JSON as JSON
data Action
data Action
= MarkCategory Int Category
= MarkCategory Int Category
type DocumentsViewT =
type DocumentsViewT =
( category ::
Star
( category ::
Category
, date :: Int
, date :: Int
, ngramCount :: Maybe Int
, ngramCount :: Maybe Int
, score :: Maybe Int
, score :: Maybe Int
...
@@ -65,8 +65,8 @@ type ResponseT =
...
@@ -65,8 +65,8 @@ type ResponseT =
, score :: Maybe Int
, score :: Maybe Int
, title :: String )
, title :: String )
newtype Response = Response
newtype Response = Response
{ cid
:: Int
{ cid :: Int
, category ::
Star
, category ::
Category
| ResponseT
| ResponseT
}
}
...
@@ -74,7 +74,7 @@ instance JSON.ReadForeign Response where
...
@@ -74,7 +74,7 @@ instance JSON.ReadForeign Response where
readImpl f = do
readImpl f = do
{ category, id, hyperdata, ngramCount, score, title } :: { category :: Int, id :: Int | ResponseT } <- JSON.readImpl f
{ category, id, hyperdata, ngramCount, score, title } :: { category :: Int, id :: Int | ResponseT } <- JSON.readImpl f
--pure $ Response { category: decodeCategory category, cid, hyperdata, ngramCount, score, title }
--pure $ Response { category: decodeCategory category, cid, hyperdata, ngramCount, score, title }
pure $ Response { category: decode
Star
category
pure $ Response { category: decode
Category
category
, cid: id
, cid: id
, hyperdata
, hyperdata
, ngramCount
, ngramCount
...
@@ -110,7 +110,7 @@ sampleData' = DocumentsView { _id : 1
...
@@ -110,7 +110,7 @@ sampleData' = DocumentsView { _id : 1
, date : 2010
, date : 2010
, title : "title"
, title : "title"
, source : Just "source"
, source : Just "source"
, category :
Star_1
, category :
UnRead
, ngramCount : Just 1
, ngramCount : Just 1
, score: Just 1 }
, score: Just 1 }
...
@@ -121,7 +121,7 @@ sampleData = map (\(Tuple t s) -> DocumentsView { _id : 1
...
@@ -121,7 +121,7 @@ sampleData = map (\(Tuple t s) -> DocumentsView { _id : 1
, date : 2017
, date : 2017
, title: t
, title: t
, source: Just s
, source: Just s
, category :
Star_1
, category :
UnRead
, ngramCount : Just 10
, ngramCount : Just 10
, score: Just 1 }) sampleDocuments
, score: Just 1 }) sampleDocuments
...
...
src/Gargantext/Components/Document/Layout.purs
View file @
6ad8d99d
...
@@ -16,7 +16,6 @@ import Gargantext.Components.AutoUpdate (autoUpdate)
...
@@ -16,7 +16,6 @@ import Gargantext.Components.AutoUpdate (autoUpdate)
import Gargantext.Components.Bootstrap as B
import Gargantext.Components.Bootstrap as B
import Gargantext.Components.Bootstrap.Types (ComponentStatus(..), SpinnerTheme(..))
import Gargantext.Components.Bootstrap.Types (ComponentStatus(..), SpinnerTheme(..))
import Gargantext.Components.Category (ratingSimpleLoader)
import Gargantext.Components.Category (ratingSimpleLoader)
import Gargantext.Components.Category.Types (decodeStar)
import Gargantext.Components.Document.Types (DocPath, Document(..), LoadedData, initialState)
import Gargantext.Components.Document.Types (DocPath, Document(..), LoadedData, initialState)
import Gargantext.Components.NgramsTable.AutoSync (useAutoSync)
import Gargantext.Components.NgramsTable.AutoSync (useAutoSync)
import Gargantext.Components.Node (NodePoly(..))
import Gargantext.Components.Node (NodePoly(..))
...
...
src/Gargantext/Components/FacetsTable.purs
View file @
6ad8d99d
...
@@ -395,6 +395,7 @@ pageCpt = here.component "page" cpt
...
@@ -395,6 +395,7 @@ pageCpt = here.component "page" cpt
wrapColElts = const identity
wrapColElts = const identity
-- TODO: how to interprete other scores?
-- TODO: how to interprete other scores?
gi Trash = "fa fa-star-empty"
gi Trash = "fa fa-star-empty"
gi UnRead = "fa fa-star-empty"
gi _ = "fa fa-star"
gi _ = "fa fa-star"
documentUrl id { listId, nodeId } =
documentUrl id { listId, nodeId } =
...
...
src/Gargantext/Components/Forest/Tree/Node/Action/Search/SearchField.purs
View file @
6ad8d99d
...
@@ -3,6 +3,7 @@ module Gargantext.Components.Forest.Tree.Node.Action.Search.SearchField where
...
@@ -3,6 +3,7 @@ module Gargantext.Components.Forest.Tree.Node.Action.Search.SearchField where
import Gargantext.Prelude
import Gargantext.Prelude
import Data.Array as A
import Data.Array as A
import Data.Either (Either(..))
import Data.Maybe (Maybe(..), maybe, fromMaybe)
import Data.Maybe (Maybe(..), maybe, fromMaybe)
import Data.Newtype (over)
import Data.Newtype (over)
import Data.Nullable (null)
import Data.Nullable (null)
...
@@ -15,8 +16,8 @@ import Effect (Effect)
...
@@ -15,8 +16,8 @@ import Effect (Effect)
import Effect.Aff (launchAff_)
import Effect.Aff (launchAff_)
import Effect.Class (liftEffect)
import Effect.Class (liftEffect)
import Gargantext.Components.Forest.Tree.Node.Action.Search.Frame (searchIframes)
import Gargantext.Components.Forest.Tree.Node.Action.Search.Frame (searchIframes)
import Gargantext.Components.Forest.Tree.Node.Action.Search.Types (DataField(..), Database(..), IMT_org(..), Org(..), SearchQuery(..), allOrgs, dataFields, defaultSearchQuery, doc, performSearch, datafield2database, Search)
import Gargantext.Components.Forest.Tree.Node.Action.Search.Types (DataField(..), Database(..), IMT_org(..), Org(..), SearchQuery(..), allOrgs, dataFields, defaultSearchQuery, doc, performSearch, datafield2database, Search
, dbFromInputValue, dbToInputValue
)
import Gargantext.Components.GraphQL.Endpoints (getIMTSchools)
import Gargantext.Components.GraphQL.Endpoints (getIMTSchools
, getNodeCorpus
)
import Gargantext.Components.GraphQL.IMT as GQLIMT
import Gargantext.Components.GraphQL.IMT as GQLIMT
import Gargantext.Components.InputWithEnter (inputWithEnter)
import Gargantext.Components.InputWithEnter (inputWithEnter)
import Gargantext.Components.Lang (Lang(..))
import Gargantext.Components.Lang (Lang(..))
...
@@ -37,13 +38,13 @@ here :: R2.Here
...
@@ -37,13 +38,13 @@ here :: R2.Here
here = R2.here "Gargantext.Components.Forest.Tree.Node.Action.Search.SearchField"
here = R2.here "Gargantext.Components.Forest.Tree.Node.Action.Search.SearchField"
defaultSearch :: Search
defaultSearch :: Search
defaultSearch = { databases: Empty
defaultSearch = { databases
: Empty
, datafield
: Nothing
, datafield
: Just (External Empty)
, node_id : Nothing
, node_id
: Nothing
, lang : Nothing
, lang
: Nothing
, term : ""
, term
: ""
, url : ""
, url
: ""
, years : []
, years
: []
}
}
type Props =
type Props =
...
@@ -93,8 +94,8 @@ componentYearsCpt = here.component "componentYears" cpt where
...
@@ -93,8 +94,8 @@ componentYearsCpt = here.component "componentYears" cpt where
((yearCpt search <$> yearsZ) <>
((yearCpt search <$> yearsZ) <>
[ H.div {}
[ H.div {}
[ H.input { on: { blur: modify newYear
[ H.input { on: { blur: modify newYear
, change: modify newYear
, change: modify newYear
, input: modify newYear } }
, input: modify newYear } }
, H.span { className: "btn btn-primary fa fa-check"
, H.span { className: "btn btn-primary fa fa-check"
, on: { click: clickAdd newYear search }} []
, on: { click: clickAdd newYear search }} []
]
]
...
@@ -180,28 +181,19 @@ isExternal _ = false
...
@@ -180,28 +181,19 @@ isExternal _ = false
isArxiv :: Maybe DataField -> Boolean
isArxiv :: Maybe DataField -> Boolean
isArxiv (Just
isArxiv (Just
( External
( External Arxiv )
( Just Arxiv
) = true
)
)
) = true
isArxiv _ = false
isArxiv _ = false
isHAL :: Maybe DataField -> Boolean
isHAL :: Maybe DataField -> Boolean
isHAL (Just
isHAL (Just
( External
( External (HAL _ ) )
( Just (HAL _ )
)
)
) = true
) = true
isHAL _ = false
isHAL _ = false
isIsTex :: Maybe DataField -> Boolean
isIsTex :: Maybe DataField -> Boolean
isIsTex ( Just
isIsTex ( Just
( External
( External ( IsTex ) )
( Just ( IsTex)
)
)
) = true
) = true
isIsTex _ = false
isIsTex _ = false
...
@@ -209,11 +201,8 @@ isIsTex _ = false
...
@@ -209,11 +201,8 @@ isIsTex _ = false
isIMT :: Maybe DataField -> Boolean
isIMT :: Maybe DataField -> Boolean
isIMT ( Just
isIMT ( Just
( External
( External
( Just
( HAL
( HAL
( Just ( IMT _) )
( Just ( IMT _)
)
)
)
)
)
)
) = true
) = true
...
@@ -222,24 +211,24 @@ isIMT _ = false
...
@@ -222,24 +211,24 @@ isIMT _ = false
isCNRS :: Maybe DataField -> Boolean
isCNRS :: Maybe DataField -> Boolean
isCNRS ( Just
isCNRS ( Just
( External
( External
( Just
( HAL
( HAL
( Just ( CNRS _) )
( Just ( CNRS _)
)
)
)
)
)
)
) = true
) = true
isCNRS _ = false
isCNRS _ = false
isPubmed :: Maybe DataField -> Boolean
isPubmed ( Just
( External ( PubMed _ ) )
) = true
isPubmed _ = false
needsLang :: Maybe DataField -> Boolean
needsLang :: Maybe DataField -> Boolean
needsLang (Just Gargantext) = true
needsLang (Just Gargantext) = true
needsLang (Just Web) = true
needsLang (Just Web) = true
needsLang ( Just
needsLang ( Just
( External
( External (HAL _) )
( Just (HAL _)
)
)
) = true
) = true
needsLang _ = false
needsLang _ = false
...
@@ -247,11 +236,9 @@ needsLang _ = false
...
@@ -247,11 +236,9 @@ needsLang _ = false
isIn :: IMT_org -> Maybe DataField -> Boolean
isIn :: IMT_org -> Maybe DataField -> Boolean
isIn org ( Just
isIn org ( Just
( External
( External
( Just
( HAL
( HAL
( Just
( Just
( IMT imtOrgs )
( IMT imtOrgs )
)
)
)
)
)
)
)
...
@@ -259,8 +246,8 @@ isIn org ( Just
...
@@ -259,8 +246,8 @@ isIn org ( Just
isIn _ _ = false
isIn _ _ = false
updateFilter :: IMT_org -> Array IMT_org -> Maybe DataField -> Maybe DataField
updateFilter :: IMT_org -> Array IMT_org -> Maybe DataField -> Maybe DataField
updateFilter org allIMTorgs (Just (External (
Just (HAL (Just (IMT imtOrgs)
))))) =
updateFilter org allIMTorgs (Just (External (
HAL (Just (IMT imtOrgs
))))) =
(Just (External (Just (HAL (Just $ IMT imtOrgs')))))
Just $ External $ HAL $ Just $ IMT imtOrgs'
where
where
imtOrgs' = if Set.member org imtOrgs
imtOrgs' = if Set.member org imtOrgs
then
then
...
@@ -272,7 +259,7 @@ updateFilter org allIMTorgs (Just (External (Just (HAL (Just (IMT imtOrgs))))))
...
@@ -272,7 +259,7 @@ updateFilter org allIMTorgs (Just (External (Just (HAL (Just (IMT imtOrgs))))))
then Set.fromFoldable allIMTorgs
then Set.fromFoldable allIMTorgs
else Set.insert org imtOrgs
else Set.insert org imtOrgs
updateFilter org allIMTorgs _ = (Just (External (
Just (HAL (Just (IMT imtOrgs')
)))))
updateFilter org allIMTorgs _ = (Just (External (
HAL (Just (IMT imtOrgs'
)))))
where
where
imtOrgs' = if org == All_IMT
imtOrgs' = if org == All_IMT
then Set.fromFoldable allIMTorgs
then Set.fromFoldable allIMTorgs
...
@@ -346,6 +333,7 @@ dataFieldNavCpt = here.component "dataFieldNav" cpt
...
@@ -346,6 +333,7 @@ dataFieldNavCpt = here.component "dataFieldNav" cpt
type DatabaseInputProps = (
type DatabaseInputProps = (
databases :: Array Database
databases :: Array Database
, search :: T.Box Search
, search :: T.Box Search
, session :: Session
)
)
databaseInput :: R2.Component DatabaseInputProps
databaseInput :: R2.Component DatabaseInputProps
...
@@ -354,34 +342,82 @@ databaseInputCpt :: R.Component DatabaseInputProps
...
@@ -354,34 +342,82 @@ databaseInputCpt :: R.Component DatabaseInputProps
databaseInputCpt = here.component "databaseInput" cpt
databaseInputCpt = here.component "databaseInput" cpt
where
where
cpt { databases
cpt { databases
, search } _ = do
, search
, session } _ = do
search' <- T.useLive T.unequal search
search' <- T.useLive T.unequal search
let db = case search'.datafield of
let db = case search'.datafield of
(Just (External (Just x))) -> Just x
(Just (External x)) -> Just x
_ -> Nothing
_ -> Nothing
dbInputValue = fromMaybe "" $ dbToInputValue <$> db
liItem :: Database -> R.Element
liItem :: Database -> R.Element
liItem db' = H.option { className : "text-primary center"
liItem db' = H.option { className : "text-primary center"
, value:
show
db' } [ H.text (show db') ]
, value:
dbToInputValue
db' } [ H.text (show db') ]
change e = do
change e = do
let value = read $ R.unsafeEventValue e
let value = dbFromInputValue $ R.unsafeEventValue e
T.modify_ (_ { datafield = Just $ External value
-- TODO Fetch pubmed api key
, databases = fromMaybe Empty value
launchAff_ $ do
}) search
updatedValue <- case value of
Just (PubMed _) ->
case search'.node_id of
Just nodeId -> do
eCorpus <- getNodeCorpus session nodeId
case eCorpus of
Left _err -> pure $ PubMed { api_key: Nothing }
Right c -> pure $ PubMed { api_key: c.pubmedAPIKey }
Nothing -> pure $ PubMed { api_key: Nothing }
_ -> pure $ fromMaybe Empty value
liftEffect $ T.modify_ (_ { datafield = Just $ External updatedValue
, databases = updatedValue
}) search
pure $
pure $
H.div { className: "form-group" }
H.div { className: "form-group" }
[ H.div {className: "text-primary center"} [ H.text "in database" ]
[ H.div {className: "text-primary center"} [ H.text "in database" ]
, R2.select { className: "form-control"
, R2.select { className: "form-control"
, defaultValue: d
efaultValue search'.datafield
, defaultValue: d
bInputValue
, on: { change }
, on: { change }
} (liItem <$> databases)
} (liItem <$> databases)
, H.div {className:"center"} [ H.text $ maybe "" doc db ]
, H.div {className:"center"} [ H.text $ maybe "" doc db ]
]
]
defaultValue datafield = show $ maybe Empty datafield2database datafield
type PubmedInputProps = (
search :: T.Box Search
, session :: Session
)
pubmedInput :: R2.Component PubmedInputProps
pubmedInput = R.createElement pubmedInputCpt
pubmedInputCpt :: R.Component PubmedInputProps
pubmedInputCpt = here.component "pubmedInput" cpt where
cpt { search, session } _ = do
search' <- T.useLive T.unequal search
case search'.datafield of
Just (External (PubMed p@{ api_key })) ->
-- TODO Fetch current API key
pure $
H.div { className: "form-group" }
[ H.div { className: "text-primary center" } [ H.text "Pubmed API key" ]
, H.input { className: "form-control"
, defaultValue: fromMaybe "" api_key
, on: { blur: modifyPubmedAPIKey search p
, change: modifyPubmedAPIKey search p
, input: modifyPubmedAPIKey search p } } ]
_ -> pure $ H.div {} []
where
modifyPubmedAPIKey search p e = do
let val = R.unsafeEventValue e
let mVal = case val of
"" -> Nothing
s -> Just s
T.modify_ (\s ->
s { datafield = Just (External (PubMed p { api_key = mVal })) }) search
type OrgInputProps =
type OrgInputProps =
...
@@ -396,7 +432,7 @@ orgInputCpt = here.component "orgInput" cpt
...
@@ -396,7 +432,7 @@ orgInputCpt = here.component "orgInput" cpt
cpt { orgs, search } _ = do
cpt { orgs, search } _ = do
let change e = do
let change e = do
let value = R.unsafeEventValue e
let value = R.unsafeEventValue e
T.modify_ (_ { datafield = Just $ External $
Just $
HAL $ read value }) search
T.modify_ (_ { datafield = Just $ External $ HAL $ read value }) search
pure $ H.div { className: "form-group" }
pure $ H.div { className: "form-group" }
[ H.div {className: "text-primary center"} [H.text "filter with organization: "]
[ H.div {className: "text-primary center"} [H.text "filter with organization: "]
...
@@ -438,13 +474,18 @@ datafieldInputCpt :: R.Component DatafieldInputProps
...
@@ -438,13 +474,18 @@ datafieldInputCpt :: R.Component DatafieldInputProps
datafieldInputCpt = here.component "datafieldInput" cpt where
datafieldInputCpt = here.component "datafieldInput" cpt where
cpt { databases, langs, search, session } _ = do
cpt { databases, langs, search, session } _ = do
search' <- T.useLive T.unequal search
search' <- T.useLive T.unequal search
datafield <- T.useFocused (_.datafield) (\a b -> b { datafield = a }) search
iframeRef <- R.useRef null
iframeRef <- R.useRef null
pure $ H.div {}
pure $ H.div {}
[ dataFieldNav { search } []
[ dataFieldNav { search } []
, if isExternal search'.datafield
, if isExternal search'.datafield
then databaseInput { databases, search } []
then databaseInput { databases, search, session } []
else H.div {} []
, if isPubmed search'.datafield
then pubmedInput { search, session } []
else H.div {} []
else H.div {} []
, if isHAL search'.datafield
, if isHAL search'.datafield
...
@@ -594,38 +635,41 @@ searchQuery selection { datafield: Nothing, term } =
...
@@ -594,38 +635,41 @@ searchQuery selection { datafield: Nothing, term } =
, selection = selection }) defaultSearchQuery
, selection = selection }) defaultSearchQuery
-- TODO Simplify both HAL Nothing and HAL (Just IMT) cases
-- TODO Simplify both HAL Nothing and HAL (Just IMT) cases
searchQuery selection { databases
searchQuery selection { databases
, datafield: datafield@(Just (External (
Just (HAL Nothing)
)))
, datafield: datafield@(Just (External (
HAL Nothing
)))
, lang
, lang
, term
, term
, node_id
, node_id
, years } = over SearchQuery (_ { databases = databases
, years } =
, datafield = datafield
over SearchQuery (_ { databases = databases
, lang = lang
, datafield = datafield
, node_id = node_id
, lang = lang
, query = queryHAL term Nothing lang years
, node_id = node_id
, selection = selection
, query = queryHAL term Nothing lang years
}) defaultSearchQuery
, selection = selection
}) defaultSearchQuery
searchQuery selection { databases
searchQuery selection { databases
, datafield: datafield@(Just (External (
Just (HAL (Just (IMT imtOrgs)
)))))
, datafield: datafield@(Just (External (
HAL (Just (IMT imtOrgs
)))))
, lang
, lang
, term
, term
, node_id
, node_id
, years } = over SearchQuery (_ { databases = databases
, years } =
, datafield = datafield
over SearchQuery (_ { databases = databases
, lang = lang
, datafield = datafield
, node_id = node_id
, lang = lang
, query = queryHAL term (Just imtOrgs) lang years
, node_id = node_id
, selection = selection
, query = queryHAL term (Just imtOrgs) lang years
}) defaultSearchQuery
, selection = selection
}) defaultSearchQuery
searchQuery selection { databases, datafield, lang, term, node_id } =
searchQuery selection { databases, datafield, lang, term, node_id } =
over SearchQuery (_ { databases = databases
over SearchQuery (_ { databases = databases
, datafield = datafield
, datafield = datafield
, lang = lang
, lang = lang
, node_id = node_id
, node_id = node_id
, query = term
, query = term
, selection = selection
, selection = selection
}) defaultSearchQuery
}) defaultSearchQuery
queryHAL :: String -> Maybe (Set.Set IMT_org) -> Maybe Lang -> Array String -> String
queryHAL :: String -> Maybe (Set.Set IMT_org) -> Maybe Lang -> Array String -> String
queryHAL term mIMTOrgs lang years =
queryHAL term mIMTOrgs lang years =
...
...
src/Gargantext/Components/Forest/Tree/Node/Action/Search/Types.purs
View file @
6ad8d99d
...
@@ -8,7 +8,6 @@ import Data.Maybe (Maybe(..), fromMaybe, maybe)
...
@@ -8,7 +8,6 @@ import Data.Maybe (Maybe(..), fromMaybe, maybe)
import Data.Newtype (class Newtype)
import Data.Newtype (class Newtype)
import Data.Set (Set)
import Data.Set (Set)
import Data.Set as Set
import Data.Set as Set
import Data.String as String
import Data.Tuple (Tuple)
import Data.Tuple (Tuple)
import Data.Tuple.Nested ((/\))
import Data.Tuple.Nested ((/\))
import Gargantext.Components.GraphQL.IMT as GQLIMT
import Gargantext.Components.GraphQL.IMT as GQLIMT
...
@@ -23,21 +22,18 @@ import Simple.JSON as JSON
...
@@ -23,21 +22,18 @@ import Simple.JSON as JSON
import URI.Extra.QueryPairs as QP
import URI.Extra.QueryPairs as QP
import URI.Query as Q
import URI.Query as Q
type Search = { databases :: Database
type Search = { databases
:: Database
, datafield :: Maybe DataField
, datafield
:: Maybe DataField
, url :: String
, url
:: String
, lang :: Maybe Lang
, lang
:: Maybe Lang
, node_id :: Maybe Int
, node_id
:: Maybe Int
, term :: String
, term
:: String
, years :: Array String
, years
:: Array String
}
}
isIsTex_Advanced :: Maybe DataField -> Boolean
isIsTex_Advanced :: Maybe DataField -> Boolean
isIsTex_Advanced ( Just
isIsTex_Advanced ( Just
( External
( External ( IsTex_Advanced) )
( Just ( IsTex_Advanced)
)
)
) = true
) = true
isIsTex_Advanced _ = false
isIsTex_Advanced _ = false
...
@@ -51,13 +47,13 @@ class Doc a where
...
@@ -51,13 +47,13 @@ class Doc a where
dataFields :: Array DataField
dataFields :: Array DataField
dataFields = [ {- Gargantext
dataFields = [ {- Gargantext
, -} External
Nothing
, -} External
Empty
, Web
, Web
-- , Files
-- , Files
]
]
data DataField = Gargantext
data DataField = Gargantext
| External
(Maybe Database)
| External
Database
| Web
| Web
| Files
| Files
...
@@ -74,9 +70,9 @@ instance Doc DataField where
...
@@ -74,9 +70,9 @@ instance Doc DataField where
doc Files = "Zip files with formats.."
doc Files = "Zip files with formats.."
derive instance Eq DataField
derive instance Eq DataField
instance JSON.WriteForeign DataField where
instance JSON.WriteForeign DataField where
writeImpl (External
(Just db)) = JSON.writeImpl $ "External " <> show db
writeImpl (External
db) = JSON.writeImpl { tag: "External"
writeImpl Web = JSON.writeImpl $ "Web"
, contents: JSON.writeImpl db }
writeImpl f = JSON.writeImpl $
show f
writeImpl f = JSON.writeImpl $
JSON.writeImpl { tag: show f }
----------------------------------------
----------------------------------------
data DataOriginApi = InternalOrigin { api :: Database }
data DataOriginApi = InternalOrigin { api :: Database }
...
@@ -91,23 +87,23 @@ instance JSON.WriteForeign DataOriginApi where
...
@@ -91,23 +87,23 @@ instance JSON.WriteForeign DataOriginApi where
writeImpl (ExternalOrigin { api }) = JSON.writeImpl { api }
writeImpl (ExternalOrigin { api }) = JSON.writeImpl { api }
datafield2dataOriginApi :: DataField -> DataOriginApi
datafield2dataOriginApi :: DataField -> DataOriginApi
datafield2dataOriginApi (External
(Just a)
) = ExternalOrigin { api : a }
datafield2dataOriginApi (External
a
) = ExternalOrigin { api : a }
datafield2dataOriginApi _
= InternalOrigin { api : IsTex } -- TODO fixme
datafield2dataOriginApi _
= InternalOrigin { api : IsTex } -- TODO fixme
------------------------------------------------------------------------
------------------------------------------------------------------------
-- | Database search specifications
-- | Database search specifications
datafield2database :: DataField -> Database
datafield2database :: DataField -> Database
datafield2database (External
(Just x)
) = x
datafield2database (External
x
) = x
datafield2database _
= Empty
datafield2database _ = Empty
allDatabases :: Array Database
allDatabases :: Array Database
allDatabases = [ Empty
allDatabases = [ Empty
, PubMed
, PubMed
{ api_key: Nothing }
, Arxiv
--
, Arxiv
, HAL Nothing
, HAL Nothing
, IsTex
, IsTex
, IsTex_Advanced
--
, IsTex_Advanced
-- , Isidore
-- , Isidore
--, Web
--, Web
--, News
--, News
...
@@ -116,7 +112,7 @@ allDatabases = [ Empty
...
@@ -116,7 +112,7 @@ allDatabases = [ Empty
data Database = All_Databases
data Database = All_Databases
| Empty
| Empty
| PubMed
| PubMed
{ api_key :: Maybe String }
| Arxiv
| Arxiv
| HAL (Maybe Org)
| HAL (Maybe Org)
| IsTex
| IsTex
...
@@ -127,7 +123,7 @@ data Database = All_Databases
...
@@ -127,7 +123,7 @@ data Database = All_Databases
derive instance Generic Database _
derive instance Generic Database _
instance Show Database where
instance Show Database where
show All_Databases = "All Databases"
show All_Databases = "All Databases"
show
PubMed
= "PubMed"
show
(PubMed _)
= "PubMed"
show Arxiv = "Arxiv"
show Arxiv = "Arxiv"
show (HAL _) = "HAL"
show (HAL _) = "HAL"
show IsTex = "IsTex"
show IsTex = "IsTex"
...
@@ -139,7 +135,7 @@ instance Show Database where
...
@@ -139,7 +135,7 @@ instance Show Database where
instance Doc Database where
instance Doc Database where
doc All_Databases = "All databases"
doc All_Databases = "All databases"
doc
PubMed
= "All Medical publications"
doc
(PubMed _)
= "All Medical publications"
doc Arxiv = "Arxiv"
doc Arxiv = "Arxiv"
doc (HAL _) = "All open science (archives ouvertes)"
doc (HAL _) = "All open science (archives ouvertes)"
doc IsTex = "All Elsevier enriched by CNRS/INIST"
doc IsTex = "All Elsevier enriched by CNRS/INIST"
...
@@ -149,22 +145,46 @@ instance Doc Database where
...
@@ -149,22 +145,46 @@ instance Doc Database where
-- doc News = "Web filtered by News"
-- doc News = "Web filtered by News"
-- doc SocialNetworks = "Web filtered by MicroBlogs"
-- doc SocialNetworks = "Web filtered by MicroBlogs"
instance Read Database where
-- instance Read Database where
read :: String -> Maybe Database
-- read :: String -> Maybe Database
read "All Databases" = Just All_Databases
-- read "All Databases" = Just All_Databases
read "PubMed" = Just PubMed
-- read "PubMed" = Just PubMed
read "Arxiv" = Just Arxiv
-- read "Arxiv" = Just Arxiv
read "HAL" = Just $ HAL Nothing
-- read "HAL" = Just $ HAL Nothing
read "Isidore" = Just Isidore
-- read "Isidore" = Just Isidore
read "IsTex" = Just IsTex
-- read "IsTex" = Just IsTex
read "IsTex_Advanced" = Just IsTex_Advanced
-- read "IsTex_Advanced" = Just IsTex_Advanced
-- read "Web" = Just Web
-- -- read "Web" = Just Web
-- read "News" = Just News
-- -- read "News" = Just News
-- read "Social Networks" = Just SocialNetworks
-- -- read "Social Networks" = Just SocialNetworks
read _ = Nothing
-- read _ = Nothing
dbToInputValue :: Database -> String
dbToInputValue All_Databases = "all_databases"
dbToInputValue (PubMed _) = "pubmed"
dbToInputValue Arxiv = "arxiv"
dbToInputValue (HAL _) = "hal"
dbToInputValue IsTex = "istex"
dbToInputValue IsTex_Advanced = "istex_advanced"
dbToInputValue Isidore = "isidore"
dbToInputValue Empty = "empty"
dbFromInputValue :: String -> Maybe Database
dbFromInputValue "all_databases" = Just All_Databases
dbFromInputValue "pubmed" = Just (PubMed { api_key: Nothing})
dbFromInputValue "arxiv" = Just Arxiv
dbFromInputValue "hal" = Just (HAL Nothing)
dbFromInputValue "istex" = Just IsTex
dbFromInputValue "istex_advanced" = Just IsTex_Advanced
dbFromInputValue "isidore" = Just Isidore
dbFromInputValue "empty" = Just Empty
dbFromInputValue _ = Nothing
derive instance Eq Database
derive instance Eq Database
instance JSON.WriteForeign Database where writeImpl = JSON.writeImpl <<< show
instance JSON.WriteForeign Database where
writeImpl (PubMed { api_key }) = JSON.writeImpl { tag: "PubMed"
, _api_key: api_key }
writeImpl f = JSON.writeImpl { tag: show f }
------------------------------------------------------------------------
------------------------------------------------------------------------
-- | Organization specifications
-- | Organization specifications
...
@@ -234,16 +254,17 @@ instance Show SearchOrder where
...
@@ -234,16 +254,17 @@ instance Show SearchOrder where
------------------------------------------------------------------------
------------------------------------------------------------------------
newtype SearchQuery = SearchQuery
newtype SearchQuery = SearchQuery
{ query :: String
{ query :: String
, databases :: Database
, databases :: Database
, datafield :: Maybe DataField
, datafield :: Maybe DataField
, files_id :: Array String
, files_id :: Array String
, lang :: Maybe Lang
, lang :: Maybe Lang
, limit :: Maybe Int
, limit :: Maybe Int
, node_id :: Maybe Int
, node_id :: Maybe Int
, offset :: Maybe Int
, offset :: Maybe Int
, order :: Maybe SearchOrder
, order :: Maybe SearchOrder
, selection :: ListSelection.Selection
, pubmedAPIKey :: Maybe String
, selection :: ListSelection.Selection
}
}
derive instance Generic SearchQuery _
derive instance Generic SearchQuery _
derive instance Newtype SearchQuery _
derive instance Newtype SearchQuery _
...
@@ -260,27 +281,29 @@ instance GT.ToQuery SearchQuery where
...
@@ -260,27 +281,29 @@ instance GT.ToQuery SearchQuery where
pair k = maybe [] $ \v ->
pair k = maybe [] $ \v ->
[ QP.keyFromString k /\ Just (QP.valueFromString $ show v) ]
[ QP.keyFromString k /\ Just (QP.valueFromString $ show v) ]
instance JSON.WriteForeign SearchQuery where
instance JSON.WriteForeign SearchQuery where
writeImpl (SearchQuery { databases, datafield, lang, node_id, query, selection }) =
writeImpl (SearchQuery { databases, datafield, lang, node_id,
pubmedAPIKey,
query, selection }) =
JSON.writeImpl { query: query -- String.replace (String.Pattern "\"") (String.Replacement "\\\"") query
JSON.writeImpl { query: query -- String.replace (String.Pattern "\"") (String.Replacement "\\\"") query
, databases
, databases
, datafield
, datafield
, lang: maybe "EN" show lang
, lang: maybe "EN" show lang
, node_id: fromMaybe 0 node_id
, node_id: fromMaybe 0 node_id
, flowListWith: selection
, flowListWith: selection
, pubmedAPIKey
}
}
defaultSearchQuery :: SearchQuery
defaultSearchQuery :: SearchQuery
defaultSearchQuery = SearchQuery
defaultSearchQuery = SearchQuery
{ query : ""
{ query : ""
, databases : Empty
, databases : Empty
, datafield : Nothing
, datafield : Nothing
, files_id : []
, files_id : []
, lang : Nothing
, lang : Nothing
, limit : Nothing
, limit : Nothing
, node_id : Nothing
, node_id : Nothing
, offset : Nothing
, offset : Nothing
, order : Nothing
, order : Nothing
, selection : ListSelection.NoList -- MyListsFirst
, pubmedAPIKey : Nothing
, selection : ListSelection.NoList -- MyListsFirst
}
}
performSearch :: Session -> Int -> SearchQuery -> AffRESTError GT.AsyncTaskWithType
performSearch :: Session -> Int -> SearchQuery -> AffRESTError GT.AsyncTaskWithType
...
...
src/Gargantext/Components/Forest/Tree/Node/Action/Upload.purs
View file @
6ad8d99d
...
@@ -156,6 +156,7 @@ uploadFileViewWithLangsCpt = here.component "uploadFileViewWithLangs" cpt
...
@@ -156,6 +156,7 @@ uploadFileViewWithLangsCpt = here.component "uploadFileViewWithLangs" cpt
[ formChoiceSafe { items: [ CSV
[ formChoiceSafe { items: [ CSV
, CSV_HAL
, CSV_HAL
, WOS
, WOS
, JSON
-- , Iramuteq
-- , Iramuteq
]
]
, default: CSV
, default: CSV
...
@@ -585,7 +586,7 @@ uploadFile { contents, fileFormat, lang, fileType, id, nodeType, mName, selectio
...
@@ -585,7 +586,7 @@ uploadFile { contents, fileFormat, lang, fileType, id, nodeType, mName, selectio
, Tuple "_wjf_name" mName
, Tuple "_wjf_name" mName
]
]
csvBodyParams = [ Tuple "_wtf_data" (Just contents)
csvBodyParams = [ Tuple "_wtf_data" (Just contents)
, Tuple "_wtf_filetype" (Just $ show
NodeList
)
, Tuple "_wtf_filetype" (Just $ show
fileType
)
, Tuple "_wtf_fileformat" (Just $ show fileFormat)
, Tuple "_wtf_fileformat" (Just $ show fileFormat)
, Tuple "_wf_lang" (Just $ show lang)
, Tuple "_wf_lang" (Just $ show lang)
, Tuple "_wtf_name" mName
, Tuple "_wtf_name" mName
...
...
src/Gargantext/Components/GraphQL.purs
View file @
6ad8d99d
...
@@ -14,7 +14,7 @@ import Gargantext.Components.GraphQL.Contact (AnnuaireContact)
...
@@ -14,7 +14,7 @@ import Gargantext.Components.GraphQL.Contact (AnnuaireContact)
import Gargantext.Components.GraphQL.Context as GQLCTX
import Gargantext.Components.GraphQL.Context as GQLCTX
import Gargantext.Components.GraphQL.IMT as GQLIMT
import Gargantext.Components.GraphQL.IMT as GQLIMT
import Gargantext.Components.GraphQL.NLP as GQLNLP
import Gargantext.Components.GraphQL.NLP as GQLNLP
import Gargantext.Components.GraphQL.Node
(Node)
import Gargantext.Components.GraphQL.Node
as GQLNode
import Gargantext.Components.GraphQL.Tree (TreeFirstLevel)
import Gargantext.Components.GraphQL.Tree (TreeFirstLevel)
import Gargantext.Components.GraphQL.User (User, UserInfo, UserInfoM)
import Gargantext.Components.GraphQL.User (User, UserInfo, UserInfoM)
import Gargantext.Components.GraphQL.Team (Team, TeamDeleteM)
import Gargantext.Components.GraphQL.Team (Team, TeamDeleteM)
...
@@ -78,8 +78,9 @@ type Schema
...
@@ -78,8 +78,9 @@ type Schema
, contexts_for_ngrams :: { corpus_id :: Int, ngrams_terms :: Array String } ==> Array GQLCTX.Context
, contexts_for_ngrams :: { corpus_id :: Int, ngrams_terms :: Array String } ==> Array GQLCTX.Context
, imt_schools :: {} ==> Array GQLIMT.School
, imt_schools :: {} ==> Array GQLIMT.School
, languages :: {} ==> Array GQLNLP.Language
, languages :: {} ==> Array GQLNLP.Language
, node_parent :: { node_id :: Int, parent_type :: String } ==> Array Node -- TODO: parent_type :: NodeType
, node_parent :: { node_id :: Int, parent_type :: String } ==> Array GQLNode.Node -- TODO: parent_type :: NodeType
, nodes :: { node_id :: Int } ==> Array Node
, nodes :: { node_id :: Int } ==> Array GQLNode.Node
, nodes_corpus :: { corpus_id :: Int } ==> Array GQLNode.Corpus
, user_infos :: { user_id :: Int } ==> Array UserInfo
, user_infos :: { user_id :: Int } ==> Array UserInfo
, users :: { user_id :: Int } ==> Array User
, users :: { user_id :: Int } ==> Array User
, team :: { team_node_id :: Int } ==> Team
, team :: { team_node_id :: Int } ==> Team
...
...
src/Gargantext/Components/GraphQL/Endpoints.purs
View file @
6ad8d99d
...
@@ -14,7 +14,7 @@ import Gargantext.Components.GraphQL.Contact (AnnuaireContact, annuaireContactQu
...
@@ -14,7 +14,7 @@ import Gargantext.Components.GraphQL.Contact (AnnuaireContact, annuaireContactQu
import Gargantext.Components.GraphQL.Context as GQLCTX
import Gargantext.Components.GraphQL.Context as GQLCTX
import Gargantext.Components.GraphQL.IMT as GQLIMT
import Gargantext.Components.GraphQL.IMT as GQLIMT
import Gargantext.Components.GraphQL.NLP as GQLNLP
import Gargantext.Components.GraphQL.NLP as GQLNLP
import Gargantext.Components.GraphQL.Node (
Node, nodeParentQuery, node
sQuery)
import Gargantext.Components.GraphQL.Node (
Corpus, Node, nodeParentQuery, nodesQuery, nodesCorpu
sQuery)
import Gargantext.Components.GraphQL.Team (Team, teamQuery)
import Gargantext.Components.GraphQL.Team (Team, teamQuery)
import Gargantext.Components.GraphQL.Tree (TreeFirstLevel, treeFirstLevelQuery)
import Gargantext.Components.GraphQL.Tree (TreeFirstLevel, treeFirstLevelQuery)
import Gargantext.Components.GraphQL.User (UserInfo, userInfoQuery)
import Gargantext.Components.GraphQL.User (UserInfo, userInfoQuery)
...
@@ -46,6 +46,15 @@ getNode session nodeId = do
...
@@ -46,6 +46,15 @@ getNode session nodeId = do
Nothing -> Left (CustomError $ "node with id" <> show nodeId <>" not found")
Nothing -> Left (CustomError $ "node with id" <> show nodeId <>" not found")
Just node -> Right node
Just node -> Right node
getNodeCorpus :: Session -> Int -> AffRESTError Corpus
getNodeCorpus session corpusId = do
{ nodes_corpus } <- queryGql session "get nodes corpus" $
nodesCorpusQuery `withVars` { id: corpusId }
liftEffect $ here.log2 "[getNodesCorpus] nodes_corpus" nodes_corpus
pure $ case A.head nodes_corpus of
Nothing -> Left (CustomError $ "corpus with id" <> show corpusId <>" not found")
Just corpus -> Right corpus
getNodeParent :: Session -> Int -> NodeType -> Aff (Array Node)
getNodeParent :: Session -> Int -> NodeType -> Aff (Array Node)
getNodeParent session nodeId parentType = do
getNodeParent session nodeId parentType = do
{ node_parent } <- queryGql session "get node parent" $
{ node_parent } <- queryGql session "get node parent" $
...
...
src/Gargantext/Components/GraphQL/Node.purs
View file @
6ad8d99d
...
@@ -2,18 +2,35 @@ module Gargantext.Components.GraphQL.Node where
...
@@ -2,18 +2,35 @@ module Gargantext.Components.GraphQL.Node where
import Gargantext.Prelude
import Gargantext.Prelude
import Data.Maybe (Maybe)
import GraphQL.Client.Args (Args, (=>>))
import GraphQL.Client.Args (Args, (=>>))
import GraphQL.Client.Variable (Var(..))
import GraphQL.Client.Variable (Var(..))
import Gargantext.Utils.GraphQL as GGQL
import Gargantext.Utils.GraphQL as GGQL
import Type.Proxy (Proxy(..))
import Type.Proxy (Proxy(..))
type Corpus
= { id :: Int
, name :: String
, parent_id :: Int
, pubmedAPIKey :: Maybe String
, type_id :: Int }
type Node
type Node
= { id :: Int
= { id :: Int
, name :: String
, name :: String
, parent_id :: Int
, parent_id :: Int
, type_id :: Int }
, type_id :: Int }
type NodesCorpusQuery =
{ nodes_corpus :: Args
{ corpus_id :: Var "id" Int }
{ id :: Unit
, name :: Unit
, parent_id :: Unit
, pubmedAPIKey :: Unit
, type_id :: Unit } }
type NodesQuery =
type NodesQuery =
{ nodes :: Args
{ nodes :: Args
{ node_id :: Var "id" Int }
{ node_id :: Var "id" Int }
...
@@ -27,6 +44,11 @@ nodesQuery = { nodes: { node_id: Var :: _ "id" Int } =>>
...
@@ -27,6 +44,11 @@ nodesQuery = { nodes: { node_id: Var :: _ "id" Int } =>>
GGQL.getFieldsStandard (Proxy :: _ Node)
GGQL.getFieldsStandard (Proxy :: _ Node)
}
}
nodesCorpusQuery :: NodesCorpusQuery
nodesCorpusQuery = { nodes_corpus: { corpus_id: Var :: _ "id" Int } =>>
GGQL.getFieldsStandard (Proxy :: _ Corpus)
}
nodeParentQuery = { node_parent: { node_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" String } =>> -- TODO parent_type :: NodeType
GGQL.getFieldsStandard (Proxy :: _ Node)
GGQL.getFieldsStandard (Proxy :: _ Node)
...
...
src/Gargantext/Components/NgramsTable.purs
View file @
6ad8d99d
...
@@ -13,6 +13,7 @@ import Gargantext.Prelude
...
@@ -13,6 +13,7 @@ import Gargantext.Prelude
import Data.Array as A
import Data.Array as A
import Data.Array as Array
import Data.Array as Array
import Data.Either (Either(..))
import Data.Either (Either(..))
import Data.Foldable (any)
import Data.FunctorWithIndex (mapWithIndex)
import Data.FunctorWithIndex (mapWithIndex)
import Data.Lens (to, view, (.~), (^.), (^?))
import Data.Lens (to, view, (.~), (^.), (^?))
import Data.Lens.At (at)
import Data.Lens.At (at)
...
@@ -47,7 +48,7 @@ import Gargantext.Components.Table.Types (Params, orderByToGTOrderBy)
...
@@ -47,7 +48,7 @@ import Gargantext.Components.Table.Types (Params, orderByToGTOrderBy)
import Gargantext.Components.Table.Types as TT
import Gargantext.Components.Table.Types as TT
import Gargantext.Config.REST (AffRESTError, RESTError, logRESTError)
import Gargantext.Config.REST (AffRESTError, RESTError, logRESTError)
import Gargantext.Core.NgramsTable.Functions (addNewNgramA, applyNgramsPatches, chartsAfterSync, commitPatch, convOrderBy, coreDispatch, filterTermSize, ngramsRepoElementToNgramsElement, normNgram, patchSetFromMap, singletonNgramsTablePatch, tablePatchHasNgrams, toVersioned)
import Gargantext.Core.NgramsTable.Functions (addNewNgramA, applyNgramsPatches, chartsAfterSync, commitPatch, convOrderBy, coreDispatch, filterTermSize, ngramsRepoElementToNgramsElement, normNgram, patchSetFromMap, singletonNgramsTablePatch, tablePatchHasNgrams, toVersioned)
import Gargantext.Core.NgramsTable.Types (Action(..), CoreAction(..), State, Dispatch, NgramsActionRef, NgramsClick, NgramsElement(..), NgramsPatch(..), NgramsTable, NgramsTablePatch(..), NgramsTerm(..), PageParams, PatchMap(..), Versioned(..), VersionedNgramsTable, VersionedWithCountNgramsTable, _NgramsElement, _NgramsRepoElement, _NgramsTable, _children, _list, _ngrams, _ngrams_repo_elements, _ngrams_scores, _occurrences, _root, applyPatchSet, ngramsTermText, replace)
import Gargantext.Core.NgramsTable.Types (Action(..), CoreAction(..), State, Dispatch, NgramsActionRef, NgramsClick, NgramsElement(..), NgramsPatch(..), Ngrams
RepoElement(..), Ngrams
Table, NgramsTablePatch(..), NgramsTerm(..), PageParams, PatchMap(..), Versioned(..), VersionedNgramsTable, VersionedWithCountNgramsTable, _NgramsElement, _NgramsRepoElement, _NgramsTable, _children, _list, _ngrams, _ngrams_repo_elements, _ngrams_scores, _occurrences, _root, applyPatchSet, ngramsTermText, replace)
import Gargantext.Hooks.Loader (useLoaderBox)
import Gargantext.Hooks.Loader (useLoaderBox)
import Gargantext.Routes (SessionRoute(..)) as Routes
import Gargantext.Routes (SessionRoute(..)) as Routes
import Gargantext.Sessions (Session, get)
import Gargantext.Sessions (Session, get)
...
@@ -525,7 +526,11 @@ loadedNgramsTableBodyCpt = here.component "loadedNgramsTableBody" cpt where
...
@@ -525,7 +526,11 @@ loadedNgramsTableBodyCpt = here.component "loadedNgramsTableBody" cpt where
exactMatches :: Boolean
exactMatches :: Boolean
exactMatches = not $ Seq.null $ Seq.filter fltr nres
exactMatches = not $ Seq.null $ Seq.filter fltr nres
where
where
fltr (Tuple ng _) = queryExactMatchesLabel searchQuery (ngramsTermText ng)
-- | Match either ngrams term or its children with the
-- | `queryExactMatchesLabel` function.
fltr :: Tuple NgramsTerm NgramsRepoElement -> Boolean
fltr (Tuple ng (NgramsRepoElement { children })) =
any (queryExactMatchesLabel searchQuery) $ (Set.map ngramsTermText $ Set.insert ng children)
rowsFilter :: NgramsElement -> Maybe NgramsElement
rowsFilter :: NgramsElement -> Maybe NgramsElement
rowsFilter ngramsElement =
rowsFilter ngramsElement =
if displayRow { ngramsElement
if displayRow { ngramsElement
...
...
src/Gargantext/Components/TopBar.purs
View file @
6ad8d99d
...
@@ -177,7 +177,7 @@ divDropdownLeftCpt = here.component "divDropdownLeft" cpt
...
@@ -177,7 +177,7 @@ divDropdownLeftCpt = here.component "divDropdownLeft" cpt
]
]
, -----------------------------------------------------------
, -----------------------------------------------------------
[ LiNav { title : "Chat"
[ LiNav { title : "Chat"
, href : "https://
chat.iscpif.fr/channel/
gargantext"
, href : "https://
webchat.oftc.net/?channels=#
gargantext"
, icon : "fa fa-rocket"
, icon : "fa fa-rocket"
, text : "Chat"
, text : "Chat"
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment