Commit 76e18024 authored by Abinaya Sudhir's avatar Abinaya Sudhir

pulled code

parents ac67045d dfb784a8
...@@ -30,6 +30,7 @@ import Routing.Hash.Aff (setHash) ...@@ -30,6 +30,7 @@ import Routing.Hash.Aff (setHash)
import Thermite (PerformAction, Render, Spec, _render, cotransform, focus, foreach, modifyState, simpleSpec, withState) import Thermite (PerformAction, Render, Spec, _render, cotransform, focus, foreach, modifyState, simpleSpec, withState)
import Unsafe.Coerce (unsafeCoerce) import Unsafe.Coerce (unsafeCoerce)
import Landing as L
type State = type State =
...@@ -47,7 +48,7 @@ newtype Response = Response ...@@ -47,7 +48,7 @@ newtype Response = Response
initialState :: State initialState :: State
initialState = initialState =
{ {
select_database : true select_database : true
, unselect_database : true , unselect_database : true
, response : [] , response : []
} }
...@@ -61,7 +62,10 @@ data Action ...@@ -61,7 +62,10 @@ data Action
| GO | GO
performAction :: forall eff props. PerformAction (console :: CONSOLE, ajax :: AJAX,dom::DOM | eff) State props Action performAction :: forall eff props. PerformAction ( console :: CONSOLE
, ajax :: AJAX
, dom :: DOM
| eff ) State props Action
performAction NoOp _ _ = void do performAction NoOp _ _ = void do
modifyState id modifyState id
...@@ -91,7 +95,8 @@ addcorpusviewSpec = simpleSpec performAction render ...@@ -91,7 +95,8 @@ addcorpusviewSpec = simpleSpec performAction render
render :: Render State props Action render :: Render State props Action
render dispatch _ state _ = render dispatch _ state _ =
[ [
div [className "container"] div [className "container"] [L.jumboTitle false]
, div [className "container"]
[ [
div [className "jumbotron"] div [className "jumbotron"]
[ div [className "row"] [ div [className "row"]
...@@ -180,7 +185,7 @@ getDatabaseDetails reqBody = do ...@@ -180,7 +185,7 @@ getDatabaseDetails reqBody = do
instance decodeJsonresponse :: DecodeJson Response where instance decodeJsonresponse :: DecodeJson Response where
decodeJson json = do decodeJson json = do
obj <- decodeJson json obj <- decodeJson json
count <- obj .? "count" count <- obj .? "count"
name <- obj .? "name" name <- obj .? "name"
pure $ Response {count,name } pure $ Response {count,name }
...@@ -44,47 +44,47 @@ group = unsafeMkProps "group" ...@@ -44,47 +44,47 @@ group = unsafeMkProps "group"
-- onEvents :: String -- PropTypes.object -- onEvents :: String -- PropTypes.object
type EchartsProps eff = type EchartsProps eff =
{ className :: String, { className :: String,
style :: String, -- object, style :: String, -- object,
theme :: String, theme :: String,
group :: String, group :: String,
option :: Option, -- PropTypes.object.isRequired, option :: Option, -- PropTypes.object.isRequired,
initOpts :: String, -- PropTypes.object, initOpts :: String, -- PropTypes.object,
notMerge :: Boolean, notMerge :: Boolean,
lazyUpdate:: Boolean, lazyUpdate :: Boolean,
loading :: Boolean, loading :: Boolean,
optsLoading:: OptsLoading, -- PropTypes.object, optsLoading :: OptsLoading, -- PropTypes.object,
onReady :: String, -- PropTypes.func, onReady :: String, -- PropTypes.func,
resizable :: Boolean, -- PropTypes.bool, resizable :: Boolean, -- PropTypes.bool,
onEvents :: String -- PropTypes.object onEvents :: String -- PropTypes.object
} }
type OptsLoading = type OptsLoading =
{ text :: String, { text :: String,
color :: Color, --- color color :: Color, --- color
textColor :: Color, --color textColor :: Color, --color
maskColor:: Color, --color maskColor :: Color, --color
zlevel :: Int zlevel :: Int
} }
type Option = type Option =
{ title :: Title { title :: Title
, legend :: Legend , legend :: Legend
, tooltip :: Tooltip , tooltip :: Tooltip
, grid :: Grid , grid :: Grid
, xAxis :: Array XAxis , xAxis :: Array XAxis
, yAxis :: Array YAxis , yAxis :: Array YAxis
, series :: Array Series , series :: Array Series
, dataZoom :: Array DataZoom , dataZoom :: Array DataZoom
} }
type DataZoom = type DataZoom =
{"type":: String {"type" :: String
, xAxisIndex:: Int , xAxisIndex :: Int
, filterMode:: String , filterMode :: String
, start:: Int , start :: Int
, end:: Int , end :: Int
} }
type Grid = type Grid =
...@@ -92,66 +92,66 @@ type Grid = ...@@ -92,66 +92,66 @@ type Grid =
} }
type Legend = type Legend =
{"type" :: String {"type" :: String
, show :: Boolean , show :: Boolean
, zlevel :: Number , zlevel :: Number
, z :: Number , z :: Number
, left :: Number , left :: Number
, top :: Number , top :: Number
, right :: Number , right :: Number
, bottom :: Number , bottom :: Number
, width :: Number , width :: Number
, height :: Number , height :: Number
, orient :: String , orient :: String
, align :: String , align :: String
, padding :: Number , padding :: Number
, itemGap :: Number , itemGap :: Number
, itemWidth :: Number , itemWidth :: Number
, itemHeight :: Number , itemHeight :: Number
, formatter :: String , formatter :: String
, selectedMode :: Boolean , selectedMode :: Boolean
, inactiveColor :: Color , inactiveColor :: Color
, selected :: String -- object , selected :: String -- object
, "data" :: Array Data , "data" :: Array Data
} }
type Data = type Data =
{name :: String { name :: String
, icon :: String , icon :: String
, textStyle :: {} , textStyle :: {}
} }
type SubtextStyle = type SubtextStyle =
{ color :: Color { color :: Color
, fontStyle :: String , fontStyle :: String
, fontWeight :: String , fontWeight :: String
, fontFamily :: String , fontFamily :: String
, fontSize :: Int , fontSize :: Int
, align :: String , align :: String
, verticalAlign :: String , verticalAlign :: String
, lineHeight :: Number , lineHeight :: Number
, width :: Number , width :: Number
, height :: Number , height :: Number
, textBorderColor :: String , textBorderColor :: String
, textBorderWidth :: Number , textBorderWidth :: Number
, textShadowColor :: String , textShadowColor :: String
, textShadowBlur :: Number , textShadowBlur :: Number
, textShadowOffsetX :: Number , textShadowOffsetX :: Number
, textShadowOffsetY :: Number , textShadowOffsetY :: Number
, rich :: Rich , rich :: Rich
} }
type Tooltip = type Tooltip =
{ trigger :: String { trigger :: String
, formatter :: String -- TODO function , formatter :: String -- TODO function
} }
type XAxis = type XAxis =
{ "data" :: Array String { "data" :: Array String
, "type" :: String , "type" :: String
, axisTick :: AxisTick , axisTick :: AxisTick
} }
type AxisTick = type AxisTick =
...@@ -160,10 +160,10 @@ type AxisTick = ...@@ -160,10 +160,10 @@ type AxisTick =
} }
type YAxis = type YAxis =
{ "type" :: String { "type" :: String
, name :: String , name :: String
, min :: Int , min :: Int
, position :: String , position :: String
, axisLabel :: AxisLabel , axisLabel :: AxisLabel
} }
...@@ -173,37 +173,37 @@ type AxisLabel = ...@@ -173,37 +173,37 @@ type AxisLabel =
type Series = type Series =
{name :: String { name :: String
, "type" :: String , "type" :: String
, "data" :: Array Int , "data" :: Array Int
} }
type Title = type Title =
{ text :: String { text :: String
, show :: Boolean , show :: Boolean
, link :: String , link :: String
, target :: String , target :: String
, textStyle :: TextStyle , textStyle :: TextStyle
, subtext :: String , subtext :: String
, sublink :: String , sublink :: String
, subtarget :: String , subtarget :: String
, subtextStyle :: SubtextStyle , subtextStyle :: SubtextStyle
, padding :: Number , padding :: Number
, itemGap :: Number , itemGap :: Number
, zlevel :: Number , zlevel :: Number
, z :: Number , z :: Number
, left :: Number , left :: Number
, top :: Number , top :: Number
, right :: Number , right :: Number
, bottom :: Number , bottom :: Number
, backgroundColor :: Color , backgroundColor :: Color
, borderColor :: Color , borderColor :: Color
, borderWidth :: Number , borderWidth :: Number
, borderRadius :: Number -- NumberOrArray , borderRadius :: Number -- NumberOrArray
, shadowBlur :: Number , shadowBlur :: Number
, shadowColor :: Color , shadowColor :: Color
, shadowOffsetX :: Number , shadowOffsetX :: Number
, shadowOffsetY :: Number , shadowOffsetY :: Number
} }
-- data NumberOrArray = Number | Array Number -- data NumberOrArray = Number | Array Number
...@@ -224,23 +224,23 @@ loading :: Boolean -> Props ...@@ -224,23 +224,23 @@ loading :: Boolean -> Props
loading = unsafeMkProps "loading" loading = unsafeMkProps "loading"
type TextStyle = type TextStyle =
{ color :: Color { color :: Color
, fontStyle :: String , fontStyle :: String
, fontWeight :: String , fontWeight :: String
, fontFamily :: String , fontFamily :: String
, fontSize :: Int , fontSize :: Int
, align :: String , align :: String
, verticalAlign :: String , verticalAlign :: String
, lineHeight :: Int , lineHeight :: Int
, width :: Int , width :: Int
, height :: Int , height :: Int
, textBorderColor :: String , textBorderColor :: String
, textBorderWidth :: Int , textBorderWidth :: Int
, textShadowColor :: String , textShadowColor :: String
, textShadowBlur :: Int , textShadowBlur :: Int
, textShadowOffsetX :: Int , textShadowOffsetX :: Int
, textShadowOffsetY :: Int , textShadowOffsetY :: Int
, rich :: Rich , rich :: Rich
} }
foreign import data TextStyleProps :: Type foreign import data TextStyleProps :: Type
...@@ -373,16 +373,20 @@ yAxisIndex = unsafeMkProps "yAxisIndex" ...@@ -373,16 +373,20 @@ yAxisIndex = unsafeMkProps "yAxisIndex"
-- , p'' -- , p''
-- ] -- ]
ex1 :: ReactElement histogram :: ReactElement
ex1 = echarts histogram = echarts
[ option [ option
[ tooltip [trigger "axis"] [ tooltip [trigger "axis"]
, grid [containLabel true] , grid [containLabel true]
, legend [data' ["Query A", "Query B", "Query C"]] , legend [data' ["Map terms coverage", "Favorites", "All"]]
-- , legend [data' ["Map Terms coverage", "Favorites", "All"]]
, xAxis , xAxis
[ type' "category" [ type' "category"
, axisTick [alignWithLabel true] , axisTick [alignWithLabel true]
, data' ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "July", "Aug", "Sep", "Oct", "Nov", "Dec"] , data' ["Jan" , "Feb", "Mar" , "Apr"
, "May", "Jun", "July", "Aug"
, "Sep", "Oct", "Nov" , "Dec"
]
] ]
, dataZoom [dz1,dz1,dz2,dz2] , dataZoom [dz1,dz1,dz2,dz2]
, yAxis [ya1, ya2] , yAxis [ya1, ya2]
...@@ -408,22 +412,22 @@ dz2 = unsafeFromPropsArray ...@@ -408,22 +412,22 @@ dz2 = unsafeFromPropsArray
ya1 = unsafeFromPropsArray ya1 = unsafeFromPropsArray
[ type' "value" [ type' "value"
, name "Publications (by year)" , name "Score metric"
, min 0 , min 0
, position "left" , position "right"
, axisLabel [formatter "{value}"] , axisLabel [formatter "{value}"]
] ]
ya2 = unsafeFromPropsArray ya2 = unsafeFromPropsArray
[ type' "value" [ type' "value"
, name "Score metric" , name "Publications (by year)"
, min 0 , min 0
, position "right" , position "left"
, axisLabel [formatter "{value}"] , axisLabel [formatter "{value}"]
] ]
sd1 = unsafeFromPropsArray sd1 = unsafeFromPropsArray
[ name "Query A" [ name "Map terms coverage"
, type' "line" , type' "line"
, label [normal[showp true, position "top"]] , label [normal[showp true, position "top"]]
, lineStyle [ normal , lineStyle [ normal
...@@ -432,26 +436,26 @@ sd1 = unsafeFromPropsArray ...@@ -432,26 +436,26 @@ sd1 = unsafeFromPropsArray
, shadowBlur 10 , shadowBlur 10
, shadowOffsetY 10 , shadowOffsetY 10
]] ]]
, data' [1, 13, 37, 35, 15, 13, 25, 21, 6, 45, 32, 2] , data' [95, 80, 75, 35, 30, 50, 70, 80, 95, 95, 95, 99]
] ]
sd2 = unsafeFromPropsArray sd3 = unsafeFromPropsArray
[ name "Query B" [ name "All"
, type' "bar" , type' "bar"
, label [normal[showp true, position "top"]] , label [normal[showp true, position "top"]]
, yAxisIndex 1 , yAxisIndex 1
, data' [22, 22, 23, 77, 24, 55, 55, 89, 98, 164, 106, 224] , data' [201, 222, 223, 777, 244, 255, 555, 879, 938, 1364, 1806, 2324]
] ]
sd3 = unsafeFromPropsArray
[ name "Query C" sd2 = unsafeFromPropsArray
[ name "Favorites"
, type' "bar" , type' "bar"
, label [normal[showp true, position "top"]] , label [normal[showp true, position "top"]]
, yAxisIndex 1 , yAxisIndex 1
, data' [201, 222, 223, 777, 244, 255, 555, 879, 938, 1364, 1806, 2324] , data' [22, 22, 23, 77, 24, 55, 139, 350, 150, 164, 106, 224]
] ]
p'' :: ReactElement p'' :: ReactElement
p'' = p [] [] p'' = p [] []
...@@ -2,7 +2,7 @@ module DocView where ...@@ -2,7 +2,7 @@ module DocView where
import Data.Argonaut import Data.Argonaut
import Chart (ex1, p'') import Chart (histogram, p'')
import Control.Monad.Aff (Aff, attempt) import Control.Monad.Aff (Aff, attempt)
import Control.Monad.Aff.Class (liftAff) import Control.Monad.Aff.Class (liftAff)
import Control.Monad.Cont.Trans (lift) import Control.Monad.Cont.Trans (lift)
...@@ -26,8 +26,8 @@ import Partial.Unsafe (unsafePartial) ...@@ -26,8 +26,8 @@ import Partial.Unsafe (unsafePartial)
import Prelude (class Eq, class Ord, class Show, Unit, bind, map, not, pure, show, void, ($), (*), (+), (-), (/), (<), (<$>), (<>), (==), (>), (>=), (>>=)) import Prelude (class Eq, class Ord, class Show, Unit, bind, map, not, pure, show, void, ($), (*), (+), (-), (/), (<), (<$>), (<>), (==), (>), (>=), (>>=))
import React (ReactElement) import React (ReactElement)
import React as R import React as R
import React.DOM (a, b, b', br', div, h3, i, input, li, option, select, span, table, tbody, td, text, thead, tr, ul) import React.DOM (a, b, b', br', div, h3, i, input, li, option, select, span, table, tbody, td, text, thead, th, tr, ul, nav)
import React.DOM.Props (Props, _type, className, href, onChange, onClick, selected, value) import React.DOM.Props (Props, _type, className, href, onChange, onClick, selected, value, scope, _id, role, _data, aria)
import ReactDOM as RDOM import ReactDOM as RDOM
import Thermite (PerformAction, Render, Spec, cotransform, createReactSpec, modifyState, simpleSpec) import Thermite (PerformAction, Render, Spec, cotransform, createReactSpec, modifyState, simpleSpec)
import Unsafe.Coerce (unsafeCoerce) import Unsafe.Coerce (unsafeCoerce)
...@@ -36,7 +36,7 @@ main :: forall e. Eff (dom:: DOM, console :: CONSOLE, ajax :: AJAX | e) Unit ...@@ -36,7 +36,7 @@ main :: forall e. Eff (dom:: DOM, console :: CONSOLE, ajax :: AJAX | e) Unit
main = do main = do
case createReactSpec spec tdata of case createReactSpec spec tdata of
{ spec, dispatcher } -> void $ do { spec, dispatcher } -> void $ do
document <- DOM.window >>= DOM.document document <- DOM.window >>= DOM.document
container <- unsafePartial (fromJust <$> DOM.querySelector (QuerySelector "#app") (DOM.htmlDocumentToParentNode document)) container <- unsafePartial (fromJust <$> DOM.querySelector (QuerySelector "#app") (DOM.htmlDocumentToParentNode document))
RDOM.render (R.createFactory (R.createClass spec) {}) container RDOM.render (R.createFactory (R.createClass spec) {}) container
...@@ -54,17 +54,16 @@ main = do ...@@ -54,17 +54,16 @@ main = do
-- TODO: When a pagination link is clicked, reload data. Right now it doesn't make sense to reload mock data. -- TODO: When a pagination link is clicked, reload data. Right now it doesn't make sense to reload mock data.
newtype Response = Response newtype Response = Response
{ cid :: Int { cid :: Int
, created :: String , created :: String
, favorite :: Boolean , favorite :: Boolean
, ngramCount :: Int , ngramCount :: Int
, hyperdata :: Hyperdata , hyperdata :: Hyperdata
} }
newtype Hyperdata = Hyperdata newtype Hyperdata = Hyperdata
{ { title :: String
title :: String , source :: String
, abstract :: String
} }
type State = CorpusTableData type State = CorpusTableData
...@@ -77,28 +76,28 @@ data Action ...@@ -77,28 +76,28 @@ data Action
instance decodeHyperdata :: DecodeJson Hyperdata where instance decodeHyperdata :: DecodeJson Hyperdata where
decodeJson json = do decodeJson json = do
obj <- decodeJson json obj <- decodeJson json
title <- obj .? "title" title <- obj .? "title"
abstract <- obj .? "abstract" source <- obj .? "source"
pure $ Hyperdata { title,abstract } pure $ Hyperdata { title,source }
instance decodeResponse :: DecodeJson Response where instance decodeResponse :: DecodeJson Response where
decodeJson json = do decodeJson json = do
obj <- decodeJson json obj <- decodeJson json
cid <- obj .? "id" cid <- obj .? "id"
created <- obj .? "created" created <- obj .? "created"
favorite <- obj .? "favorite" favorite <- obj .? "favorite"
ngramCount <- obj .? "ngramCount" ngramCount <- obj .? "ngramCount"
hyperdata <- obj .? "hyperdata" hyperdata <- obj .? "hyperdata"
pure $ Response { cid, created, favorite, ngramCount, hyperdata } pure $ Response { cid, created, favorite, ngramCount, hyperdata }
type Name = String type Name = String
type Open = Boolean type Open = Boolean
type URL = String type URL = String
type ID = Int type ID = Int
data NTree a = NLeaf a | NNode ID Open Name (Array (NTree a)) data NTree a = NLeaf a | NNode ID Open Name (Array (NTree a))
...@@ -112,56 +111,62 @@ toggleNode sid (NNode iid open name ary) = ...@@ -112,56 +111,62 @@ toggleNode sid (NNode iid open name ary) =
toggleNode sid a = a toggleNode sid a = a
spec :: Spec _ State _ Action spec :: Spec _ State _ Action
spec = simpleSpec performAction render spec = simpleSpec performAction render
where where
render :: Render State _ Action render :: Render State _ Action
render dispatch _ state@(TableData d) _ = render dispatch _ state@(TableData d) _ =
[ div [className "container"] [ div [className "container"]
[ [ div [className "row"]
div [className "jumbotron"] [ div [className "col-md-3"]
[ [ br' []
div [className "row"] , br' []
[ div [className "col-md-3"] , div [className "tree"] [toHtml dispatch d.tree]
[ br' [] ]
, br' [] , div [className "col-md-9"]
, div [className "tree"] [toHtml dispatch d.tree] [ nav []
] [ div [className "nav nav-tabs", _id "nav-tab",role "tablist"]
, div [className "col-md-9"] [
[ a [ className "nav-item nav-link active"
br' [] , _id "nav-home-tab"
, br' [] , _data {toggle : "tab"}
, p'' , href "#nav-home"
, h3 [] [text "Chart Title"] , role "tab"
, ex1 , aria {controls : "nav-home"}
, p'' , aria {selected:true}] [ text "Documents"]
, a [className "nav-item nav-link",_id "nav-profile-tab", _data {toggle : "tab"},href "#nav-profile",role "tab",aria {controls : "nav-profile"},aria {selected:true}] [ text "Sources"]
, div [] [b [] [text d.title]]
, div [] [ text "Search " ,a [className "nav-item nav-link",_id "nav-contact-tab", _data {toggle : "tab"},href "#nav-contact",role "tab",aria {controls : "nav-contact"},aria {selected:true}] [ text "Authors"]
, input [] [] ,a [className "nav-item nav-link",_id "nav-contact-tab", _data {toggle : "tab"},href "#nav-contact",role "tab",aria {controls : "nav-contact"},aria {selected:true}] [ text "Terms"]
] ,a [className "nav-item nav-link",_id "nav-contact-tab", _data {toggle : "tab"},href "#nav-contact",role "tab",aria {controls : "nav-contact"},aria {selected:true}] [ text "(+)"]
, sizeDD d.pageSize dispatch
, br' []
, br' []
, textDescription d.currentPage d.pageSize d.totalRecords
, br' []
, br' []
, pagination dispatch d.totalPages d.currentPage
, br' []
, br' []
, table []
[thead [] [tr []
[ td [] [ b' [text "Date"]]
, td [] [ b' [text "Title"]]
, td [] [ b' [text "Source"]]
, td [] [ b' [text "Fav"]]
, td [] [ b' [text "Delete"]]
]]
, tbody [] $ map showRow d.rows
] ]
] ]
, br' []
, p''
, h3 [] [text "Chart Title"]
, histogram
, p''
, br' []
, div [] [ b [] [text d.title]
, text " Filter "
, input [] []
, sizeDD d.pageSize dispatch
, textDescription d.currentPage d.pageSize d.totalRecords
, pagination dispatch d.totalPages d.currentPage
]
, table [ className "table"]
[thead [ className "thead-dark"]
[tr [] [ th [scope "col"] [ b' [text "Date"] ]
, th [scope "col"] [ b' [text "Title"] ]
, th [scope "col"] [ b' [text "Source"] ]
, th [scope "col"] [ b' [text "Favorite"]]
, th [scope "col"] [ b' [text "Delete"] ]
]
]
, tbody [] $ map showRow d.rows
]
] ]
] ]
] ]
...@@ -171,19 +176,13 @@ spec = simpleSpec performAction render ...@@ -171,19 +176,13 @@ spec = simpleSpec performAction render
------------------------------------------------------------------------ ------------------------------------------------------------------------
-- Realistic Tree for the UI -- Realistic Tree for the UI
urlFacetDoc :: String
urlFacetDoc = "http://localhost:8009/index.html#/docView"
myCorpus :: Int -> String -> NTree (Tuple String String) myCorpus :: Int -> String -> NTree (Tuple String String)
myCorpus n name = NNode n false name myCorpus n name = NNode n false name
[ NLeaf (Tuple "Facets" urlFacetDoc) [ NLeaf (Tuple "Facets" "#/docView")
, NLeaf (Tuple "Graph" urlFacetDoc) , NLeaf (Tuple "Graph" "#/docView")
, NLeaf (Tuple "Dashboard" urlFacetDoc) , NLeaf (Tuple "Dashboard" "#/userPage")
] ]
urlFacetAuth :: String
urlFacetAuth = urlFacetDoc
exampleTree :: NTree (Tuple String String) exampleTree :: NTree (Tuple String String)
exampleTree = exampleTree =
NNode 1 true "My gargantext" NNode 1 true "My gargantext"
...@@ -195,26 +194,29 @@ exampleTree = ...@@ -195,26 +194,29 @@ exampleTree =
] ]
] ]
------------------------------------------------------------------------ ------------------------------------------------------------------------
-- TODO -- TODO
-- alignment to the right -- alignment to the right
nodeOptionsCorp = [ i [className "fab fa-whmcs" ] []] nodeOptionsCorp activated = case activated of
true -> [ i [className "fab fa-whmcs" ] []]
false -> []
-- TODO -- TODO
-- alignment to the right -- alignment to the right
-- on hover make other options available: -- on hover make other options available:
nodeOptionsView = [ i [className "fas fa-sync-alt" ] [] nodeOptionsView activated = case activated of
, i [className "fas fa-upload" ] [] true -> [ i [className "fas fa-sync-alt" ] []
, i [className "fas fa-share-alt"] [] , i [className "fas fa-upload" ] []
] , i [className "fas fa-share-alt"] []
]
false -> []
toHtml :: _ -> FTree -> ReactElement toHtml :: _ -> FTree -> ReactElement
toHtml d (NLeaf (Tuple name link)) = toHtml d (NLeaf (Tuple name link)) =
li [] li []
[ a [ href link] [ a [ href link]
( [ text (name <> " ") ( [ text (name <> " ")
] <> nodeOptionsView ] <> nodeOptionsView false
) )
] ]
toHtml d (NNode id open name ary) = toHtml d (NNode id open name ary) =
...@@ -222,7 +224,7 @@ toHtml d (NNode id open name ary) = ...@@ -222,7 +224,7 @@ toHtml d (NNode id open name ary) =
[ li [] $ [ li [] $
( [ a [onClick $ (\e-> d $ ToggleFolder id)] [i [fldr open] []] ( [ a [onClick $ (\e-> d $ ToggleFolder id)] [i [fldr open] []]
, text $ " " <> name <> " " , text $ " " <> name <> " "
] <> nodeOptionsCorp <> ] <> nodeOptionsCorp false <>
if open then if open then
map (toHtml d) ary map (toHtml d) ary
else [] else []
...@@ -246,11 +248,11 @@ performAction LoadData _ _ = void do ...@@ -246,11 +248,11 @@ performAction LoadData _ _ = void do
where where
res2corpus (Response res) = res2corpus (Response res) =
Corpus { _id : res.cid Corpus { _id : res.cid
, url : "" , url : ""
, date : res.created , date : res.created
, title : (\(Hyperdata r) -> r.title) res.hyperdata , title : (\(Hyperdata r) -> r.title) res.hyperdata
, source : (\(Hyperdata r) -> r.abstract)res.hyperdata , source : (\(Hyperdata r) -> r.source)res.hyperdata
, fav : res.favorite , fav : res.favorite
} }
...@@ -258,7 +260,11 @@ performAction (ToggleFolder i) _ _ = void (cotransform (\(TableData td) -> Table ...@@ -258,7 +260,11 @@ performAction (ToggleFolder i) _ _ = void (cotransform (\(TableData td) -> Table
changePageSize :: PageSizes -> CorpusTableData -> CorpusTableData changePageSize :: PageSizes -> CorpusTableData -> CorpusTableData
changePageSize ps (TableData td) = TableData $ td { pageSize = ps, totalPages = td.totalRecords / pageSizes2Int ps, currentPage = 1} changePageSize ps (TableData td) =
TableData $ td { pageSize = ps
, totalPages = td.totalRecords / pageSizes2Int ps
, currentPage = 1
}
data PageSizes = PS10 | PS20 | PS50 | PS100 data PageSizes = PS10 | PS20 | PS50 | PS100
...@@ -332,7 +338,9 @@ pagination d tp cp ...@@ -332,7 +338,9 @@ pagination d tp cp
else else
span [] span []
[ text " " [ text " "
, a [href "javascript:void()", onClick (\e -> d $ ChangePage $ cp - 1)] [text "Previous"] , a [ href "javascript:void()"
, onClick (\e -> d $ ChangePage $ cp - 1)
] [text "Previous"]
, text " " , text " "
] ]
next = if cp == tp then next = if cp == tp then
...@@ -340,7 +348,9 @@ pagination d tp cp ...@@ -340,7 +348,9 @@ pagination d tp cp
else else
span [] span []
[ text " " [ text " "
, a [href "javascript:void()", onClick (\e -> d $ ChangePage $ cp + 1)] [text "Next"] , a [ href "javascript:void()"
, onClick (\e -> d $ ChangePage $ cp + 1)
] [text "Next"]
, text " " , text " "
] ]
first = if cp == 1 then first = if cp == 1 then
...@@ -348,7 +358,9 @@ pagination d tp cp ...@@ -348,7 +358,9 @@ pagination d tp cp
else else
span [] span []
[ text " " [ text " "
, a [href "javascript:void()", onClick (\e -> d $ ChangePage 1)] [text "1"] , a [ href "javascript:void()"
, onClick (\e -> d $ ChangePage 1)
] [text "1"]
, text " " , text " "
] ]
last = if cp == tp then last = if cp == tp then
...@@ -356,7 +368,9 @@ pagination d tp cp ...@@ -356,7 +368,9 @@ pagination d tp cp
else else
span [] span []
[ text " " [ text " "
, a [href "javascript:void()", onClick (\e -> d $ ChangePage tp)] [text $ show tp] , a [ href "javascript:void()"
, onClick (\e -> d $ ChangePage tp)
] [text $ show tp]
, text " " , text " "
] ]
ldots = if cp >= 5 then ldots = if cp >= 5 then
...@@ -374,7 +388,9 @@ fnmid :: _ -> Int -> ReactElement ...@@ -374,7 +388,9 @@ fnmid :: _ -> Int -> ReactElement
fnmid d i fnmid d i
= span [] = span []
[ text " " [ text " "
, a [href "javascript:void()", onClick (\e -> d $ ChangePage i)] [text $ show i] , a [ href "javascript:void()"
, onClick (\e -> d $ ChangePage i)
] [text $ show i]
, text " " , text " "
] ]
...@@ -387,23 +403,25 @@ greaterthan x y = x > y ...@@ -387,23 +403,25 @@ greaterthan x y = x > y
newtype TableData a newtype TableData a
= TableData = TableData
{ rows :: Array {row :: a, delete :: Boolean} { rows :: Array { row :: a
, totalPages :: Int , delete :: Boolean
, currentPage :: Int }
, pageSize :: PageSizes , totalPages :: Int
, currentPage :: Int
, pageSize :: PageSizes
, totalRecords :: Int , totalRecords :: Int
, title :: String , title :: String
, tree :: FTree , tree :: FTree
} }
newtype Corpus newtype Corpus
= Corpus = Corpus
{ _id :: Int { _id :: Int
, url :: String , url :: String
, date :: String , date :: String
, title :: String , title :: String
, source :: String , source :: String
, fav :: Boolean , fav :: Boolean
} }
type CorpusTableData = TableData Corpus type CorpusTableData = TableData Corpus
...@@ -422,24 +440,24 @@ sdata = data' sampleData ...@@ -422,24 +440,24 @@ sdata = data' sampleData
tdata :: CorpusTableData tdata :: CorpusTableData
tdata = TableData tdata = TableData
{ rows : sdata { rows : sdata
, totalPages : 10 , totalPages : 10
, currentPage : 1 , currentPage : 1
, pageSize : PS10 , pageSize : PS10
, totalRecords : 100 , totalRecords : 100
, title : "Publications by title" , title : "Documents"
, tree : exampleTree , tree : exampleTree
} }
tdata' :: _ -> CorpusTableData tdata' :: _ -> CorpusTableData
tdata' d = TableData tdata' d = TableData
{ rows : d { rows : d
, totalPages : 10 , totalPages : 10
, currentPage : 1 , currentPage : 1
, pageSize : PS10 , pageSize : PS10
, totalRecords : 100 , totalRecords : 100
, title : "Publications by title" , title : "Documents"
, tree : exampleTree , tree : exampleTree
} }
...@@ -449,10 +467,13 @@ showRow {row : (Corpus c), delete} = ...@@ -449,10 +467,13 @@ showRow {row : (Corpus c), delete} =
[ td [] [text c.date] [ td [] [text c.date]
, td [] [text c.title] , td [] [text c.title]
, td [] [text c.source] , td [] [text c.source]
, td [] [text $ show c.fav] , td [] [div [className $ fa <> "fa-star"][]]
, td [] [ input [ _type "checkbox"] []] , td [] [input [ _type "checkbox"] []]
] ]
where
fa = case c.fav of
true -> "fas "
false -> "far "
...@@ -477,3 +498,6 @@ loadData = do ...@@ -477,3 +498,6 @@ loadData = do
--liftEff $ log $ "GET /api response: " <> show a.response --liftEff $ log $ "GET /api response: " <> show a.response
let res = decodeJson a.response let res = decodeJson a.response
pure res pure res
...@@ -6,7 +6,8 @@ import DOM (DOM) ...@@ -6,7 +6,8 @@ import DOM (DOM)
import Network.HTTP.Affjax (AJAX) import Network.HTTP.Affjax (AJAX)
import Prelude hiding (div) import Prelude hiding (div)
import React.DOM (a, button, div, footer, h1, h3, hr, i, img, li, p, span, text, ul) import React.DOM (a, button, div, footer, h1, h3, hr, i, img, li, p, span, text, ul)
import React.DOM.Props (_data, _id, aria, className, href, onClick, role, src, style, tabIndex, target, title) import React.DOM.Props (Props, _data, _id, aria, className, href, onClick, role, src, style, tabIndex, target, title)
import React (ReactElement)
import Routing.Hash.Aff (setHash) import Routing.Hash.Aff (setHash)
import Thermite (PerformAction, Render, Spec, simpleSpec) import Thermite (PerformAction, Render, Spec, simpleSpec)
import Thermite as T import Thermite as T
...@@ -49,162 +50,65 @@ performAction Login _ _ = void do ...@@ -49,162 +50,65 @@ performAction Login _ _ = void do
performAction SignUp _ _ = void do performAction SignUp _ _ = void do
T.modifyState \state -> state T.modifyState \state -> state
jumboTitle :: Boolean -> ReactElement
jumboTitle b = div jumbo
loginSpec :: forall props eff . Spec (console::CONSOLE, ajax::AJAX, dom::DOM | eff) State props Action [ div [className "row" ]
loginSpec = simpleSpec performAction render [ div [className "col-md-8 content"]
[ h1 [] [ text "Gargantext"]
, p [] [ text "search map share" ]
, p [] [ a [ className "btn btn-success btn-lg spacing-class"
, href "https://iscpif.fr/gargantext/your-first-map/"
, target "blank"
, title "Your first map in less than 5 minutes"
]
[ span [ aria {hidden : true}
, className "glyphicon glyphicon-hand-right"
] []
, text " Documentation"
]
]
]
, div [ className "col-md-2 content"]
[p [ className "right" ]
[ div [_id "logo-designed" ]
[ img [ src "images/logo.png", title "Project hosted by CNRS (France, Europa, Solar System)" ]
[]
]
]
]
]
]
where
jumbo = case b of
true -> [className "jumbotron"]
false -> []
imageEnter :: Props -> ReactElement
imageEnter action = div [className "row"]
[ div [className "col-md-offset-5 col-md-6 content"]
[ img [ src "images/Gargantextuel-212x300.jpg"
, _id "funnyimg"
, title "Click and test by yourself"
, action
]
[]
]
]
home :: forall props eff . Spec (console::CONSOLE, ajax::AJAX, dom::DOM | eff) State props Action
home = simpleSpec performAction render
where where
render :: Render State props Action render :: Render State props Action
render dispatch _ state _ = render dispatch _ state _ =
[ [ div [ className "container" ] [ jumboTitle true ]
-- div [ _id "dafixedtop", className "navbar navbar-inverse navbar-fixed-top", role "navigation"] , div [ className "container" ] [ imageEnter (onClick \_ -> dispatch $ Enter)]
-- [ div [className "container"] , div [ className "container" ] [ blocksRandomText ]
-- [ ]
-- div [ className "navbar-inner" ]
-- [ a [ className "navbar-brand logoSmall", href "/" ]
-- [ img [ src "images/logoSmall.png", title "Back to home." ]
-- []
-- ]
-- ]
-- , div [className "navbar-collapse collapse"]
-- [
-- ul [className "nav navbar-nav"]
-- [
-- ul [className "nav navbar-nav pull-left"] [
-- li [className "dropdown"]
-- [
-- a [
-- className "dropdown-toggle navbar-text", _data {toggle: "dropdown"}, href "#", role "button", title "Informations about Gargantext" ]
-- [ span [ aria {hidden : true}, className "glyphicon glyphicon-info-sign" ]
-- []
-- , text "Info"
-- , i [ className "caret" ]
-- []
-- ]
-- , ul [className "dropdown-menu"]
-- [ li []
-- [ a [tabIndex (-1), target "blank", title "Documentation and tutorials", href "https://iscpif.fr/gargantext/your-first-map/"]
-- [text "Documentation"]
-- ]
-- , li [className "divider"] []
-- , li []
-- [
-- a [ tabIndex (-1), target "blank", title "About", href "/about/", title "More informations about the project, its sponsors and its authors"]
-- [ text "About"]
-- ]
-- ]
-- ]
-- ]
-- ]
-- , ul [className "nav navbar-nav pull-right"]
-- [
-- li [className "dropdown"]
-- [
-- a [ className "dropdown-toggle navbar-text", _data {toggle : "dropdown"}, href "#", role "button", title "That is your username" ]
-- [ i [ className "" ]
-- []
-- , span [ aria {hidden : true}, className "glyphicon glyphicon-user", style {color:"white"} ]
-- []
-- , i [ className "caret" ]
-- []
-- ]
-- , ul [className "dropdown-menu"]
-- [
-- li []
-- [ a [tabIndex (-1), target "blank", title "Send us a message (bug, thanks, congrats...)", href "https://www.iscpif.fr/gargantext/feedback-and-bug-reports/"]
-- [
-- span [ className "glyphicon glyphicon-bullhorn" ,aria {hidden : true}] []
-- , text "Report Feedback"
-- ]
-- ]
-- , li [ className"divider"]
-- []
-- , li []
-- [ a [tabIndex (-1), href "/auth/login" ]
-- [ span [className "glyphicon glyphicon-log-in",aria {hidden : true}] []
-- , text "login"
-- ]
-- ]
-- ]
-- ]
-- ]
-- ]
-- ]
-- ]
div [className "container"]
[
div [className "jumbotron"]
[
div [className "row"]
[
div [className "col-md-8 content"]
[
h1 []
[ text "Gargantext" ]
, p []
[ text "Collaborative knowledge mapping experience" ]
-- TODO : put the login in top right page [#54]
, p []
[
-- a [ className "btn btn-primary btn-lg spacing-class ", onClick \_ -> dispatch $ Submit , title "Click and test by yourself" ]
-- [ span [ className "glyphicon glyphicon-hand-right" ]
-- []
-- , text " Login"
-- ]
---- TODO: login / sign up will not be mandatory any more (mandatory to save/share your research only)
---- TODO: ask for login or account creation after 5 mn when user is not logged and has made one search at least
-- , a [ className "btn btn-warning btn-lg spacing-class", href "https://iscpif.fr/services/applyforourservices/", target "blank", title "Fill the form to sign up" ]
-- [ span [ aria {hidden : true}, className "glyphicon glyphicon-hand-right" ]
-- []
-- , text "Sign Up"
-- ]
a [ className "btn btn-success btn-lg spacing-class", href "https://iscpif.fr/gargantext/your-first-map/", target "blank", title "Fill the form to sign up" ]
[ span [ aria {hidden : true}, className "glyphicon glyphicon-hand-right" ]
[]
, text " Get's started"
]
]
, span [ aria {hidden : true}, className "glyphicon glyphicon-warning-sign" ]
[]
, i []
[ text "Some features may not work without a javascript optimized browser (Chromium for instance). " ]
]
, div [className "col-md-2 content"]
[
p [ className "right" ]
[ div [_id "logo-designed" ]
[ img [ src "images/logo.png", title "Logo designed by dacha and anoe" ]
[]
]
]
]
]
]
]
, div [className "container"]
[ div [className "row"]
[ div [className "col-md-offset-5 col-md-6 content"]
[ img [ src "images/Gargantextuel-212x300.jpg"
, title "Gargantextuel drawn by Cecile Meadel"
, _id "funnyimg"
, onClick \_ -> dispatch $ Enter , title "Click and test by yourself"
] []
]
]
]
, div [ className "container" ] blocksRandomText :: ReactElement
[ div [ className "row" ] blocksRandomText = div [ className "row" ]
[ div [ className "col-md-4 content" ] [ div [ className "col-md-4 content" ]
[ h3 [] [ h3 []
[ a [ href "#", title "Random sentences in Gargantua's Books chapters, historically true" ] [ a [ href "#", title "Random sentences in Gargantua's Books chapters, historically true" ]
...@@ -245,28 +149,5 @@ loginSpec = simpleSpec performAction render ...@@ -245,28 +149,5 @@ loginSpec = simpleSpec performAction render
] ]
] ]
] ]
]
, div [className "container"]
[
hr [] []
, footer []
[ p []
[ text "Gargantext "
, span [className "glyphicon glyphicon-registration-mark" ]
[]
, text ", version 4.0"
, a [ href "http://www.cnrs.fr", target "blank", title "Institution that enables this project." ]
[ text ", Copyrights "
, span [ className "glyphicon glyphicon-copyright-mark" ]
[]
, text " CNRS 2017-Present"
]
, a [ href "http://gitlab.iscpif.fr/humanities/gargantext/blob/stable/LICENSE", target "blank", title "Legal instructions of the project." ]
[ text ", Licences aGPLV3 and CECILL variant Affero compliant" ]
, text "."
]
]
]
]
...@@ -26,6 +26,9 @@ import Thermite (PerformAction, Render, Spec, modifyState, simpleSpec) ...@@ -26,6 +26,9 @@ import Thermite (PerformAction, Render, Spec, modifyState, simpleSpec)
import Unsafe.Coerce (unsafeCoerce) import Unsafe.Coerce (unsafeCoerce)
-- TODO: ask for login (modal) or account creation after 15 mn when user is not logged and has made one search at least
newtype State = State newtype State = State
{ username :: String { username :: String
, password :: String , password :: String
...@@ -49,7 +52,11 @@ data Action ...@@ -49,7 +52,11 @@ data Action
| SetPassword String | SetPassword String
performAction :: forall eff props. PerformAction (console :: CONSOLE, ajax :: AJAX,dom::DOM | eff) State props Action performAction :: forall eff props. PerformAction ( console :: CONSOLE
, ajax :: AJAX
, dom :: DOM
| eff
) State props Action
performAction NoOp _ _ = void do performAction NoOp _ _ = void do
modifyState id modifyState id
...@@ -148,18 +155,16 @@ unsafeEventValue e = (unsafeCoerce e).target.value ...@@ -148,18 +155,16 @@ unsafeEventValue e = (unsafeCoerce e).target.value
getDeviseID :: forall eff. Eff (dom :: DOM | eff) (Maybe String) getDeviseID :: forall eff. Eff (dom :: DOM | eff) (Maybe String)
getDeviseID = do getDeviseID = do
w <- window w <- window
ls <- localStorage w ls <- localStorage w
i <- getItem "token" ls getItem "token" ls
pure $ i
setToken :: forall e . String -> Eff (dom :: DOM | e) Unit setToken :: forall e . String -> Eff (dom :: DOM | e) Unit
setToken s = do setToken s = do
w <- window w <- window
ls <- localStorage w ls <- localStorage w
liftEff $ setItem "token" s ls setItem "token" s ls
pure unit
...@@ -169,7 +174,7 @@ newtype LoginRes = LoginRes ...@@ -169,7 +174,7 @@ newtype LoginRes = LoginRes
newtype LoginReq = LoginReq newtype LoginReq = LoginReq
{ username :: String { username :: String
, password :: String , password :: String
} }
...@@ -207,7 +212,7 @@ loginReq encodeData = ...@@ -207,7 +212,7 @@ loginReq encodeData =
instance decodeLoginRes :: DecodeJson LoginRes where instance decodeLoginRes :: DecodeJson LoginRes where
decodeJson json = do decodeJson json = do
obj <- decodeJson json obj <- decodeJson json
token <- obj .? "token" token <- obj .? "token"
pure $ LoginRes { token} pure $ LoginRes { token}
......
...@@ -3,25 +3,21 @@ module Navigation where ...@@ -3,25 +3,21 @@ module Navigation where
import DOM import DOM
import AddCorpusview as AC import AddCorpusview as AC
import Control.Monad.Aff.Class (liftAff)
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Class (liftEff)
import Control.Monad.Eff.Console (CONSOLE) import Control.Monad.Eff.Console (CONSOLE)
import Data.Either (Either(..)) import Data.Either (Either(..))
import Data.Foldable (fold) import Data.Foldable (fold)
import Data.Lens (Lens', Prism', lens, over, prism) import Data.Lens (Lens', Prism', lens, over, prism)
import Data.Maybe (Maybe, Maybe(Nothing, Just)) import Data.Maybe (Maybe(Nothing, Just))
import Landing as L import Landing as L
import Login as LN import Login as LN
import Network.HTTP.Affjax (AJAX) import Network.HTTP.Affjax (AJAX)
import PageRouter (Routes(..)) import PageRouter (Routes(..))
import Prelude hiding (div) import Prelude (class Applicative, class Bind, Unit, bind, id, map, negate, pure, unit, void, ($), (<>))
import React (ReactElement) import React (ReactElement)
import React.DOM (a, div, i, img, li, span, text, ul, map') import React.DOM (a, div, img, li, span, text, ul, input, button, footer, p, hr, form)
import React.DOM.Props (_data, _id, aria, className, href, role, src, style, tabIndex, target, title, onClick) import React.DOM.Props (_data, _id, aria, className, href, name, placeholder, _type, role, src, style, tabIndex, target, title)
import Thermite (PerformAction, Render, Spec, _render, defaultRender, focus, modifyState, simpleSpec, withState) import Thermite (PerformAction, Render, Spec, _render, defaultRender, focus, modifyState, simpleSpec, withState)
import DocView as DV import DocView as DV
import Landing as Landing
import SearchForm as S import SearchForm as S
import UserPage as UP import UserPage as UP
...@@ -39,7 +35,7 @@ type AppState = ...@@ -39,7 +35,7 @@ type AppState =
initAppState :: AppState initAppState :: AppState
initAppState = initAppState =
{ currentRoute : Just Home { currentRoute : Just Home
, landingState : L.initialState , landingState : L.initialState
, loginState : LN.initialState , loginState : LN.initialState
, addCorpusState : AC.initialState , addCorpusState : AC.initialState
...@@ -48,7 +44,6 @@ initAppState = ...@@ -48,7 +44,6 @@ initAppState =
, userPage : UP.initialState , userPage : UP.initialState
} }
data Action data Action
= Initialize = Initialize
| LandingA L.Action | LandingA L.Action
...@@ -60,7 +55,9 @@ data Action ...@@ -60,7 +55,9 @@ data Action
| UserPageA UP.Action | UserPageA UP.Action
performAction :: forall eff props. PerformAction (dom :: DOM |eff) AppState props Action performAction :: forall eff props. PerformAction ( dom :: DOM
| eff
) AppState props Action
performAction (SetRoute route) _ _ = void do performAction (SetRoute route) _ _ = void do
modifyState $ _ {currentRoute = pure route} modifyState $ _ {currentRoute = pure route}
...@@ -68,9 +65,8 @@ performAction _ _ _ = void do ...@@ -68,9 +65,8 @@ performAction _ _ _ = void do
modifyState id modifyState id
---- Lens and Prism ---- Lens and Prism
_landingState:: Lens' AppState L.State _landingState :: Lens' AppState L.State
_landingState = lens (\s -> s.landingState) (\s ss -> s{landingState = ss}) _landingState = lens (\s -> s.landingState) (\s ss -> s{landingState = ss})
...@@ -81,8 +77,7 @@ _landingAction = prism LandingA \action -> ...@@ -81,8 +77,7 @@ _landingAction = prism LandingA \action ->
_-> Left action _-> Left action
_loginState :: Lens' AppState LN.State
_loginState:: Lens' AppState LN.State
_loginState = lens (\s -> s.loginState) (\s ss -> s{loginState = ss}) _loginState = lens (\s -> s.loginState) (\s ss -> s{loginState = ss})
...@@ -93,7 +88,7 @@ _loginAction = prism LoginA \action -> ...@@ -93,7 +88,7 @@ _loginAction = prism LoginA \action ->
_-> Left action _-> Left action
_addCorpusState:: Lens' AppState AC.State _addCorpusState :: Lens' AppState AC.State
_addCorpusState = lens (\s -> s.addCorpusState) (\s ss -> s{addCorpusState = ss}) _addCorpusState = lens (\s -> s.addCorpusState) (\s ss -> s{addCorpusState = ss})
...@@ -104,8 +99,7 @@ _addCorpusAction = prism AddCorpusA \action -> ...@@ -104,8 +99,7 @@ _addCorpusAction = prism AddCorpusA \action ->
_-> Left action _-> Left action
_docViewState :: Lens' AppState DV.State
_docViewState:: Lens' AppState DV.State
_docViewState = lens (\s -> s.docViewState) (\s ss -> s{docViewState = ss}) _docViewState = lens (\s -> s.docViewState) (\s ss -> s{docViewState = ss})
...@@ -116,7 +110,7 @@ _docViewAction = prism DocViewA \action -> ...@@ -116,7 +110,7 @@ _docViewAction = prism DocViewA \action ->
_-> Left action _-> Left action
_searchState:: Lens' AppState S.State _searchState :: Lens' AppState S.State
_searchState = lens (\s -> s.searchState) (\s ss -> s{searchState = ss}) _searchState = lens (\s -> s.searchState) (\s ss -> s{searchState = ss})
...@@ -127,7 +121,7 @@ _searchAction = prism SearchA \action -> ...@@ -127,7 +121,7 @@ _searchAction = prism SearchA \action ->
_-> Left action _-> Left action
_userPageState:: Lens' AppState UP.State _userPageState :: Lens' AppState UP.State
_userPageState = lens (\s -> s.userPage) (\s ss -> s{userPage = ss}) _userPageState = lens (\s -> s.userPage) (\s ss -> s{userPage = ss})
...@@ -147,9 +141,13 @@ pagesComponent s = ...@@ -147,9 +141,13 @@ pagesComponent s =
Nothing -> Nothing ->
selectSpec Home selectSpec Home
where where
selectSpec :: Routes -> Spec (ajax :: AJAX, console :: CONSOLE, dom :: DOM | eff) AppState props Action selectSpec :: Routes -> Spec ( ajax :: AJAX
, console :: CONSOLE
, dom :: DOM
| eff
) AppState props Action
selectSpec Login = focus _loginState _loginAction LN.renderSpec selectSpec Login = focus _loginState _loginAction LN.renderSpec
selectSpec Home = wrap $ focus _landingState _landingAction L.loginSpec selectSpec Home = wrap $ focus _landingState _landingAction L.home
selectSpec AddCorpus = wrap $ focus _addCorpusState _addCorpusAction AC.addcorpusviewSpec selectSpec AddCorpus = wrap $ focus _addCorpusState _addCorpusAction AC.addcorpusviewSpec
selectSpec DocView = wrap $ focus _docViewState _docViewAction DV.spec selectSpec DocView = wrap $ focus _docViewState _docViewAction DV.spec
selectSpec SearchView = wrap $ focus _searchState _searchAction S.searchSpec selectSpec SearchView = wrap $ focus _searchState _searchAction S.searchSpec
...@@ -158,20 +156,117 @@ pagesComponent s = ...@@ -158,20 +156,117 @@ pagesComponent s =
routingSpec :: forall props eff. Spec (dom :: DOM |eff) AppState props Action routingSpec :: forall props eff. Spec (dom :: DOM |eff) AppState props Action
routingSpec = simpleSpec performAction defaultRender routingSpec = simpleSpec performAction defaultRender
wrap :: forall eff props. Spec (E eff) AppState props Action -> Spec (E eff) AppState props Action wrap :: forall eff props. Spec (E eff) AppState props Action -> Spec (E eff) AppState props Action
wrap spec = wrap spec =
fold fold
[ sidebarnavSpec [ sidebarnavSpec
-- TODO Add Tree to the template
--, exampleTree'
, innerContainer $ spec , innerContainer $ spec
, footerLegalInfo
] ]
where where
innerContainer :: Spec (E eff) AppState props Action -> Spec (E eff) AppState props Action innerContainer :: Spec (E eff) AppState props Action -> Spec (E eff) AppState props Action
innerContainer = over _render \render d p s c -> innerContainer = over _render \render d p s c ->
[ div [_id "page-wrapper"] [ div [_id "page-wrapper"]
[ [
div[className "container-fluid"] (render d p s c) div [className "container-fluid"] (render d p s c)
] ]
] ]
-- TODO Add Tree to the template
-- exampleTree' :: forall props eff. Spec (dom :: DOM |eff) AppState props Action
-- exampleTree' = simpleSpec performAction render
-- where
-- render :: Render AppState props Action
-- render dispatch _ state _ = DV.toHtml dispatch DV.exampleTree
sidebarnavSpec :: forall props eff. Spec (dom :: DOM |eff) AppState props Action
sidebarnavSpec = simpleSpec performAction render
where
render :: Render AppState props Action
render dispatch _ state _ =
[ div [ _id "dafixedtop"
, className "navbar navbar-inverse navbar-fixed-top"
, role "navigation"
] [ div [className "container"]
[ div [ className "navbar-inner" ]
[ divLogo
, div [ className "collapse navbar-collapse"]
[ divDropdownLeft
, ul [className "nav navbar-nav"][text " XXXXXXXXXXXXXXXXXXX "]
, divSearchBar
, divDropdownRight
]
]
]
]
]
divLogo :: ReactElement
divLogo = a [ className "navbar-brand logoSmall"
, href "/index.html"
] [ img [ src "images/logoSmall.png"
, title "Back to home."
] []
]
divDropdownLeft :: ReactElement
divDropdownLeft = ul [className "nav navbar-nav"]
[ ul [className "nav navbar-nav pull-left"]
[ li [className "dropdown"]
[ a [ className "dropdown-toggle navbar-text"
, _data {toggle: "dropdown"}
, href "#", role "button"
, title "About Gargantext"
][ span [ aria {hidden : true}
, className "glyphicon glyphicon-info-sign"
] []
, text " Info"
]
, ul [className "dropdown-menu"]
(( map liNav [ LiNav { title : "Quick start, tutorials and methodology"
, href : "https://iscpif.fr/gargantext/your-first-map/"
, icon : "fas fa-book"
, text : "Documentation"
}
, LiNav { title : "Report bug here"
, href : "https://www.iscpif.fr/gargantext/feedback-and-bug-reports/"
, icon : "glyphicon glyphicon-bullhorn"
, text : "Feedback"
}
]
)
<> [li [className "divider"] []] <>
(map liNav [ LiNav { title : "Interactive chat"
, href : "https://chat.iscpif.fr/channel/gargantext"
, icon : "fab fa-rocketchat"
, text : "Chat"
}
, LiNav { title : "Asynchronous discussions"
, href : "https://discourse.iscpif.fr/c/gargantext"
, icon : "fab fa-discourse"
, text : "Forum"
}
]
)
<> [li [className "divider"] []] <>
[ liNav (LiNav { title : "More about us (you)"
, href : "http://iscpif.fr"
, icon : "fas fa-question-circle"
, text : "About"
}
)
]
)
]
]
]
data LiNav = LiNav { title :: String data LiNav = LiNav { title :: String
...@@ -190,102 +285,30 @@ liNav (LiNav { title:tit ...@@ -190,102 +285,30 @@ liNav (LiNav { title:tit
, target "blank" , target "blank"
, title tit , title tit
, href h , href h
] ] [ span [ className i ] []
, text $ " " <> txt
[ span [ className i ] [] ]
, text $ " " <> txt
]
] ]
divLogo :: ReactElement
divLogo = div [ className "navbar-inner" ]
[ a [ className "navbar-brand logoSmall"
, href "/index.html"
]
[ img [ src "images/logoSmall.png"
, title "Back to home." ]
[]
]
]
--divDropdownLeft :: ReactElement
--divDropdownLeft = undefined
sidebarnavSpec :: forall props eff. Spec (dom :: DOM |eff) AppState props Action -- TODO put the search form in the center of the navBar
sidebarnavSpec = simpleSpec performAction render divSearchBar :: ReactElement
where divSearchBar = ul [ className "nav navbar-nav"]
render :: Render AppState props Action [ div [className "navbar-form"]
render dispatch _ state _ = [ input [ className "search-query"
[ , placeholder "Query, URL or FILE (works with Firefox or Chromium browsers)"
div [ _id "dafixedtop" , _type "text"
, className "navbar navbar-inverse navbar-fixed-top" , style { height: "35px"
, role "navigation" , width : "450px"
] -- , color: "white"
-- , background : "#A1C2D8"
[ div [className "container"] }
[ divLogo ] []
-- divDropdownLeft -- TODO add button in navbar (and "enter" execution)
--------------------------------------------------------------------------- -- , div [] [button [][]]
-- here is divDropDowLeft-------------------------------------------------- ]
-- FIXME : divDropDownLeft and divDropDownRight seems to be intricated in dropdown? ]
---------------------------------------------------------------------------
, div [className "navbar-collapse collapse"]
[ ul [className "nav navbar-nav"]
[ ul [className "nav navbar-nav pull-left"]
[ li [className "dropdown"]
[ a [ className "dropdown-toggle navbar-text"
, _data {toggle: "dropdown"}
, href "#", role "button"
, title "Informations about Gargantext"
]
[ span [ aria {hidden : true}
, className "glyphicon glyphicon-info-sign"
] []
, text " Info"
]
, ul [className "dropdown-menu"]
(( map liNav [ LiNav { title : "Documentation and tutorials"
, href : "https://iscpif.fr/gargantext/your-first-map/"
, icon : "fas fa-book"
, text : "Documentation"
}
, LiNav { title : "Report bug here"
, href : "https://www.iscpif.fr/gargantext/feedback-and-bug-reports/"
, icon : "glyphicon glyphicon-bullhorn"
, text : "Feedback"
}
, LiNav { title : "Interactive chat"
, href : "https://chat.iscpif.fr/channel/gargantext"
, icon : "fab fa-rocketchat"
, text : "Chat"
}
, LiNav { title : "Asynchronous discussions"
, href : "https://discourse.iscpif.fr/c/gargantext"
, icon : "fab fa-discourse"
, text : "Forum"
}
]
)
<> [li [className "divider"] []] <>
[ liNav (LiNav { title : "About"
, href : "http://iscpif.fr"
, icon : "fas fa-question-circle"
, text : "About"
}
)
]
)
]
]
]
---------------------------------------------------------------------------
, divDropdownRight
]
]
]
]
--divDropdownRight :: Render AppState props Action --divDropdownRight :: Render AppState props Action
divDropdownRight :: ReactElement divDropdownRight :: ReactElement
...@@ -298,6 +321,7 @@ divDropdownRight = ul [className "nav navbar-nav pull-right"] ...@@ -298,6 +321,7 @@ divDropdownRight = ul [className "nav navbar-nav pull-right"]
, className "glyphicon glyphicon-log-in" , className "glyphicon glyphicon-log-in"
, href "#/login" , href "#/login"
, style {color:"white"} , style {color:"white"}
, title "Log in and save your time"
-- TODO hover: bold -- TODO hover: bold
] ]
-- TODO if logged in -- TODO if logged in
...@@ -307,6 +331,36 @@ divDropdownRight = ul [className "nav navbar-nav pull-right"] ...@@ -307,6 +331,36 @@ divDropdownRight = ul [className "nav navbar-nav pull-right"]
] ]
] ]
footerLegalInfo :: forall props eff. Spec (dom :: DOM |eff) AppState props Action
footerLegalInfo = simpleSpec performAction render
where
render :: Render AppState props Action
render dispatch _ state _ = [div [ className "container" ] [ hr [] [], footerLegalInfo']]
where
footerLegalInfo' = footer [] [ p [] [ text "Gargantext "
, span [className "glyphicon glyphicon-registration-mark" ] []
, text ", version 4.0"
, a [ href "http://www.cnrs.fr"
, target "blank"
, title "Project hosted by CNRS."
]
[ text ", Copyrights "
, span [ className "glyphicon glyphicon-copyright-mark" ] []
, text " CNRS 2017-Present"
]
, a [ href "http://gitlab.iscpif.fr/humanities/gargantext/blob/stable/LICENSE"
, target "blank"
, title "Legal instructions of the project."
]
[ text ", Licences aGPLV3 and CECILL variant Affero compliant" ]
, text "."
]
]
layoutSpec :: forall eff props. Spec (E eff) AppState props Action layoutSpec :: forall eff props. Spec (E eff) AppState props Action
layoutSpec = layoutSpec =
fold fold
...@@ -319,11 +373,14 @@ layoutSpec = ...@@ -319,11 +373,14 @@ layoutSpec =
container = over _render \render d p s c -> container = over _render \render d p s c ->
(render d p s c) (render d p s c)
dispatchAction :: forall t115 t445 t447. Bind t445 => Applicative t445 => (Action -> t445 t447) -> t115 -> Routes -> t445 Unit dispatchAction :: forall t115 t445 t447.
Bind t445 => Applicative t445 =>
(Action -> t445 t447) -> t115 -> Routes -> t445 Unit
dispatchAction dispatcher _ Home = do dispatchAction dispatcher _ Home = do
_ <- dispatcher $ SetRoute $ Home _ <- dispatcher $ SetRoute $ Home
_ <- dispatcher $ LandingA $ L.NoOp _ <- dispatcher $ LandingA $ L.NoOp
pure unit pure unit
dispatchAction dispatcher _ Login = do dispatchAction dispatcher _ Login = do
_ <- dispatcher $ SetRoute $ Login _ <- dispatcher $ SetRoute $ Login
_ <- dispatcher $ LoginA $ LN.NoOp _ <- dispatcher $ LoginA $ LN.NoOp
...@@ -339,15 +396,16 @@ dispatchAction dispatcher _ DocView = do ...@@ -339,15 +396,16 @@ dispatchAction dispatcher _ DocView = do
_ <- dispatcher $ DocViewA $ DV.LoadData _ <- dispatcher $ DocViewA $ DV.LoadData
pure unit pure unit
dispatchAction dispatcher _ SearchView = do dispatchAction dispatcher _ SearchView = do
_ <- dispatcher $ SetRoute $ SearchView _ <- dispatcher $ SetRoute $ SearchView
_ <- dispatcher $ SearchA $ S.NoOp _ <- dispatcher $ SearchA $ S.NoOp
pure unit pure unit
dispatchAction dispatcher _ UserPage = do dispatchAction dispatcher _ UserPage = do
_ <- dispatcher $ SetRoute $ UserPage _ <- dispatcher $ SetRoute $ UserPage
_ <- dispatcher $ UserPageA $ UP.NoOp _ <- dispatcher $ UserPageA $ UP.NoOp
pure unit pure unit
...@@ -25,12 +25,12 @@ data Routes ...@@ -25,12 +25,12 @@ data Routes
instance showRoutes :: Show Routes where instance showRoutes :: Show Routes where
show Home = "Home" show Home = "Home"
show Login = "Login" show Login = "Login"
show AddCorpus = "AddCorpus" show AddCorpus = "AddCorpus"
show DocView = "DocView" show DocView = "DocView"
show SearchView = "SearchView" show SearchView = "SearchView"
show UserPage = "UserPage" show UserPage = "UserPage"
int :: Match Int int :: Match Int
int = floor <$> num int = floor <$> num
...@@ -45,20 +45,30 @@ routing = ...@@ -45,20 +45,30 @@ routing =
<|> addcorpusRoute <|> addcorpusRoute
<|> home <|> home
where where
userPageRoute = UserPage <$ route "userPage" userPageRoute = UserPage <$ route "userPage"
searchRoute = SearchView <$ route "search" searchRoute = SearchView <$ route "search"
docviewRoute = DocView <$ route "docView" docviewRoute = DocView <$ route "docView"
addcorpusRoute = AddCorpus <$ route "addCorpus" addcorpusRoute = AddCorpus <$ route "addCorpus"
loginRoute = Login <$ route "login" loginRoute = Login <$ route "login"
home = Home <$ lit "" home = Home <$ lit ""
route str = lit "" *> lit str route str = lit "" *> lit str
routeHandler :: forall e. (Maybe Routes -> Routes -> Eff ( dom :: DOM, console :: CONSOLE | e) Unit) -> Maybe Routes -> Routes -> Eff (dom :: DOM, console :: CONSOLE | e) Unit
routeHandler :: forall e. ( Maybe Routes -> Routes -> Eff
( dom :: DOM
, console :: CONSOLE
| e
) Unit
) -> Maybe Routes -> Routes -> Eff
( dom :: DOM
, console :: CONSOLE
| e
) Unit
routeHandler dispatchAction old new = do routeHandler dispatchAction old new = do
liftEff $ log $ "change route : " <> show new liftEff $ log $ "change route : " <> show new
w <- window w <- window
ls <- localStorage w ls <- localStorage w
token <- getItem "accessToken" ls token <- getItem "accessToken" ls
let tkn = token let tkn = token
liftEff $ log $ "JWToken : " <> show tkn liftEff $ log $ "JWToken : " <> show tkn
case tkn of case tkn of
......
...@@ -6,11 +6,12 @@ import Control.Monad.Cont.Trans (lift) ...@@ -6,11 +6,12 @@ import Control.Monad.Cont.Trans (lift)
import DOM (DOM) import DOM (DOM)
import Network.HTTP.Affjax (AJAX) import Network.HTTP.Affjax (AJAX)
import Prelude hiding (div) import Prelude hiding (div)
import React.DOM (br', button, div, h3, input, text) import React.DOM (br', button, div, h3, input, text, i, span, img)
import React.DOM.Props (_id, _type, className, name, onClick, onInput, placeholder, value) import React.DOM.Props (_id, _type, className, name, onClick, onInput, placeholder, value, aria, src, title)
import Routing.Hash.Aff (setHash) import Routing.Hash.Aff (setHash)
import Thermite (PerformAction, Render, Spec, modifyState, simpleSpec) import Thermite (PerformAction, Render, Spec, modifyState, simpleSpec)
import Unsafe.Coerce (unsafeCoerce) import Unsafe.Coerce (unsafeCoerce)
import Landing as L
type State = type State =
{ {
...@@ -47,44 +48,42 @@ performAction GO _ _ = void do ...@@ -47,44 +48,42 @@ performAction GO _ _ = void do
unsafeEventValue :: forall event. event -> String unsafeEventValue :: forall event. event -> String
unsafeEventValue e = (unsafeCoerce e).target.value unsafeEventValue e = (unsafeCoerce e).target.value
-- TODO: case loggedIn of True -> Just Tree ; False -> Nothing
-- TODO: put the search form in the center of the page searchSpec :: forall props eff . Spec ( console :: CONSOLE
searchSpec :: forall props eff . Spec (console::CONSOLE, ajax::AJAX, dom::DOM | eff) State props Action , ajax :: AJAX
, dom :: DOM
| eff
) State props Action
searchSpec = simpleSpec performAction render searchSpec = simpleSpec performAction render
where where
render :: Render State props Action render :: Render State props Action
render dispatch _ state _ = render dispatch _ state _ =
[ [ div [className "container"] [L.jumboTitle false]
div [className "container"] , div [className "container"]
[ [ div [className "jumbotron" ]
div [className "jumbotron"] [ div [className "row" ]
[ [ div [className "col-md-10" ]
div [className "row"]
[
div [className "col-md-10"]
[ br' []
, br' []
, div [className "form-group"]
[
input [className "form-control",
_id "id_password",
name "query",
placeholder "Enter Query",
_type "text",
value state.query,
onInput \e -> dispatch (SetQuery (unsafeEventValue e))
] []
, br'[]
]
]
, div [className "col-md-2"]
[ br' [] [ br' []
, br' [] , br' []
-- TODO put Gargantext logo as search button , div [ className "form-group"]
, button [onClick \_ -> dispatch GO] [text "GO"] [ input [ className "form-control"
] , _id "id_password"
] , name "query"
] , placeholder "Query, URL or FILE (works best with Firefox or Chromium browsers)"
, _type "text"
, value state.query
, onInput \e -> dispatch (SetQuery (unsafeEventValue e))
] []
, br'[]
]
]
, div [ className "col-md-2"]
[ br' []
, br' []
, button [onClick \_ -> dispatch GO] [text "GO"]
]
, br' []
]
]
]
] ]
]
...@@ -8,33 +8,40 @@ import React.DOM (a, div, h3, h5, h6, i, img, li, nav, small, span, table, tbody ...@@ -8,33 +8,40 @@ import React.DOM (a, div, h3, h5, h6, i, img, li, nav, small, span, table, tbody
import React.DOM.Props (_data, _id, aria, className, href, role, scope, src) import React.DOM.Props (_data, _id, aria, className, href, role, scope, src)
import Thermite (PerformAction, Render, Spec, modifyState, simpleSpec) import Thermite (PerformAction, Render, Spec, modifyState, simpleSpec)
import DocView as DV
type State = String type State = String
initialState :: State initialState :: State
initialState ="" initialState = ""
data Action data Action = NoOp
= NoOp
performAction :: forall eff props. PerformAction (console :: CONSOLE, ajax :: AJAX,dom::DOM | eff) State props Action performAction :: forall eff props. PerformAction ( console :: CONSOLE
, ajax :: AJAX
, dom :: DOM
| eff
) State props Action
performAction NoOp _ _ = void do performAction NoOp _ _ = void do
modifyState id modifyState id
userPageSpec :: forall props eff . Spec ( console :: CONSOLE
userPageSpec :: forall props eff . Spec (console::CONSOLE, ajax::AJAX, dom::DOM | eff) State props Action , ajax :: AJAX
, dom :: DOM
| eff
) State props Action
userPageSpec = simpleSpec performAction render userPageSpec = simpleSpec performAction render
where where
render :: Render State props Action render :: Render State props Action
render dispatch _ state _ = render dispatch _ state _ =
[ div [className "container-fluid"] [ -- TODO: div [className "tree"] [DV.toHtml dispatch d.tree]
div [className "container-fluid"]
[ div [className "row", _id "user-page-header"] [ div [className "row", _id "user-page-header"]
[ div [className "col-md-2"] [ div [className "col-md-2"]
[ h3 [] [text "UserName"] [ h3 [] [text "User Name"]
] ]
, div [className "col-md-8"] [] , div [className "col-md-8"] []
, div [className "col-md-2"] , div [className "col-md-2"]
...@@ -54,26 +61,21 @@ userPageSpec = simpleSpec performAction render ...@@ -54,26 +61,21 @@ userPageSpec = simpleSpec performAction render
ul [className "list-group"] ul [className "list-group"]
[ [
li [className "list-group-item justify-content-between"] li [className "list-group-item justify-content-between"]
[ span [] [text "fonction"] [ span [] [text "Fonction"]
, span [className "badge badge-default badge-pill"] [text "Ensignent checheur"] , span [className "badge badge-default badge-pill"] [text "Enseignant chercheur"]
] ]
, li [className "list-group-item justify-content-between"] , li [className "list-group-item justify-content-between"]
[ span [] [text "Entitte, service"] [ span [] [text "Entité, service"]
, span [className "badge badge-default badge-pill"] [text "Mines Saint - Etinene SPIN -PTSI"] , span [className "badge badge-default badge-pill"] [text "Mines Saint-Etienne SPIN -PTSI"]
] ]
, li [className "list-group-item justify-content-between"] , li [className "list-group-item justify-content-between"]
[ span [] [text "Telephone"] [ span [] [text "Téléphone"]
, span [className "badge badge-default badge-pill"] [text "04 77 42 0070"] , span [className "badge badge-default badge-pill"] [text "(+33) 04 77 42 0070"]
] ]
, li [className "list-group-item justify-content-between"] , li [className "list-group-item justify-content-between"]
[ span [] [text "Telephone"] [ span [] [text "Courriel"]
, span [className "badge badge-default badge-pill"] [text "04 77 42 0070"] , span [className "badge badge-default badge-pill"] [text "gargantua@rabelais.fr"]
]
, li [className "list-group-item justify-content-between"]
[ span [] [text "courriel"]
, span [className "badge badge-default badge-pill"] [text "veronica@mines-stsi.fr"]
] ]
, li [className "list-group-item justify-content-between"] , li [className "list-group-item justify-content-between"]
[ span [] [text "Bureau"] [ span [] [text "Bureau"]
...@@ -81,11 +83,11 @@ userPageSpec = simpleSpec performAction render ...@@ -81,11 +83,11 @@ userPageSpec = simpleSpec performAction render
] ]
, li [className "list-group-item justify-content-between"] , li [className "list-group-item justify-content-between"]
[ span [] [text "Apellation"] [ span [] [text "Apellation"]
, span [className "badge badge-default badge-pill"] [text "Maitre de reherche (EPA)"] , span [className "badge badge-default badge-pill"] [text "Maître de conférences (EPA)"]
] ]
, li [className "list-group-item justify-content-between"] , li [className "list-group-item justify-content-between"]
[ span [] [text "Lieu"] [ span [] [text "Lieu"]
, span [className "badge badge-default badge-pill"] [text "Saint -Etienne, 158 Cours Fauriel"] , span [className "badge badge-default badge-pill"] [text "Saint-Etienne, 158 Cours Fauriel"]
] ]
] ]
...@@ -95,62 +97,73 @@ userPageSpec = simpleSpec performAction render ...@@ -95,62 +97,73 @@ userPageSpec = simpleSpec performAction render
] ]
, div [className "row",_id "user-page-footer"] , div [className "row",_id "user-page-footer"]
[ div [className "col-md-12"] [ div [className "col-md-12"]
[ nav [] facets
[ div [className "nav nav-tabs", _id "nav-tab",role "tablist"] ]
[ ]
a [className "nav-item nav-link active",_id "nav-home-tab", _data {toggle : "tab"},href "#nav-home",role "tab",aria {controls : "nav-home"},aria {selected:true}] [ text "Publications (12)"] ]
, a [className "nav-item nav-link",_id "nav-profile-tab", _data {toggle : "tab"},href "#nav-profile",role "tab",aria {controls : "nav-profile"},aria {selected:true}] [ text "Brevets (2)"]
,a [className "nav-item nav-link",_id "nav-contact-tab", _data {toggle : "tab"},href "#nav-contact",role "tab",aria {controls : "nav-contact"},aria {selected:true}] [ text "Projets IMT (5)"]
facets = [ nav []
[ div [className "nav nav-tabs", _id "nav-tab",role "tablist"]
[ a [className "nav-item nav-link active",_id "nav-home-tab" , _data {toggle : "tab"},href "#nav-home" ,role "tab",aria {controls : "nav-home"} ,aria {selected:true}] [ text "Publications (12)"]
, a [className "nav-item nav-link" ,_id "nav-profile-tab", _data {toggle : "tab"},href "#nav-profile",role "tab",aria {controls : "nav-profile"},aria {selected:true}] [ text "Brevets (2)"]
, a [className "nav-item nav-link" ,_id "nav-contact-tab", _data {toggle : "tab"},href "#nav-contact",role "tab",aria {controls : "nav-contact"},aria {selected:true}] [ text "Projets (5)"]
, a [className "nav-item nav-link" ,_id "nav-contact-tab", _data {toggle : "tab"},href "#nav-contact",role "tab",aria {controls : "nav-contact"},aria {selected:true}] [ text "All (19)"]
] ]
] ]
, div [className "tab-content" , _id "nav-tabContent"] , div [className "tab-content" , _id "nav-tabContent"]
[ [
div [className "tab-pane fade show active", role "tabpanel", aria {labelledby : "nav-home-tab"}, _id "nav-home"] div [ className "tab-pane fade show active"
[ , role "tabpanel"
table [ className "table"] , aria {labelledby : "nav-home-tab"}
, _id "nav-home"
]
[ facetExample ]
, div [ className "tab-pane fade show"
, role "tabpanel"
, aria {labelledby : "nav-profile-tab"}
, _id "nav-profile"
]
[ ]
, div [ className "tab-pane fade show"
, role "tabpanel"
, aria {labelledby : "nav-contact-tab"}
, _id "nav-contact"
]
[ ]
]
]
facetExample = table [ className "table"]
[ thead [ className "thead-dark"] [ thead [ className "thead-dark"]
[ tr [] [ tr []
[ [ th [ scope "col"] [ text "Date" ]
th [ scope "col"] , th [ scope "col"] [ text "Description" ]
[ text "Date" , th [ scope "col"] [ text "Projects" ]
] , th [ scope "col"] [ text "Favorite" ]
, th [scope "col"] , th [ scope "col"] [ text "Delete" ]
[ text "Description"
]
, th [ scope "col"]
[ text "Projects"]
, th [ scope "col"]
[ text " Favorite"]
, th [scope "col"]
[text "Delete"]
] ]
] ]
, tbody [] , tbody []
[ tr []
[ td [] [ text "2012/03/06"] [ tr [] [ td [] [ text "2012/03/06"]
, td [] [ text "USE OF ACOUSTIC TO DISCRIMINATE DAMAGE MODES IN COMPOSITE -ANTENNA - STRUCTURE DURING BUCKLING LOADING "] , td [] [ text "Big data and text mining"]
, td [] [ text "ICEM15: 15TH INTERNATIONAL CONFERENCE ON EXPERIMENTAL MECHANICS"] , td [] [ text "European funds"]
, td [] [ i [className "fas fa-star"] []] , td [] [ text "True"]
, td [] [ text "delete"] , td [] [ text "False"]
] ]
, tr [] [ td [] [ text "2013/03/06"]
, td [] [ text "Cryptography"]
, td [] [ text "French funds"]
, td [] [ text "True"]
, td [] [ text "False"]
]
, tr [] [ td [] [ text "2013/03/06"]
, td [] [ text "Artificial Intelligence"]
, td [] [ text "Not found"]
, td [] [ text "True"]
, td [] [ text "False"]
]
] ]
] ]
]
, div [className "tab-pane fade show", role "tabpanel", aria {labelledby : "nav-profile-tab"}, _id "nav-profile"]
[
span [] [text "Lorizzle ipsum bling bling sit amizzle, consectetuer adipiscing elit. Nizzle sapien velizzle, bling bling volutpat, suscipit , gravida vel, arcu. Check it out hizzle that's the shizzle. We gonna chung erizzle. Fo izzle dolor fo turpis tempizzle tempor. Gangsta boom shackalack mofo et turpizzle. Sizzle izzle tortor. Pellentesque uhuh ... yih!"]
]
, div [className "tab-pane fade show", role "tabpanel", aria {labelledby : "nav-contact-tab"}, _id "nav-contact"]
[
span [] [text "Lorizzle ipsum bling bling sit amizzle, consectetuer adipiscing elit. Nizzle sapien velizzle, bling bling volutpat, suscipit , gravida vel, arcu. Check it out hizzle that's the shizzle. We gonna chung erizzle. Fo izzle dolor fo turpis tempizzle tempor. Gangsta boom shackalack mofo et turpizzle. Sizzle izzle tortor. Pellentesque uhuh ... yih!"]
]
]
]
]
]
]
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