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

Merge branch 'dev' into dev-search

parents b1c31559 278b0c8c
......@@ -8,11 +8,15 @@
/.purs*
/.psa*
/.spago
bundle.js
# webpack splays purescript modules in dist. we don't want these to be
# added, but we do want static assets to be added
/dist/*
!/dist/styles/
/dist/styles/*map
!/dist/examples/
!/dist/fonts/
!/dist/images/
!/dist/js/
/dist/styles/*map
\ No newline at end of file
# css source maps
/dist/styles/*map
......@@ -93,7 +93,67 @@ And run a repl:
yarn repl
```
## Note to the contributors
```shell
yarn install && yarn ps-deps
```
### Running a dev server
```shell
yarn dev
```
This will launch a hot-reloading development server with
webpack-dev-server. Visit [localhost:9000](http://localhost:9000/) to
see the result when the output shows a line like this:
```
ℹ 「wdm」: Compiled successfully.
```
#### Purescript IDE integration
A `purs ide` connection will be available on port 9002 while the
development server is running.
A guide to getting set up with the IDE integration is beyond the scope
of this document.
#### Source maps
Currently broken. Someone please fix them.
### Getting a purescript repl
```shell
yarn repl
```
### Building for production
```shell
yarn build
```
Note that a production build takes a little while.
### How do I?
#### Change which backend to connect to?
Edit `Config.purs`. Find the function `endConfig'` just after the
imports and edit `back`. The definitions are not far below, just after
the definitions of the various `front` options.
Example (using `demo.gargantext.org` as backend):
```
endConfig' :: ApiVersion -> EndConfig
endConfig' v = { front : frontRelative
, back : backDemo v }
```
### Contributor notes
Please follow CONTRIBUTING.md
......
{
"name": "purescript-gargantext",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"output"
],
"dependencies": {
"purescript-console": "^4.1.0",
"purescript-thermite": "https://github.com/np/purescript-thermite.git#cf194360c8ee440978a2b342382fc3fddc65b39e",
"purescript-affjax": "^7.0.0",
"purescript-routing": "^8.0.0",
"purescript-argonaut": "^4.0.1",
"purescript-random": "^4.0.0",
"purescript-css": "^4.0.0"
},
"devDependencies": {
"purescript-psci-support": "^4.0.0"
},
"resolutions": {
"purescript-react": "exports",
"purescript-profunctor-lenses": "^4.0.0"
}
}
#!/bin/bash
yarn install && yarn rebuild-set && yarn install-ps && yarn pulp --psc-package build && yarn pulp --psc-package browserify --to dist/bundle.js
......@@ -4,13 +4,12 @@
<meta charset="utf-8"/>
<title>CNRS GarganText</title>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link href="https://use.fontawesome.com/releases/v5.0.8/css/all.css" rel="stylesheet">
<link href="https://use.fontawesome.com/releases/v5.0.8/styles/all.css" rel="stylesheet">
<link href="styles/login.min.css" rel="stylesheet">
<link href="styles/bootstrap.min.css" rel="stylesheet">
<!-- <link href="css/lavish-bootstrap.css" rel="stylesheet"> -->
<link rel="stylesheet" type="text/css" href="styles/menu.css"/>
<!-- <link href="styles/lavish-bootstrap.css" rel="stylesheet"> -->
<link rel="stylesheet" type="text/css" href="styles/context-menu.css"/>
<link rel="stylesheet" type="text/css" href="styles/annotation.css"/>
<link rel="stylesheet" type="text/css" href="styles/menu.css"/>
<link href="styles/Login.css" rel="stylesheet">
<style>
* {margin: 0; padding: 0; list-style: none;}
......@@ -54,7 +53,7 @@
background-color: "#000";
top: 12px;
}
</style>
</style>
</head>
<body>
<div id="app" class ="container-fluid"></div>
......
// This file is just a wrapper so that webpack will call our main function
require('./Main.purs').main();
#!/bin/bash
echo "Upgrading nodeJS"
sudo npm cache clean -f
sudo npm install -g n
sudo n stable
sudo n latest
echo "Installing yarn"
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt update
sudo apt install yarn
./build
......@@ -4,6 +4,7 @@
"rebuild-set": "spago psc-package-insdhall",
"install-ps": "psc-package install",
"build": "pulp --psc-package browserify -t dist/bundle.js",
"dev": "webpack-dev-server --env dev --mode development",
"repl": "pulp --psc-package repl",
"clean": "rm -Rf output"
},
......@@ -19,6 +20,9 @@
"react-dom": "^16.8.2",
"react-sigma": "git://github.com/np/react-sigma.git#shouldComponentUpdate"
},
"eslintConfig": {
"extends": "react-app"
},
"devDependencies": {
"@babel/cli": "^7.1.5",
"@babel/core": "^7.1.6",
......@@ -26,13 +30,30 @@
"@babel/preset-react": "^7.0.0",
"@babel/preset-stage-2": "^7.0.0",
"babel-core": "^7.0.0-bridge",
"babel-loader": "^8.0.4",
"clean-webpack-plugin": "^1.0.0",
"css-loader": "^2.1.0",
"envify": "^4.1.0",
"executive": "^1.6.3",
"file-loader": "^3.0.1",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^4.0.0-beta.5",
"http-server": "^0.11.1",
"mini-css-extract-plugin": "^0.5.0",
"psc-package": "^3.0.1",
"pulp": "^12.4.0",
"purescript": "^0.12.4",
"purs-loader": "^3.3.0",
"react-testing-library": "^6.1.2",
"spago": "^0.7.5"
},
"version": "0.0.0"
"source-map-loader": "^0.2.4",
"spago": "^0.7.5",
"style-loader": "^0.23.1",
"uglify-js": "^3.4.9",
"uglifyify": "^5.0.1",
"webpack": "^4.26.0",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.10",
"webpack-node-externals": "^1.7.2",
"xhr2": "^0.1.4"
}
}
#!/bin/bash
rm -rf .psc-package output bower_components node_modules
./build
#!/bin/bash
yarn repl
......@@ -19,7 +19,7 @@ import DOM.Simple.Document as Document
import DOM.Simple.Types ( DOMRect )
import Effect (Effect)
import Effect.Uncurried ( mkEffectFn1 )
import FFI.Simple ( (...), (..), (.=), delay )
import FFI.Simple ( (...), (..), delay )
import Reactix as R
import Reactix.DOM.HTML as HTML
import Reactix.SyntheticEvent as E
......@@ -56,8 +56,17 @@ contextMenuCpt = R.hooksComponent "ContextMenu" cpt
]
]
pure $ R.createPortal [ elems root menu rect $ cs ] host
elems ref menu (Just rect) = HTML.div (({ ref , className: "context-menu", style: position menu rect} .= "data-toggle" $ "popover") .= "data-placement" $ "right")
elems ref _ _ = HTML.div (({ ref, className: "context-menu" } .= "data-toggle" $ "popover") .= "data-placement" $ "right")
elems ref menu (Just rect) = HTML.div
{ ref
, className: "context-menu"
, style: position menu rect
, data: {toggle: "popover", placement: "right"}
}
elems ref _ _ = HTML.div
{ ref
, className: "context-menu"
, data: {toggle: "popover", placement: "right"}
}
contextMenuEffect
:: forall t
......
......@@ -50,6 +50,7 @@ type Props =
, chart :: ReactElement
, tabType :: TabType
, listId :: Int
, corpusId :: Maybe Int
-- ^ tabType is not ideal here since it is too much entangled with tabs and
-- ngramtable. Let's see how this evolves.
}
......@@ -175,7 +176,7 @@ layoutDocview = simpleSpec performAction render
(_documentIdsDeleted <>~ documentIdsToDelete)
render :: Render State Props Action
render dispatch {nodeId, tabType, listId, totalRecords, chart} deletionState _ =
render dispatch {nodeId, tabType, listId, corpusId, totalRecords, chart} deletionState _ =
[ {- br'
, div [ style {textAlign : "center"}] [ text " Filter "
, input [className "form-control", style {width : "120px", display : "inline-block"}, placeholder "Filter here"]
......@@ -188,8 +189,9 @@ layoutDocview = simpleSpec performAction render
[ chart
, div [className "col-md-12"]
[ pageLoader
{ path: initialPageParams {nodeId, tabType, listId}
{ path: initialPageParams {nodeId, tabType, listId, corpusId}
, listId
, corpusId
, totalRecords
, deletionState
, dispatch
......@@ -210,14 +212,14 @@ layoutDocview = simpleSpec performAction render
mock :: Boolean
mock = false
type PageParams = {nodeId :: Int, listId :: Int, tabType :: TabType, params :: T.Params}
type PageParams = {nodeId :: Int, listId :: Int, corpusId :: Maybe Int, tabType :: TabType, params :: T.Params}
initialPageParams :: {nodeId :: Int, listId :: Int, tabType :: TabType} -> PageParams
initialPageParams {nodeId, listId, tabType} =
{nodeId, tabType, listId, params: T.initialParams}
initialPageParams :: {nodeId :: Int, listId :: Int, corpusId :: Maybe Int, tabType :: TabType} -> PageParams
initialPageParams {nodeId, listId, corpusId, tabType} =
{nodeId, tabType, listId, corpusId, params: T.initialParams}
loadPage :: PageParams -> Aff (Array DocumentsView)
loadPage {nodeId, tabType, listId, params: {limit, offset, orderBy}} = do
loadPage {nodeId, tabType, listId, corpusId, params: {limit, offset, orderBy}} = do
logs "loading documents page: loadPage with Offset and limit"
res <- get $ toUrl Back (Tab tabType offset limit (convOrderBy <$> orderBy)) (Just nodeId)
let docs = res2corpus <$> res
......@@ -253,25 +255,27 @@ type PageLoaderProps row =
, dispatch :: Action -> Effect Unit
, deletionState :: State
, listId :: Int
, corpusId :: Maybe Int
| row
}
renderPage :: forall props path.
Render (Loader.State {nodeId :: Int, listId :: Int, tabType :: TabType | path} (Array DocumentsView))
Render (Loader.State {nodeId :: Int, listId :: Int, corpusId :: Maybe Int, tabType :: TabType | path} (Array DocumentsView))
{ totalRecords :: Int
, dispatch :: Action -> Effect Unit
, deletionState :: State
, listId :: Int
, corpusId :: Maybe Int
| props
}
(Loader.Action PageParams)
renderPage _ _ {loaded: Nothing} _ = [] -- TODO loading spinner
renderPage loaderDispatch { totalRecords, dispatch, listId
renderPage loaderDispatch { totalRecords, dispatch, listId, corpusId
, deletionState: {documentIdsToDelete, documentIdsDeleted, localFavorites}}
{currentPath: {nodeId, tabType}, loaded: Just res} _ =
[ T.tableElt
{ rows
, setParams: \params -> liftEffect $ loaderDispatch (Loader.SetPath {nodeId, tabType, listId, params})
, setParams: \params -> liftEffect $ loaderDispatch (Loader.SetPath {nodeId, tabType, listId, corpusId, params})
, container: T.defaultContainer { title: "Documents" }
, colNames:
T.ColumnName <$>
......@@ -287,38 +291,40 @@ renderPage loaderDispatch { totalRecords, dispatch, listId
where
gi true = "glyphicon glyphicon-star"
gi false = "glyphicon glyphicon-star-empty"
isChecked _id = Set.member _id documentIdsToDelete
toDelete (DocumentsView {_id}) = Set.member _id documentIdsToDelete
isDeleted (DocumentsView {_id}) = Set.member _id documentIdsDeleted
isFavorite {_id,fav} = maybe fav identity (localFavorites ^. at _id)
corpusDocument (Just corpusId) = R.CorpusDocument corpusId
corpusDocument _ = R.Document
rows = (\(DocumentsView r) ->
let isFav = isFavorite r in
let isFav = isFavorite r
toDel = toDelete $ DocumentsView r in
{ row:
[ div []
[ a [ className $ gi isFav
, if (toDelete $ DocumentsView r) then style {textDecoration : "line-through"}
else style {textDecoration : "none"}
, if toDel then style {textDecoration : "line-through"}
else style {textDecoration : "none"}
, onClick $ (\_-> dispatch $ MarkFavorites r._id (not isFav))] []
]
-- TODO show date: Year-Month-Day only
, if (toDelete $ DocumentsView r) then
, if toDel then
div [ style {textDecoration : "line-through"}][text (show r.date)]
else
div [ ][text (show r.date)]
, if (toDelete $ DocumentsView r) then
a [ href (toLink $ R.Document listId r._id)
, if toDel then
a [ href (toLink $ (corpusDocument corpusId) listId r._id)
, style {textDecoration : "line-through"}
, target "_blank"
] [ text r.title ]
else
a [ href (toLink $ R.Document listId r._id)
a [ href (toLink $ (corpusDocument corpusId) listId r._id)
, target "_blank" ] [ text r.title ]
, if (toDelete $ DocumentsView r) then
, if toDel then
div [style {textDecoration : "line-through"}] [ text r.source]
else
div [] [ text r.source]
, input [ _type "checkbox"
, checked (isChecked r._id)
, checked toDel
, onClick $ (\_ -> dispatch $ ToggleDocumentToDelete r._id)]
]
, delete: true
......
module Gargantext.Components.Loader2 where
import Data.Maybe (Maybe(..), isNothing)
import Data.Tuple.Nested ((/\))
import Gargantext.Prelude
import Effect.Aff (Aff, launchAff, launchAff_, killFiber)
import Effect.Class (liftEffect)
import Effect.Exception (error)
import Reactix as R
type State path loaded = { currentPath :: path, loaded :: Maybe loaded }
useLoader
:: forall path loaded
. Eq path
=> Show path
=> path
-> (path -> Aff loaded)
-> (path -> loaded -> R.Element)
-> R.Hooks R.Element
useLoader newPath loader render = do
{currentPath, loaded} /\ setState <- R.useState' { currentPath: newPath, loaded: Nothing }
R.useEffect $
if (isNothing loaded || newPath /= currentPath) then do
logs $ "useLoader " <> show {newPath, currentPath, loadedIsNothing: isNothing loaded}
fiber <- launchAff do
freshlyLoaded <- loader newPath
liftEffect $ setState $ const { currentPath: newPath, loaded: Just freshlyLoaded }
pure $ launchAff_ $ killFiber (error "useLoader") fiber
else do
pure $ pure $ unit
pure case loaded of
Nothing ->
-- TODO load spinner
R.fragment []
Just loadedData ->
render currentPath loadedData
......@@ -14,7 +14,7 @@ import DOM.Simple.Element as Element
import DOM.Simple.Event as DE
import Effect ( Effect )
import Effect.Uncurried (mkEffectFn1)
import FFI.Simple ((..), (.=))
import FFI.Simple ((..))
import Reactix as R
import Reactix.DOM.HTML as HTML
import Reactix.DOM.HTML (text, button, div, input, option, form, span, ul, li, a)
......@@ -70,7 +70,9 @@ databaseInput (db /\ setDB) dbs =
onClick = mkEffectFn1 $ \_ -> setDB (const $ Just db)
dropdownBtnProps = { id: "search-dropdown"
, className: "btn btn-default dropdown-toggle"
, type: "button"} .= "data-toggle" $ "dropdown"
, type: "button"
, data: {toggle: "dropdown"}
}
dropdownBtn (Just db) = button dropdownBtnProps [ span {} [ text (show db) ] ]
dropdownBtn (Nothing) = button dropdownBtnProps [ span {} [ text "-" ] ]
......
This diff is collapsed.
......@@ -14,13 +14,10 @@ import Data.Argonaut (class DecodeJson, decodeJson, class EncodeJson, encodeJson
import Data.Foldable (foldMap)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)
import Data.Map (Map)
import Data.Map as DM
import Data.Maybe (Maybe(..), maybe)
import Data.Tuple (Tuple(..))
import Gargantext.Router as R
import Gargantext.Types
import Gargantext.Types (TermList, TermSize(..))
urlPlease :: End -> String -> String
urlPlease end path = theEnd.baseUrl <> theEnd.prePath <> path
......@@ -62,6 +59,11 @@ frontDev = { baseUrl: "https://dev.gargantext.org"
, prePath: "/#/"
}
frontDemo :: Config
frontDemo = { baseUrl: "https://demo.gargantext.org"
, prePath: "/#/"
}
frontProd :: Config
frontProd = { baseUrl: "https://gargantext.org"
, prePath: "/#/"
......@@ -210,6 +212,7 @@ routesPath R.SearchView = "search"
routesPath (R.Folder i) = "folder/" <> show i
routesPath (R.Corpus i) = "corpus/" <> show i
routesPath R.AddCorpus = "addCorpus"
routesPath (R.CorpusDocument c l i) = "corpus/" <> show c <> "/list/" <> show l <> "/document/" <> show i
routesPath (R.Document l i) = "list/" <> show l <> "/document/" <> show i
routesPath (R.PGraphExplorer i) = "#/"
routesPath R.Dashboard = "dashboard"
......
......@@ -6,6 +6,7 @@ import Prelude hiding (div)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)
import Data.List (fromFoldable)
import Data.Maybe (Maybe(..))
import Data.Tuple (Tuple(..))
import Gargantext.Config (TabType(..), TabSubType(..), PTabNgramType(..))
......@@ -48,7 +49,8 @@ statefulTabs =
{ nodeId, chart
, tabType: TabPairing TabDocs
, totalRecords: 4736
, listId: loaded.defaultListId}) $
, listId: loaded.defaultListId
, corpusId: Nothing}) $
noState DT.docViewSpec
ngramsViewSpec :: {mode :: Mode} -> Spec Tab.State Props Tab.Action
......
......@@ -24,7 +24,7 @@ import Gargantext.Components.Annotation.AnnotatedField as AnnotatedField
import Gargantext.Types (TermList)
import Gargantext.Utils.Reactix ( scuff )
type DocPath = { nodeId :: Int, listIds :: Array Int, tabType :: TabType }
type DocPath = { nodeId :: Int, listIds :: Array Int, corpusId :: Maybe Int, tabType :: TabType }
type NodeDocument = NodePoly Document
......@@ -333,8 +333,8 @@ docViewSpec = simpleSpec performAction render
badge s = span [className "badge badge-default badge-pill"] [text s]
NodePoly {hyperdata : Document doc} = document
layout :: Spec {} {nodeId :: Int, listId :: Int} Void
layout = cmapProps (\{nodeId, listId} -> {nodeId, listIds: [listId], tabType})
layout :: Spec {} {nodeId :: Int, listId :: Int, corpusId :: Maybe Int} Void
layout = cmapProps (\{nodeId, listId, corpusId} -> {nodeId, listIds: [listId], corpusId, tabType})
$ simpleSpec defaultPerformAction render
where
tabType = TabDocument (TabNgramType CTabTerms)
......
......@@ -419,7 +419,7 @@ specOld = fold [treespec treeSpec, graphspec $ simpleSpec performAction render']
Nothing ->
simpleSpec defaultPerformAction defaultRender
Just treeId ->
(cmapProps (const {root: treeId}) (noState Tree.treeview))
(cmapProps (const {root: treeId, mCurrentRoute: Nothing}) (noState Tree.treeview))
render' :: Render State {} Action
......
......@@ -8,7 +8,6 @@ import Data.List (fromFoldable)
import Data.Maybe (Maybe(..))
import Data.Tuple (Tuple(..))
import Gargantext.Config (TabType(..), TabSubType(..))
import Gargantext.Config (CTabNgramType(..), End(..), Path(..), TabSubType(..), TabType(..), toUrl)
import Gargantext.Pages.Corpus.Tabs.Types (Props)
......@@ -59,22 +58,24 @@ statefulTabs =
where
-- TODO totalRecords
docs = noState ( cmapProps (\{path: corpusId} -> {corpusId : corpusId, tabType: TabCorpus TabDocs}) histoSpec
docs = noState ( cmapProps (\{path: corpusId} -> {corpusId, tabType: TabCorpus TabDocs}) histoSpec
<>
(cmapProps (\{path: nodeId, loaded: loaded} ->
{ nodeId : nodeId
(cmapProps (\{path: nodeId, loaded} ->
{ nodeId
, chart : div [][]
, tabType: TabCorpus TabDocs
, totalRecords: 4737
, listId: loaded.defaultListId}) $ noState DT.docViewSpec
, listId: loaded.defaultListId
, corpusId: Just nodeId}) $ noState DT.docViewSpec
)
)
trash = cmapProps (\{path: nodeId, loaded: loaded} ->
trash = cmapProps (\{path: nodeId, loaded} ->
{ nodeId
, chart: div [][]
, tabType: TabCorpus TabTrash
, totalRecords: 4736
, listId: loaded.defaultListId}) $ noState DT.docViewSpec
, listId: loaded.defaultListId
, corpusId: Nothing}) $ noState DT.docViewSpec
ngramsViewSpec :: {mode :: Mode} -> Spec Tab.State Props Tab.Action
......@@ -86,13 +87,13 @@ ngramsViewSpec {mode} =
)
where
tabType = TabCorpus $ TabNgramType $ modeTabType mode
chart Authors = cmapProps (\{path: corpusId} -> {corpusId : corpusId, tabType}) pieSpec
chart Sources = cmapProps (\{path: corpusId} -> {corpusId : corpusId, tabType}) barSpec
chart Authors = cmapProps (\{path: corpusId} -> {corpusId, tabType}) pieSpec
chart Sources = cmapProps (\{path: corpusId} -> {corpusId, tabType}) barSpec
chart Institutes = cmapProps (\{loaded: {defaultListId}, path: corpusId} ->
{corpusId, listId: defaultListId, tabType, limit: (Just 1000)})
treeSpec
chart Terms = cmapProps (\{loaded: {defaultListId}, path: corpusId} ->
{corpusId, listId: defaultListId, tabType, limit: (Just 1000)})
-- TODO limit should be select in the chart by default it is 1000
......
......@@ -48,6 +48,9 @@ dispatchAction dispatcher _ (Annuaire id) = do
dispatchAction dispatcher _ (Folder id) = do
dispatcher $ SetRoute $ Folder id
dispatchAction dispatcher _ (CorpusDocument c i n) = do
dispatcher $ SetRoute $ CorpusDocument c i n
dispatchAction dispatcher _ (Document i n) = do
dispatcher $ SetRoute $ Document i n
......
......@@ -60,7 +60,8 @@ pagesComponent s = case s.currentRoute of
selectSpec (Corpus i) = layout0 $ cmapProps (const {nodeId: i}) $ noState Corpus.layout
selectSpec AddCorpus = layout0 $ focus _addCorpusState _addCorpusAction AC.layoutAddcorpus
selectSpec SearchView = layout0 $ focus _searchState _searchAction S.searchSpec
selectSpec (Document l i) = layout0 $ cmapProps (const {nodeId: i, listId: l}) $ noState Annotation.layout
selectSpec (CorpusDocument c l i) = layout0 $ cmapProps (const {nodeId: i, listId: l, corpusId: Just c}) $ noState Annotation.layout
selectSpec (Document l i) = layout0 $ cmapProps (const {nodeId: i, listId: l, corpusId: Nothing}) $ noState Annotation.layout
selectSpec (PGraphExplorer i)= layout1 $ focus _graphExplorerState _graphExplorerAction GE.specOld
selectSpec Dashboard = layout0 $ noState Dsh.layoutDashboard
selectSpec (Annuaire i) = layout0 $ cmapProps (const {annuaireId: i}) $ noState A.layout
......@@ -89,14 +90,13 @@ layout0 layout =
withState \st ->
case st.loginState.authData of
Just (AuthData {tree_id}) ->
ls $ cmapProps (const {root: tree_id}) as
ls $ cmapProps (const {root: tree_id, mCurrentRoute: st.currentRoute}) as
Nothing ->
outerLayout1
, rs bs
]
ls = over _render \render d p s c -> [
div [ className "col-md-2", style {paddingTop: "60px"} ] $ render d p s c
]
rs = over _render \render d p s c -> [
div [ case (s.loginState.authData) of
......@@ -138,7 +138,7 @@ layout1 layout =
[ withState \st ->
case st.loginState.authData of
Just (AuthData {tree_id}) ->
ls $ cmapProps (const {root: tree_id}) as
ls $ cmapProps (const {root: tree_id, mCurrentRoute: st.currentRoute}) as
Nothing ->
outerLayout1
, rs bs
......
......@@ -21,6 +21,7 @@ data Routes
| Corpus Int
| AddCorpus
| Document Int Int
| CorpusDocument Int Int Int
| PGraphExplorer Int
| Dashboard
| Annuaire Int
......@@ -33,6 +34,7 @@ routing = oneOf
, SearchView <$ route "search"
, AddCorpus <$ route "addCorpus"
, Folder <$> (route "folder" *> int)
, CorpusDocument <$> (route "corpus" *> int) <*> (lit "list" *> int) <*> (lit "document" *> int)
, Corpus <$> (route "corpus" *> int)
, Document <$> (route "list" *> int) <*> (lit "document" *> int)
, Dashboard <$ route "dashboard"
......@@ -42,10 +44,10 @@ routing = oneOf
, ContactPage <$> (route "contact" *> int)
, Home <$ lit ""
]
where
route str = lit "" *> lit str
int :: Match Int
int = floor <$> num
......@@ -55,6 +57,7 @@ instance showRoutes :: Show Routes where
show SearchView = "Search"
show (UserPage i) = "User" <> show i
show (ContactPage i) = "Contact" <> show i
show (CorpusDocument _ _ i) = "Document" <> show i
show (Document _ i) = "Document" <> show i
show (Corpus i) = "Corpus" <> show i
show (Annuaire i) = "Annuaire" <> show i
......
......@@ -45,4 +45,4 @@ select :: ElemFactory
select = createDOMElement "select"
effToggler :: forall e. R.State Boolean -> EffectFn1 e Unit
effToggler (_value /\ setValue) = mkEffectFn1 $ \e -> setValue not
effToggler (value /\ setValue) = mkEffectFn1 $ \e -> setValue $ const $ not value
<!doctype>
<html>
<head>
<meta charset="utf-8"/>
<title>CNRS GarganText</title>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link href="https://use.fontawesome.com/releases/v5.0.8/styles/all.css" rel="stylesheet">
<link href="styles/login.min.css" rel="stylesheet">
<link href="styles/bootstrap.min.css" rel="stylesheet">
<!-- <link href="styles/lavish-bootstrap.css" rel="stylesheet"> -->
<link rel="stylesheet" type="text/css" href="styles/context-menu.css"/>
<link rel="stylesheet" type="text/css" href="styles/menu.css"/>
<link href="styles/Login.css" rel="stylesheet">
<style>
* {margin: 0; padding: 0; list-style: none;}
.tree ul li {
margin-left: 15px;
position: relative;
padding-left: 5px;
}
#toolbar {display : inline;}
#toolbar ul li {display : inline }
#toolbar ul li form {display : inline}
.tree { margin-top : 20px;}
.tree ul li::before {
content: " ";
position: absolute;
width: 1px;
background-color: #000;
top: 5px;
bottom: -12px;
left: -10px;
}
body > .tree ul > li:first-child::before {top: 12px;}
.tree ul li:not(:first-child):last-child::before {display: none;}
.tree ul li:only-child::before {
display: list-item;
content: " ";
position: absolute;
width: 1px;
background-color: "#000";
top: 5px;
bottom: 7px;
height: 7px;
left: -10px;
}
.tree ul li::after {
content: " ";
position: absolute;
left: -10px;
width: 10px;
height: 1px;
background-color: "#000";
top: 12px;
}
</style>
</head>
<body>
<div id="app" class ="container-fluid"></div>
<div id="menu-portal"></div>
<script src="bundle.js"></script>
<script src="js/bootstrap-native.min.js"></script>
</body>
</html>
// This file is just a wrapper so that webpack will call our main function
require('./Main.purs').main();
'use strict';
let webpack = require('webpack');
let path = require('path');
let exec = require('executive');
let nodeExternals = require('webpack-node-externals');
let isWebpackDevServer = process.argv.some(a => path.basename(a) === 'webpack-dev-server');
let HtmlWebpackPlugin = require('html-webpack-plugin');
let CleanWebpackPlugin = require('clean-webpack-plugin');
let isWatch = process.argv.some(a => a === '--watch');
// TODO: We have agreed to move to spago, but not done it yet
// let spago_sources = async () =>
// exec.quiet(
// "psc-package sources",
// { options: 'strict' }
// ).then(function (res) {
// let sources = res.stdout.split(/\r?\n/);
// sources.pop(); // extra newline at the end of output
// return sources;
// });
let dist = path.join(__dirname, 'dist');
let src = path.join(__dirname, 'src');
let test = path.join(__dirname, 'test');
// kill when spago
let futured = async () => new Promise((resolve, _) => resolve([]));
module.exports = (env) =>
// spago_sources()
futured()
.then(function (ps_sources) {
ps_sources.push('src/**/*.purs');
// TODO: testing in browser and headless
// if (env === "browser" || env === "headless")
// ps_sources.push('test/Main.purs');
let config = {
cache: true,
mode: 'development',
target: "web",
devtool: 'inline-source-map',
devServer: {
disableHostCheck: true,
contentBase: dist,
compress: true,
port: 8000
},
output: {
path: dist,
filename: 'bundle.js'
},
module: {
rules: [
{test: /\.purs$/,
exclude: /(node_modules)/,
use: [
{loader: "purs-loader",
options: {
src: ps_sources,
output: dist,
pscIde: true,
pscIdeClientArgs: {port: 4002},
pscIdeServerArgs: {port: 4002},
pscArgs: {codegen: "js,sourcemaps"},
pscPackage: true,
bundle: false,
watch: isWatch}},
{loader: "source-map-loader"},
]},
{test: /\.css$/,
exclude: /(node_modules)/,
use: ["style-loader", "css-loader"]},
{test: /\.(png|jpg|gif|svg)$/,
exclude: /(node_modules)/,
use: [ "file-loader" ]},
{test: /\.js$/,
exclude: /(node_modules)/,
use: ["babel-loader", "source-map-loader"]}
]
},
resolve: {
modules: [ 'node_modules' ],
extensions: [ '.purs', '.js']
},
plugins: [
// TODO: can we put the checked-in assets in dist somewhere else
// and move them into place so we can clean?
// new CleanWebpackPlugin(['dist']),
new webpack.LoaderOptionsPlugin({debug: true})
],
entry: path.join(src, "index.js")
};
switch(env) {
case 'dev':
console.log("Serving index.html from template src/index.html")
config.plugins.push(new HtmlWebpackPlugin({
template: path.join(src, "index.html")
}));
break;
// TODO: testing environments - browser and headless
// case 'browser':
// config.plugins.push(new HtmlWebpackPlugin({
// title: "Reactix",
// template: path.join(test, "browser.html")
// }));
// break;
// case 'headless': break;
default:
console.log("unknown env: ", env);
}
return config;
});
This diff is collapsed.
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