Commit 5e5108ac authored by Alexandre Delanoë's avatar Alexandre Delanoë

[FEAT] Docs Table, user ratings ergonomy improved (majoritaire vote inside)

parent 7b35504a
...@@ -29,7 +29,7 @@ import Reactix.DOM.HTML as H ...@@ -29,7 +29,7 @@ import Reactix.DOM.HTML as H
import Gargantext.Prelude import Gargantext.Prelude
import Gargantext.Components.Category.Types import Gargantext.Components.Category.Types
import Gargantext.Components.DocsTable.Types (DocumentsView(..), LocalCategories) import Gargantext.Components.DocsTable.Types (DocumentsView(..), LocalCategories, LocalUserScore)
import Gargantext.Ends (Frontends, url) import Gargantext.Ends (Frontends, url)
import Gargantext.Hooks.Loader (useLoaderWithCacheAPI, HashedResponse(..)) import Gargantext.Hooks.Loader (useLoaderWithCacheAPI, HashedResponse(..))
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
...@@ -43,17 +43,68 @@ thisModule :: String ...@@ -43,17 +43,68 @@ thisModule :: String
thisModule = "Gargantext.Components.Category" thisModule = "Gargantext.Components.Category"
------------------------------------------------------------------------ ------------------------------------------------------------------------
type RatingProps =
( score :: Star
, nodeId :: NodeID
, row :: DocumentsView
, session :: Session
, setLocalCategories :: R.Setter LocalUserScore
)
rating :: R2.Component RatingProps
rating = R.createElement ratingCpt
ratingCpt :: R.Component RatingProps
ratingCpt = R.hooksComponentWithModule thisModule "rating" cpt
where
cpt { score, nodeId, row: DocumentsView r, session, setLocalCategories } _ = do
pure $ H.div {className:"flex"} divs
where
divs = map (\s -> H.div { className : icon score s
, on: {click: onClick score s}
} []) stars
icon Star_0 Star_0 = "fa fa-times-circle"
icon _ Star_0 = "fa fa-times"
icon c s = if star2score c < star2score s
then "fa fa-star-o"
else "fa fa-star"
onClick score c = \_-> do
setLocalCategories $ Map.insert r._id c
void $ launchAff
$ putRating session nodeId
$ RatingQuery {nodeIds: [r._id], rating: c}
newtype RatingQuery =
RatingQuery { nodeIds :: Array Int
, rating :: Star
}
instance encodeJsonRatingQuery :: EncodeJson RatingQuery where
encodeJson (RatingQuery post) =
"ntc_nodesId" := post.nodeIds
~> "ntc_category" := encodeJson post.rating
~> jsonEmptyObject
putRating :: Session -> Int -> RatingQuery -> Aff (Array Int)
putRating session nodeId = put session $ ratingRoute nodeId
where
ratingRoute :: Int -> SessionRoute
ratingRoute nodeId = NodeAPI Node (Just nodeId) "category"
type CarousselProps = (
category :: Category ------------------------------------------------------------------------
type CarousselProps =
( category :: Category
, nodeId :: NodeID , nodeId :: NodeID
, row :: DocumentsView , row :: DocumentsView
, session :: Session , session :: Session
, setLocalCategories :: R.Setter LocalCategories , setLocalCategories :: R.Setter LocalCategories
) )
-- caroussel :: Category -> R.Element
caroussel :: R2.Component CarousselProps caroussel :: R2.Component CarousselProps
caroussel = R.createElement carousselCpt caroussel = R.createElement carousselCpt
...@@ -79,7 +130,9 @@ carousselCpt = R.hooksComponentWithModule thisModule "caroussel" cpt ...@@ -79,7 +130,9 @@ carousselCpt = R.hooksComponentWithModule thisModule "caroussel" cpt
onClick c = \_-> do onClick c = \_-> do
setLocalCategories $ Map.insert r._id c setLocalCategories $ Map.insert r._id c
void $ launchAff $ putCategories session nodeId $ CategoryQuery {nodeIds: [r._id], category: c} void $ launchAff
$ putCategories session nodeId
$ CategoryQuery {nodeIds: [r._id], category: c}
icon :: Category -> Boolean -> String icon :: Category -> Boolean -> String
icon cat b = btn b $ "glyphicon glyphicon-" <> (color $ size b $ icon' cat b) icon cat b = btn b $ "glyphicon glyphicon-" <> (color $ size b $ icon' cat b)
...@@ -111,7 +164,7 @@ icon cat b = btn b $ "glyphicon glyphicon-" <> (color $ size b $ icon' cat b) ...@@ -111,7 +164,7 @@ icon cat b = btn b $ "glyphicon glyphicon-" <> (color $ size b $ icon' cat b)
btn true s = s btn true s = s
btn false s = "btn " <> s btn false s = "btn " <> s
-------------------------------------------------------------------------
newtype CategoryQuery = CategoryQuery { newtype CategoryQuery = CategoryQuery {
nodeIds :: Array Int nodeIds :: Array Int
, category :: Category , category :: Category
......
...@@ -8,7 +8,40 @@ import Data.Generic.Rep.Show (genericShow) ...@@ -8,7 +8,40 @@ import Data.Generic.Rep.Show (genericShow)
import Gargantext.Prelude import Gargantext.Prelude
------------------------------------------------------------------------ ------------------------------------------------------------------------
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 genericStar :: Generic Star _
instance showStar :: Show Star where
show = genericShow
instance eqStar :: Eq Star where
eq = genericEq
instance decodeJsonStar :: DecodeJson Star where
decodeJson json = do
obj <- decodeJson json
pure $ decodeStar obj
instance encodeJsonStar :: EncodeJson Star where
encodeJson x = encodeJson (star2score x)
decodeStar :: Int -> Star
decodeStar 0 = Star_1
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
------------------------------------------------------------------------
data Category = Trash | UnRead | Checked | Topic | Favorite data Category = Trash | UnRead | Checked | Topic | Favorite
categories :: Array Category categories :: Array Category
......
...@@ -24,8 +24,8 @@ import Reactix as R ...@@ -24,8 +24,8 @@ import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
------------------------------------------------------------------------ ------------------------------------------------------------------------
import Gargantext.Prelude import Gargantext.Prelude
import Gargantext.Components.Category (caroussel) import Gargantext.Components.Category (caroussel, rating)
import Gargantext.Components.Category.Types (Category(..), decodeCategory) import Gargantext.Components.Category.Types (Category(..), decodeCategory, Star(..), decodeStar)
import Gargantext.Components.DocsTable.Types import Gargantext.Components.DocsTable.Types
import Gargantext.Components.Table.Types as T import Gargantext.Components.Table.Types as T
import Gargantext.Components.Nodes.Lists.Types as NT import Gargantext.Components.Nodes.Lists.Types as NT
...@@ -274,7 +274,7 @@ pageLayoutCpt = R.hooksComponentWithModule thisModule "pageLayout" cpt where ...@@ -274,7 +274,7 @@ pageLayoutCpt = R.hooksComponentWithModule thisModule "pageLayout" cpt where
, renderer: paint , renderer: paint
} }
(NT.CacheOff /\ _) -> do (NT.CacheOff /\ _) -> do
localCategories <- R.useState' (mempty :: LocalCategories) localCategories <- R.useState' (mempty :: LocalUserScore)
paramsS <- R.useState' params paramsS <- R.useState' params
let loader p = do let loader p = do
let route = tableRouteWithPage (p { params = fst paramsS, query = query }) let route = tableRouteWithPage (p { params = fst paramsS, query = query })
...@@ -318,7 +318,7 @@ pagePaintCpt :: R.Component PagePaintProps ...@@ -318,7 +318,7 @@ pagePaintCpt :: R.Component PagePaintProps
pagePaintCpt = R.hooksComponentWithModule thisModule "pagePaintCpt" cpt pagePaintCpt = R.hooksComponentWithModule thisModule "pagePaintCpt" cpt
where where
cpt { documents, layout, params } _ = do cpt { documents, layout, params } _ = do
localCategories <- R.useState' (mempty :: LocalCategories) localCategories <- R.useState' (mempty :: LocalUserScore)
pure $ pagePaintRaw { documents: A.fromFoldable filteredRows pure $ pagePaintRaw { documents: A.fromFoldable filteredRows
, layout , layout
, localCategories , localCategories
...@@ -339,7 +339,7 @@ pagePaintCpt = R.hooksComponentWithModule thisModule "pagePaintCpt" cpt ...@@ -339,7 +339,7 @@ pagePaintCpt = R.hooksComponentWithModule thisModule "pagePaintCpt" cpt
type PagePaintRawProps = ( type PagePaintRawProps = (
documents :: Array DocumentsView documents :: Array DocumentsView
, layout :: Record PageLayoutProps , layout :: Record PageLayoutProps
, localCategories :: R.State LocalCategories , localCategories :: R.State LocalUserScore
, params :: R.State T.Params , params :: R.State T.Params
) )
...@@ -372,9 +372,9 @@ pagePaintRawCpt = R.hooksComponentWithModule thisModule "pagePaintRawCpt" cpt wh ...@@ -372,9 +372,9 @@ pagePaintRawCpt = R.hooksComponentWithModule thisModule "pagePaintRawCpt" cpt wh
} }
where where
sid = sessionId session sid = sessionId session
gi Favorite = "glyphicon glyphicon-star" gi Star_1 = "glyphicon glyphicon-star"
gi _ = "glyphicon glyphicon-star-empty" gi _ = "glyphicon glyphicon-star-empty"
trashClassName Trash _ = "trash" trashClassName Star_0 _ = "trash"
trashClassName _ true = "active" trashClassName _ true = "active"
trashClassName _ false = "" trashClassName _ false = ""
corpusDocument corpusDocument
...@@ -390,7 +390,8 @@ pagePaintRawCpt = R.hooksComponentWithModule thisModule "pagePaintRawCpt" cpt wh ...@@ -390,7 +390,8 @@ pagePaintRawCpt = R.hooksComponentWithModule thisModule "pagePaintRawCpt" cpt wh
T.makeRow [ -- H.div {} [ H.a { className, style, on: {click: click Favorite} } [] ] T.makeRow [ -- H.div {} [ H.a { className, style, on: {click: click Favorite} } [] ]
H.div { className: "column-tag flex" } [ docChooser { listId, mCorpusId, nodeId: r._id, selected, sidePanelTriggers, tableReload: reload } [] H.div { className: "column-tag flex" } [ docChooser { listId, mCorpusId, nodeId: r._id, selected, sidePanelTriggers, tableReload: reload } []
] ]
, H.div { className: "column-tag flex" } [ caroussel { category: cat, nodeId, row: dv, session, setLocalCategories } [] ] --, H.div { className: "column-tag flex" } [ caroussel { category: cat, nodeId, row: dv, session, setLocalCategories } [] ]
, H.div { className: "column-tag flex" } [ rating { score: cat, nodeId, row: dv, session, setLocalCategories } [] ]
--, H.input { type: "checkbox", defaultValue: checked, on: {click: click Trash} } --, H.input { type: "checkbox", defaultValue: checked, on: {click: click Trash} }
-- TODO show date: Year-Month-Day only -- TODO show date: Year-Month-Day only
, H.div { className: tClassName } [ R2.showText r.date ] , H.div { className: tClassName } [ R2.showText r.date ]
...@@ -403,7 +404,7 @@ pagePaintRawCpt = R.hooksComponentWithModule thisModule "pagePaintRawCpt" cpt wh ...@@ -403,7 +404,7 @@ pagePaintRawCpt = R.hooksComponentWithModule thisModule "pagePaintRawCpt" cpt wh
, delete: true } , delete: true }
where where
cat = getCategory lc r cat = getCategory lc r
checked = Trash == cat checked = Star_1 == cat
tClassName = trashClassName cat selected tClassName = trashClassName cat selected
className = gi cat className = gi cat
selected = R.readRef currentDocIdRef == Just r._id selected = R.readRef currentDocIdRef == Just r._id
......
...@@ -8,7 +8,7 @@ import Data.Tuple (Tuple(..)) ...@@ -8,7 +8,7 @@ import Data.Tuple (Tuple(..))
import Gargantext.Prelude import Gargantext.Prelude
import Gargantext.Components.Category.Types (Category(..), decodeCategory) import Gargantext.Components.Category.Types (Category(..), decodeCategory, Star(..), decodeStar)
data Action data Action
= MarkCategory Int Category = MarkCategory Int Category
...@@ -16,7 +16,7 @@ data Action ...@@ -16,7 +16,7 @@ data Action
newtype DocumentsView newtype DocumentsView
= DocumentsView = DocumentsView
{ _id :: Int { _id :: Int
, category :: Category , category :: Star
, date :: Int , date :: Int
, ngramCount :: Maybe Int , ngramCount :: Maybe Int
, score :: Maybe Int , score :: Maybe Int
...@@ -63,7 +63,7 @@ instance encodeDocumentsView :: EncodeJson DocumentsView where ...@@ -63,7 +63,7 @@ instance encodeDocumentsView :: EncodeJson DocumentsView where
newtype Response = Response newtype Response = Response
{ cid :: Int { cid :: Int
, hyperdata :: Hyperdata , hyperdata :: Hyperdata
, category :: Category , category :: Star
, ngramCount :: Maybe Int , ngramCount :: Maybe Int
, score :: Maybe Int , score :: Maybe Int
, title :: String , title :: String
...@@ -94,10 +94,11 @@ instance decodeResponse :: DecodeJson Response where ...@@ -94,10 +94,11 @@ instance decodeResponse :: DecodeJson Response where
ngramCount <- obj .: "ngramCount" ngramCount <- obj .: "ngramCount"
score <- obj .: "score" score <- obj .: "score"
title <- obj .: "title" title <- obj .: "title"
pure $ Response { category: decodeCategory category, cid, hyperdata, ngramCount, score, title } --pure $ Response { category: decodeCategory category, cid, hyperdata, ngramCount, score, title }
pure $ Response { category: decodeStar category, cid, hyperdata, ngramCount, score, title }
type LocalCategories = Map Int Category type LocalCategories = Map Int Category
type LocalUserScore = Map Int Star
type Query = String type Query = String
--------------------------------------------------------- ---------------------------------------------------------
...@@ -107,7 +108,7 @@ sampleData' = DocumentsView { _id : 1 ...@@ -107,7 +108,7 @@ sampleData' = DocumentsView { _id : 1
, date : 2010 , date : 2010
, title : "title" , title : "title"
, source : "source" , source : "source"
, category : UnRead , category : Star_1
, ngramCount : Just 1 , ngramCount : Just 1
, score: Just 1 } , score: Just 1 }
...@@ -118,7 +119,7 @@ sampleData = map (\(Tuple t s) -> DocumentsView { _id : 1 ...@@ -118,7 +119,7 @@ sampleData = map (\(Tuple t s) -> DocumentsView { _id : 1
, date : 2017 , date : 2017
, title: t , title: t
, source: s , source: s
, category : UnRead , category : Star_1
, ngramCount : Just 10 , ngramCount : Just 10
, score: Just 1 }) sampleDocuments , score: Just 1 }) sampleDocuments
......
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