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
import Gargantext.Prelude
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.Hooks.Loader (useLoaderWithCacheAPI, HashedResponse(..))
import Gargantext.Utils.Reactix as R2
......@@ -43,17 +43,68 @@ thisModule :: String
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"
type CarousselProps = (
category :: Category
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
, nodeId :: NodeID
, row :: DocumentsView
, session :: Session
, setLocalCategories :: R.Setter LocalCategories
)
-- caroussel :: Category -> R.Element
caroussel :: R2.Component CarousselProps
caroussel = R.createElement carousselCpt
......@@ -79,7 +130,9 @@ carousselCpt = R.hooksComponentWithModule thisModule "caroussel" cpt
onClick c = \_-> do
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 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 false s = "btn " <> s
-------------------------------------------------------------------------
newtype CategoryQuery = CategoryQuery {
nodeIds :: Array Int
, category :: Category
......
......@@ -8,7 +8,40 @@ import Data.Generic.Rep.Show (genericShow)
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
categories :: Array Category
......
......@@ -24,8 +24,8 @@ import Reactix as R
import Reactix.DOM.HTML as H
------------------------------------------------------------------------
import Gargantext.Prelude
import Gargantext.Components.Category (caroussel)
import Gargantext.Components.Category.Types (Category(..), decodeCategory)
import Gargantext.Components.Category (caroussel, rating)
import Gargantext.Components.Category.Types (Category(..), decodeCategory, Star(..), decodeStar)
import Gargantext.Components.DocsTable.Types
import Gargantext.Components.Table.Types as T
import Gargantext.Components.Nodes.Lists.Types as NT
......@@ -274,7 +274,7 @@ pageLayoutCpt = R.hooksComponentWithModule thisModule "pageLayout" cpt where
, renderer: paint
}
(NT.CacheOff /\ _) -> do
localCategories <- R.useState' (mempty :: LocalCategories)
localCategories <- R.useState' (mempty :: LocalUserScore)
paramsS <- R.useState' params
let loader p = do
let route = tableRouteWithPage (p { params = fst paramsS, query = query })
......@@ -318,7 +318,7 @@ pagePaintCpt :: R.Component PagePaintProps
pagePaintCpt = R.hooksComponentWithModule thisModule "pagePaintCpt" cpt
where
cpt { documents, layout, params } _ = do
localCategories <- R.useState' (mempty :: LocalCategories)
localCategories <- R.useState' (mempty :: LocalUserScore)
pure $ pagePaintRaw { documents: A.fromFoldable filteredRows
, layout
, localCategories
......@@ -339,7 +339,7 @@ pagePaintCpt = R.hooksComponentWithModule thisModule "pagePaintCpt" cpt
type PagePaintRawProps = (
documents :: Array DocumentsView
, layout :: Record PageLayoutProps
, localCategories :: R.State LocalCategories
, localCategories :: R.State LocalUserScore
, params :: R.State T.Params
)
......@@ -372,9 +372,9 @@ pagePaintRawCpt = R.hooksComponentWithModule thisModule "pagePaintRawCpt" cpt wh
}
where
sid = sessionId session
gi Favorite = "glyphicon glyphicon-star"
gi Star_1 = "glyphicon glyphicon-star"
gi _ = "glyphicon glyphicon-star-empty"
trashClassName Trash _ = "trash"
trashClassName Star_0 _ = "trash"
trashClassName _ true = "active"
trashClassName _ false = ""
corpusDocument
......@@ -390,7 +390,8 @@ pagePaintRawCpt = R.hooksComponentWithModule thisModule "pagePaintRawCpt" cpt wh
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" } [ 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} }
-- TODO show date: Year-Month-Day only
, H.div { className: tClassName } [ R2.showText r.date ]
......@@ -403,7 +404,7 @@ pagePaintRawCpt = R.hooksComponentWithModule thisModule "pagePaintRawCpt" cpt wh
, delete: true }
where
cat = getCategory lc r
checked = Trash == cat
checked = Star_1 == cat
tClassName = trashClassName cat selected
className = gi cat
selected = R.readRef currentDocIdRef == Just r._id
......
......@@ -8,7 +8,7 @@ import Data.Tuple (Tuple(..))
import Gargantext.Prelude
import Gargantext.Components.Category.Types (Category(..), decodeCategory)
import Gargantext.Components.Category.Types (Category(..), decodeCategory, Star(..), decodeStar)
data Action
= MarkCategory Int Category
......@@ -16,7 +16,7 @@ data Action
newtype DocumentsView
= DocumentsView
{ _id :: Int
, category :: Category
, category :: Star
, date :: Int
, ngramCount :: Maybe Int
, score :: Maybe Int
......@@ -63,7 +63,7 @@ instance encodeDocumentsView :: EncodeJson DocumentsView where
newtype Response = Response
{ cid :: Int
, hyperdata :: Hyperdata
, category :: Category
, category :: Star
, ngramCount :: Maybe Int
, score :: Maybe Int
, title :: String
......@@ -94,10 +94,11 @@ instance decodeResponse :: DecodeJson Response where
ngramCount <- obj .: "ngramCount"
score <- obj .: "score"
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 LocalUserScore = Map Int Star
type Query = String
---------------------------------------------------------
......@@ -107,7 +108,7 @@ sampleData' = DocumentsView { _id : 1
, date : 2010
, title : "title"
, source : "source"
, category : UnRead
, category : Star_1
, ngramCount : Just 1
, score: Just 1 }
......@@ -118,7 +119,7 @@ sampleData = map (\(Tuple t s) -> DocumentsView { _id : 1
, date : 2017
, title: t
, source: s
, category : UnRead
, category : Star_1
, ngramCount : Just 10
, 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