Commit 66c58ed7 authored by Alexandre Delanoë's avatar Alexandre Delanoë

Merge branch 'dev-merge' into dev

parents faa5ccfb dc04d045
...@@ -533,7 +533,9 @@ li .leaf:hover a.settings { ...@@ -533,7 +533,9 @@ li .leaf:hover a.settings {
} }
.code-editor-heading { .code-editor-heading {
display: flex; /* .buttons-right */
/* display: flex */
/* justify-content: flex-end */
} }
.code-editor-heading .renameable { .code-editor-heading .renameable {
flex-grow: 2; flex-grow: 2;
...@@ -541,20 +543,7 @@ li .leaf:hover a.settings { ...@@ -541,20 +543,7 @@ li .leaf:hover a.settings {
.code-editor-heading .renameable .text { .code-editor-heading .renameable .text {
padding-right: 10px; padding-right: 10px;
} }
.code-editor-heading .buttons-right {
display: flex;
justify-content: flex-end;
}
.code-editor .toolbar {
display: flex;
justify-content: flex-start;
width: 100%;
}
.code-editor .editor {
display: flex;
width: 100%;
}
.code-editor .editor .code-area { .code-editor .editor .code-area {
flex-grow: 1; flex-grow: 1;
max-height: 200px; max-height: 200px;
......
{"version":3,"sourceRoot":"","sources":["../../src/sass/_menu.sass","../../src/sass/_context_menu.sass","../../src/sass/_graph.sass","../../src/sass/_login.sass","../../src/sass/_tree.sass","../../src/sass/_code_editor.sass","../../src/sass/_styles.sass","../../src/sass/_range_slider.sass"],"names":[],"mappings":"AAAA;AAEA;AACA;AACA;AACA;AACA;AAEA;EACI;EACA;;;AAEJ;EACI;EACA;EACA;EACA;;;AAEJ;EACE;;;AAEF;AACI;EACA;;;AAEJ;AACI;EACA;;;AAGJ;AACA;EACI;;;AAEJ;EACI;EACA;EACA;EACA;;;AAEJ;EACE;EACA;;;AAEF;EACE;;;AC7CF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;;;AClBF;EACE;EACA;EACA;;;AAEF;AAkCE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAxCA;EAZA;EACA;EAEA;EAWE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEF;EACE;EACA;;AAGA;EACE;EACA;;AACN;EACE;;AACF;EACE;;AAEF;EApCA;EACA;EAEA;EAmCE;EACA;;AACF;EACE;;AACF;EACE;;AAWF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEJ;EACE;;AAEA;EACE;;AAEJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;ACpFJ;EACE;;;AAOF;EACE;;AACA;EACE;EACA;;;AAEJ;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAGF;EACE;;AAEE;EACE;EACA;;AACA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;;;AAKJ;EACE;EACA;EACA;;;AAGJ;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;;AACF;EACE;EACA;;AACA;EACE;EACA;EACA;EACA;;AACA;EACE;;AACF;EACE;EACA;EACA;EACA;;AACA;EACE;;AACN;EACE;EACA;EACA;EACA;;;AAGN;EACE;EACA;EACA;EACA;EACA;;AAGE;EACE;;;AAEN;EACE;EACA;EACA;EACA;EACA;;AAGE;EACE;;;AAEN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AAEJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;AACA;EACE;EACA;;;AAGF;EACE;;;AAEJ;EACI;EACA;;;AAGF;EACE;;;AAEJ;EACE;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;;;ACvKF;EACE;;;AAGA;EACE;EACA;EACA;;AAEA;EACE;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAER;EACE;;AAEE;EACE;;AACA;EACE;EACA;EACA;EACA;;AACF;EACE;EACA;EACA;EACA;EACA;;AACF;EACE;;AACF;EACE;EACA;EACA;EAEA;EACA;EACA;;AAEA;EACE;;AACF;EACE;;AAGN;EACE;;AACF;EACE;;AACA;EACE;EACA;;AAEE;EACE;EACA;;AACF;EACE;EACA;;AAIR;EACE;;AACF;EACE;;AACA;EACE;EACA;;AAEE;EACE;EACA;;AACF;EACE;EACA;;AACF;EACE;EACA;;AAEV;EACE;;AACF;EACE;;AAEE;EACE;;AACF;EACE;;AACN;EACE;;AAEE;EACE;;;AAGR;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAEF;EACE;;;AAIF;EACE;;AAEA;EACE;;;AAGN;EACE;;AACF;EACE;;AACF;EACE;;;AC7IJ;EACE;;AAEA;EACE;;AACA;EACE;;AACJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;;AACF;EACE;EACA;;AACA;EACE;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EArDR;EACA;EACA;EACA;EACA;EACA;EACA;EAlBA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AA2DM;EACE;EACA;EACA;EACA;EACA;EA7DR;EACA;EACA;EACA;EACA;EACA;EACA;EAlBA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAmEE;EACE;EACA;EACA;EACA;EACA;EACA;;AACF;EACE;EACA;EACA;;AACA;EACE;EACA;;AACF;EACE;EACA;;AACF;EACE;EACA;;AAGE;EACE;;AAEF;EACE;;;ACtGV;EACE;;AACF;EACE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;;AAGE;EACE;EACA;;AAEF;EACE;EACA;;;AAEV;EACE;;AACA;EACE;EACA;EACA;;;AAIA;EACE;;AACA;EACE;EACA;;AACF;EACE;;AACA;EACE;;AACJ;EACE;;;AAER;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAIE;EACE;;;ACvDN;EACE;AACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EAEA;EAEA;;AAEA;EACE;EAEA;EACA;EACA;;;AAGN;EACE","file":"sass.css"} {"version":3,"sourceRoot":"","sources":["../../src/sass/_menu.sass","../../src/sass/_context_menu.sass","../../src/sass/_graph.sass","../../src/sass/_login.sass","../../src/sass/_tree.sass","../../src/sass/_code_editor.sass","../../src/sass/_styles.sass","../../src/sass/_range_slider.sass"],"names":[],"mappings":"AAAA;AAEA;AACA;AACA;AACA;AACA;AAEA;EACI;EACA;;;AAEJ;EACI;EACA;EACA;EACA;;;AAEJ;EACE;;;AAEF;AACI;EACA;;;AAEJ;AACI;EACA;;;AAGJ;AACA;EACI;;;AAEJ;EACI;EACA;EACA;EACA;;;AAEJ;EACE;EACA;;;AAEF;EACE;;;AC7CF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;;;AClBF;EACE;EACA;EACA;;;AAEF;AAkCE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAxCA;EAZA;EACA;EAEA;EAWE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEF;EACE;EACA;;AAGA;EACE;EACA;;AACN;EACE;;AACF;EACE;;AAEF;EApCA;EACA;EAEA;EAmCE;EACA;;AACF;EACE;;AACF;EACE;;AAWF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEJ;EACE;;AAEA;EACE;;AAEJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;ACpFJ;EACE;;;AAOF;EACE;;AACA;EACE;EACA;;;AAEJ;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAGF;EACE;;AAEE;EACE;EACA;;AACA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;;;AAKJ;EACE;EACA;EACA;;;AAGJ;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;;AACF;EACE;EACA;;AACA;EACE;EACA;EACA;EACA;;AACA;EACE;;AACF;EACE;EACA;EACA;EACA;;AACA;EACE;;AACN;EACE;EACA;EACA;EACA;;;AAGN;EACE;EACA;EACA;EACA;EACA;;AAGE;EACE;;;AAEN;EACE;EACA;EACA;EACA;EACA;;AAGE;EACE;;;AAEN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AAEJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;AACA;EACE;EACA;;;AAGF;EACE;;;AAEJ;EACI;EACA;;;AAGF;EACE;;;AAEJ;EACE;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;;;ACvKF;EACE;;;AAGA;EACE;EACA;EACA;;AAEA;EACE;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAER;EACE;;AAEE;EACE;;AACA;EACE;EACA;EACA;EACA;;AACF;EACE;EACA;EACA;EACA;EACA;;AACF;EACE;;AACF;EACE;EACA;EACA;EAEA;EACA;EACA;;AAEA;EACE;;AACF;EACE;;AAGN;EACE;;AACF;EACE;;AACA;EACE;EACA;;AAEE;EACE;EACA;;AACF;EACE;EACA;;AAIR;EACE;;AACF;EACE;;AACA;EACE;EACA;;AAEE;EACE;EACA;;AACF;EACE;EACA;;AACF;EACE;EACA;;AAEV;EACE;;AACF;EACE;;AAEE;EACE;;AACF;EACE;;AACN;EACE;;AAEE;EACE;;;AAGR;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAEF;EACE;;;AAIF;EACE;;AAEA;EACE;;;AAGN;EACE;;AACF;EACE;;AACF;EACE;;;AC7IJ;AAKE;AACA;AACA;;AANA;EACE;;AACA;EACE;;;AAOF;EACE;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EA7CR;EACA;EACA;EACA;EACA;EACA;EACA;EAlBA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAmDM;EACE;EACA;EACA;EACA;EACA;EArDR;EACA;EACA;EACA;EACA;EACA;EACA;EAlBA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AA2DE;EACE;EACA;EACA;EACA;EACA;EACA;;AACF;EACE;EACA;EACA;;AACA;EACE;EACA;;AACF;EACE;EACA;;AACF;EACE;EACA;;AAGE;EACE;;AAEF;EACE;;;AC9FV;EACE;;AACF;EACE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;;AAGE;EACE;EACA;;AAEF;EACE;EACA;;;AAEV;EACE;;AACA;EACE;EACA;EACA;;;AAIA;EACE;;AACA;EACE;EACA;;AACF;EACE;;AACA;EACE;;AACJ;EACE;;;AAER;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAIE;EACE;;;ACvDN;EACE;AACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EAEA;EAEA;;AAEA;EACE;EAEA;EACA;EACA;;;AAGN;EACE","file":"sass.css"}
\ No newline at end of file \ No newline at end of file
...@@ -119,7 +119,7 @@ appCpt = R.hooksComponentWithModule thisModule "app" cpt where ...@@ -119,7 +119,7 @@ appCpt = R.hooksComponentWithModule thisModule "app" cpt where
documentMainLayout { listId, mCorpusId: Just corpusId, nodeId, session } [] documentMainLayout { listId, mCorpusId: Just corpusId, nodeId, session } []
] ]
Dashboard sid nodeId -> withSession sid $ \session -> forested [ Dashboard sid nodeId -> withSession sid $ \session -> forested [
dashboardLayout { nodeId, session } dashboardLayout { nodeId, session } []
] ]
Document sid listId nodeId -> Document sid listId nodeId ->
withSession sid $ withSession sid $
......
...@@ -117,15 +117,14 @@ codeEditorCpt = R.hooksComponentWithModule thisModule "codeEditor" cpt ...@@ -117,15 +117,14 @@ codeEditorCpt = R.hooksComponentWithModule thisModule "codeEditor" cpt
setCodeOverlay controls code' setCodeOverlay controls code'
renderHtml code' controls renderHtml code' controls
pure $ H.div { className: "code-editor" } [ pure $ H.div { className: "code-editor" }
toolbar {controls, onChange} [ toolbar {controls, onChange}
, H.div { className: "row error" } [ , H.div { className: "row error" }
errorComponent {error: controls.error} [ errorComponent {error: controls.error} ]
] , H.div { className: "row editor" }
, H.div { className: "row editor" } [ [ H.div { className: "code-area " <> (codeHidden $ fst controls.viewType) }
H.div { className: "code-area " <> (codeHidden $ fst controls.viewType) } [ [ H.div { className: "code-container" }
H.div { className: "code-container" } [ [ H.textarea { defaultValue: code
H.textarea { defaultValue: code
, on: { change: onEditChange controls onChange } , on: { change: onEditChange controls onChange }
, placeholder: "Type some code..." , placeholder: "Type some code..."
, ref: controls.codeElRef } [ ] , ref: controls.codeElRef } [ ]
...@@ -208,12 +207,15 @@ toolbarCpt = R.hooksComponentWithModule thisModule "toolbar" cpt ...@@ -208,12 +207,15 @@ toolbarCpt = R.hooksComponentWithModule thisModule "toolbar" cpt
where where
cpt props@{controls: {codeType, error, viewType}} _ = do cpt props@{controls: {codeType, error, viewType}} _ = do
pure $ pure $
H.div { className: "row toolbar" } [ H.div { className: "row toolbar" }
codeTypeSelector { [ H.div { className: "col-2" }
[ codeTypeSelector {
codeType codeType
, onChange: onChangeCodeType props , onChange: onChangeCodeType props
} }
, viewTypeSelector {state: viewType} ]
, H.div { className: "col-1" }
[ viewTypeSelector {state: viewType} ]
] ]
-- Handle rerendering of preview when viewType changed -- Handle rerendering of preview when viewType changed
......
...@@ -135,9 +135,11 @@ sideTab _ _ = H.div {} [] ...@@ -135,9 +135,11 @@ sideTab _ _ = H.div {} []
-- selectedNodes :: Record Props -> Map.Map String Nodes -> R.Element -- selectedNodes :: Record Props -> Map.Map String Nodes -> R.Element
selectedNodes props nodesMap = selectedNodes props nodesMap =
R2.row [ R2.col 12 R2.row [ R2.col 12
[ RH.ul { id: "myTab", className: "nav nav-tabs", role: "tablist"} [ RH.ul { className: "nav nav-tabs d-flex justify-content-center"
, id: "myTab"
, role: "tablist" }
[ RH.div { className: "tab-content" } [ RH.div { className: "tab-content" }
[ RH.div { className: "" [ RH.div { className: "d-flex flex-wrap justify-content-center"
, role: "tabpanel" } , role: "tabpanel" }
( Seq.toUnfoldable ( Seq.toUnfoldable
$ ( Seq.map (badge props.selectedNodeIds) $ ( Seq.map (badge props.selectedNodeIds)
...@@ -156,7 +158,7 @@ selectedNodes props nodesMap = ...@@ -156,7 +158,7 @@ selectedNodes props nodesMap =
] ]
neighborhood props = RH.div { className: "tab-content", id: "myTabContent" } neighborhood props = RH.div { className: "tab-content", id: "myTabContent" }
[ RH.div { -- className: "flex-space-around d-flex justify-content-center" [ RH.div { -- className: "flex-space-around d-flex justify-content-center"
className: "flex-space-around d-flex" className: "d-flex flex-wrap flex-space-around"
, id: "home" , id: "home"
, role: "tabpanel" , role: "tabpanel"
} }
...@@ -170,7 +172,7 @@ removeButton btnType text rType props' nodesMap' = ...@@ -170,7 +172,7 @@ removeButton btnType text rType props' nodesMap' =
if Set.isEmpty $ fst props'.selectedNodeIds then if Set.isEmpty $ fst props'.selectedNodeIds then
RH.div {} [] RH.div {} []
else else
RH.button { className: "btn btn-" <> btnType RH.button { className: "btn btn-sm btn-" <> btnType
, on: { click: onClickRemove rType props' nodesMap' } , on: { click: onClickRemove rType props' nodesMap' }
} }
[ RH.text text ] [ RH.text text ]
......
...@@ -42,7 +42,10 @@ inputWithEnter props = R.createElement inputWithEnterCpt props [] ...@@ -42,7 +42,10 @@ inputWithEnter props = R.createElement inputWithEnterCpt props []
where where
onInput e = do onInput e = do
if autoSave then
onValueChanged $ R.unsafeEventValue e onValueChanged $ R.unsafeEventValue e
else
pure unit
onKeyPress e = do onKeyPress e = do
char <- R2.keyCode e char <- R2.keyCode e
......
This diff is collapsed.
...@@ -2,8 +2,9 @@ module Gargantext.Components.Nodes.Corpus.Dashboard where ...@@ -2,8 +2,9 @@ module Gargantext.Components.Nodes.Corpus.Dashboard where
import DOM.Simple.Console (log2) import DOM.Simple.Console (log2)
import Data.Array as A import Data.Array as A
import Data.List as List
import Data.Maybe (Maybe(..), fromMaybe) import Data.Maybe (Maybe(..), fromMaybe)
import Data.Tuple (fst) import Data.Tuple (Tuple(..), snd)
import Data.Tuple.Nested ((/\)) import Data.Tuple.Nested ((/\))
import Effect (Effect) import Effect (Effect)
import Effect.Aff (launchAff_) import Effect.Aff (launchAff_)
...@@ -11,8 +12,10 @@ import Effect.Class (liftEffect) ...@@ -11,8 +12,10 @@ import Effect.Class (liftEffect)
import Reactix as R import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
import Gargantext.Components.Nodes.Corpus (fieldsCodeEditor)
import Gargantext.Components.Nodes.Corpus.Chart.Predefined as P import Gargantext.Components.Nodes.Corpus.Chart.Predefined as P
import Gargantext.Components.Nodes.Dashboard.Types as DT import Gargantext.Components.Nodes.Dashboard.Types as DT
import Gargantext.Components.Nodes.Types
import Gargantext.Hooks.Loader (useLoader) import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Prelude import Gargantext.Prelude
import Gargantext.Sessions (Session, sessionId) import Gargantext.Sessions (Session, sessionId)
...@@ -20,6 +23,7 @@ import Gargantext.Types (NodeID) ...@@ -20,6 +23,7 @@ import Gargantext.Types (NodeID)
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Reload as GUR import Gargantext.Utils.Reload as GUR
thisModule :: String
thisModule = "Gargantext.Components.Nodes.Corpus.Dashboard" thisModule = "Gargantext.Components.Nodes.Corpus.Dashboard"
type Props = type Props =
...@@ -27,42 +31,42 @@ type Props = ...@@ -27,42 +31,42 @@ type Props =
, session :: Session , session :: Session
) )
dashboardLayout :: Record Props -> R.Element dashboardLayout :: R2.Component Props
dashboardLayout props = R.createElement dashboardLayoutCpt props [] dashboardLayout = R.createElement dashboardLayoutCpt
dashboardLayoutCpt :: R.Component Props
dashboardLayoutCpt = R.hooksComponentWithModule thisModule "dashboardLayout" cpt
where where
dashboardLayoutCpt :: R.Component Props
dashboardLayoutCpt = R.hooksComponentWithModule thisModule "dashboardLayout" cpt
cpt { nodeId, session } _ = do cpt { nodeId, session } _ = do
let sid = sessionId session let sid = sessionId session
pure $ dashboardLayoutWithKey { key: show sid <> "-" <> show nodeId, nodeId, session } pure $ dashboardLayoutWithKey { key: show sid <> "-" <> show nodeId, nodeId, session } []
type KeyProps = ( type KeyProps = (
key :: String key :: String
| Props | Props
) )
dashboardLayoutWithKey :: Record KeyProps -> R.Element dashboardLayoutWithKey :: R2.Component KeyProps
dashboardLayoutWithKey props = R.createElement dashboardLayoutWithKeyCpt props [] dashboardLayoutWithKey = R.createElement dashboardLayoutWithKeyCpt
dashboardLayoutWithKeyCpt :: R.Component KeyProps
dashboardLayoutWithKeyCpt = R.hooksComponentWithModule thisModule "dashboardLayoutWithKey" cpt
where where
dashboardLayoutWithKeyCpt :: R.Component KeyProps
dashboardLayoutWithKeyCpt = R.hooksComponentWithModule thisModule "dashboardLayoutWithKey" cpt
cpt { nodeId, session } _ = do cpt { nodeId, session } _ = do
reload <- GUR.new reload <- GUR.new
useLoader {nodeId, reload: GUR.value reload, session} DT.loadDashboardWithReload $ useLoader {nodeId, reload: GUR.value reload, session} DT.loadDashboardWithReload $
\dashboardData@{hyperdata: DT.Hyperdata h, parentId} -> do \dashboardData@{hyperdata: DT.Hyperdata h, parentId} -> do
let { charts } = h let { charts, fields } = h
dashboardLayoutLoaded { charts dashboardLayoutLoaded { charts
, corpusId: parentId , corpusId: parentId
, defaultListId: 0 , defaultListId: 0
, fields
, key: show $ GUR.value reload , key: show $ GUR.value reload
, nodeId , nodeId
, onChange: onChange nodeId reload (DT.Hyperdata h) , onChange: onChange nodeId reload (DT.Hyperdata h)
, session } , session } []
where where
onChange :: NodeID -> GUR.ReloadS -> DT.Hyperdata -> Array P.PredefinedChart -> Effect Unit onChange :: NodeID -> GUR.ReloadS -> DT.Hyperdata -> Array P.PredefinedChart -> Effect Unit
onChange nodeId' reload (DT.Hyperdata h) charts = do onChange nodeId' reload (DT.Hyperdata h) charts = do
...@@ -76,38 +80,69 @@ type LoadedProps = ...@@ -76,38 +80,69 @@ type LoadedProps =
( charts :: Array P.PredefinedChart ( charts :: Array P.PredefinedChart
, corpusId :: NodeID , corpusId :: NodeID
, defaultListId :: Int , defaultListId :: Int
, fields :: List.List FTField
, key :: String , key :: String
, onChange :: Array P.PredefinedChart -> Effect Unit , onChange :: Array P.PredefinedChart -> Effect Unit
| Props | Props
) )
dashboardLayoutLoaded :: Record LoadedProps -> R.Element dashboardLayoutLoaded :: R2.Component LoadedProps
dashboardLayoutLoaded props = R.createElement dashboardLayoutLoadedCpt props [] dashboardLayoutLoaded = R.createElement dashboardLayoutLoadedCpt
dashboardLayoutLoadedCpt :: R.Component LoadedProps
dashboardLayoutLoadedCpt = R.hooksComponentWithModule thisModule "dashboardLayoutLoaded" cpt
where where
cpt props@{ charts, corpusId, defaultListId, onChange, session } _ = do dashboardLayoutLoadedCpt :: R.Component LoadedProps
pure $ dashboardLayoutLoadedCpt = R.hooksComponentWithModule thisModule "dashboardLayoutLoaded" cpt
H.div {} ([ H.h1 {} [ H.text "Board" ]
cpt props@{ charts, corpusId, defaultListId, fields, nodeId, onChange, session } _ = do
let fieldsWithIndex = List.mapWithIndex (\idx -> \t -> Tuple idx t) fields
fieldsS <- R.useState' fieldsWithIndex
fieldsRef <- R.useRef fields
-- handle props change of fields
R.useEffect1' fields $ do
if R.readRef fieldsRef == fields then
pure unit
else do
R.setRef fieldsRef fields
snd fieldsS $ const fieldsWithIndex
pure $ H.div {}
[ H.div { className: "row" }
[ H.div { className: "col-12" }
([ H.h1 {} [ H.text "Board" ]
, H.p {} [ H.text "Summary of all your charts here" ] , H.p {} [ H.text "Summary of all your charts here" ]
] <> chartsEls <> [addNew]) ] <> chartsEls <> [addNew])
]
, H.div { className: "row" }
[ H.div { className: "col-12" }
[ fieldsCodeEditor { fields: fieldsS
, nodeId
, session } ]
]
, H.div { className: "row" }
[ H.div { className: "btn btn-secondary"
, on: { click: onClickAddField fieldsS }
}
[ H.span { className: "fa fa-plus" } [ ]
]
]
]
where where
addNew = H.div { className: "row" } [ addNew = H.div { className: "row" } [
H.span { className: "btn btn-secondary" H.span { className: "btn btn-secondary"
, on: { click: onClickAdd }} [ H.span { className: "fa fa-plus" } [] ] , on: { click: onClickAddChart }} [ H.span { className: "fa fa-plus" } [] ]
] ]
where where
onClickAdd _ = onChange $ A.cons P.CDocsHistogram charts onClickAddChart _ = onChange $ A.cons P.CDocsHistogram charts
chartsEls = A.mapWithIndex chartIdx charts chartsEls = A.mapWithIndex chartIdx charts
chartIdx idx chart = chartIdx idx chart =
renderChart { chart, corpusId, defaultListId, onChange: onChangeChart, onRemove, session } renderChart { chart, corpusId, defaultListId, onChange: onChangeChart, onRemove, session } []
where where
onChangeChart c = do onChangeChart c = do
log2 "[dashboardLayout] idx" idx
log2 "[dashboardLayout] new chart" c
onChange $ fromMaybe charts (A.modifyAt idx (\_ -> c) charts) onChange $ fromMaybe charts (A.modifyAt idx (\_ -> c) charts)
onRemove _ = onChange $ fromMaybe charts $ A.deleteAt idx charts onRemove _ = onChange $ fromMaybe charts $ A.deleteAt idx charts
onClickAddField :: forall e. R.State FTFieldsWithIndex -> e -> Effect Unit
onClickAddField (_ /\ setFieldsS) _ = do
setFieldsS $ \fieldsS -> List.snoc fieldsS $ Tuple (List.length fieldsS) defaultField
type PredefinedChartProps = type PredefinedChartProps =
( chart :: P.PredefinedChart ( chart :: P.PredefinedChart
...@@ -118,14 +153,15 @@ type PredefinedChartProps = ...@@ -118,14 +153,15 @@ type PredefinedChartProps =
, session :: Session , session :: Session
) )
renderChart :: Record PredefinedChartProps -> R.Element renderChart :: R2.Component PredefinedChartProps
renderChart props = R.createElement renderChartCpt props [] renderChart = R.createElement renderChartCpt
renderChartCpt :: R.Component PredefinedChartProps
renderChartCpt = R.hooksComponentWithModule thisModule "renderChart" cpt
where where
renderChartCpt :: R.Component PredefinedChartProps
renderChartCpt = R.hooksComponentWithModule thisModule "renderChart" cpt
cpt { chart, corpusId, defaultListId, onChange, onRemove, session } _ = do cpt { chart, corpusId, defaultListId, onChange, onRemove, session } _ = do
pure $ H.div { className: "chart" } pure $ H.div { className: "row chart card" }
[ H.div { className: "card-header" }
[ H.div { className: "row" } [ H.div { className: "row" }
[ H.div { className: "col-2" } [ H.div { className: "col-2" }
[ R2.select { defaultValue: show chart [ R2.select { defaultValue: show chart
...@@ -137,11 +173,14 @@ renderChartCpt = R.hooksComponentWithModule thisModule "renderChart" cpt ...@@ -137,11 +173,14 @@ renderChartCpt = R.hooksComponentWithModule thisModule "renderChart" cpt
, on: { click: onRemoveClick }} [ H.span { className: "fa fa-trash" } [] ] , on: { click: onRemoveClick }} [ H.span { className: "fa fa-trash" } [] ]
] ]
] ]
, H.div { className: "row" } ]
, H.div { className: "card-body" }
[ H.div { className: "row" }
[ H.div { className: "col-12 chart" } [ H.div { className: "col-12 chart" }
[ P.render chart params ] [ P.render chart params ]
] ]
] ]
]
where where
option pc = option pc =
H.option { value: show pc } [ H.text $ show pc ] H.option { value: show pc } [ H.text $ show pc ]
......
module Gargantext.Components.Nodes.Corpus.Types where module Gargantext.Components.Nodes.Corpus.Types where
import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, (.:), (:=), (~>), jsonEmptyObject) import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, (.:), (:=), (~>), jsonEmptyObject)
import Data.Argonaut.Decode.Error (JsonDecodeError(..))
import Data.List as List import Data.List as List
import Data.Either (Either(..))
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Eq (genericEq)
import Data.Generic.Rep.Show (genericShow)
import Data.Maybe (Maybe(..)) import Data.Maybe (Maybe(..))
import Gargantext.Components.Node (NodePoly) import Gargantext.Components.Node (NodePoly)
import Gargantext.Prelude import Gargantext.Components.Nodes.Types (FTField, Field(..), FieldType(..), isJSON)
import Gargantext.Prelude (bind, pure, ($))
type Author = String
type Description = String
type Query = String
type Tag = String
type Title = String
type HaskellCode = String
type MarkdownText = String
type Hash = String
newtype Hyperdata = newtype Hyperdata =
Hyperdata { fields :: List.List FTField } Hyperdata { fields :: List.List FTField }
...@@ -35,182 +22,6 @@ instance encodeHyperdata :: EncodeJson Hyperdata where ...@@ -35,182 +22,6 @@ instance encodeHyperdata :: EncodeJson Hyperdata where
"fields" := fields "fields" := fields
~> jsonEmptyObject ~> jsonEmptyObject
newtype Field a =
Field { name :: String
, typ :: a
}
type FTField = Field FieldType
derive instance genericFTField :: Generic (Field FieldType) _
instance eqFTField :: Eq (Field FieldType) where
eq = genericEq
instance showFTField :: Show (Field FieldType) where
show = genericShow
data FieldType =
Haskell { haskell :: HaskellCode
, tag :: Tag
}
| Python { python :: HaskellCode
, tag :: Tag
}
| JSON { authors :: Author
, desc :: Description
, query :: Query
, tag :: Tag
, title :: Title
}
| Markdown { tag :: Tag
, text :: MarkdownText
}
isJSON :: FTField -> Boolean
isJSON (Field {typ}) = isJSON' typ
where
isJSON' (JSON _) = true
isJSON' _ = false
getCorpusInfo :: List.List FTField -> CorpusInfo
getCorpusInfo as = case List.head (List.filter isJSON as) of
Just (Field {typ: JSON {authors, desc, query, title}}) -> CorpusInfo { title
, desc
, query
, authors
, totalRecords: 0
}
_ -> CorpusInfo { title:"Empty"
, desc:""
, query:""
, authors:""
, totalRecords: 0
}
derive instance genericFieldType :: Generic FieldType _
instance eqFieldType :: Eq FieldType where
eq = genericEq
instance showFieldType :: Show FieldType where
show = genericShow
instance decodeFTField :: DecodeJson (Field FieldType) where
decodeJson json = do
obj <- decodeJson json
name <- obj .: "name"
type_ <- obj .: "type"
data_ <- obj .: "data"
typ <- case type_ of
"Haskell" -> do
haskell <- data_ .: "haskell"
tag <- data_ .: "tag"
pure $ Haskell {haskell, tag}
"Python" -> do
python <- data_ .: "python"
tag <- data_ .: "tag"
pure $ Python {python, tag}
"JSON" -> do
authors <- data_ .: "authors"
desc <- data_ .: "desc"
query <- data_ .: "query"
tag <- data_ .: "tag"
title <- data_ .: "title"
pure $ JSON {authors, desc, query, tag, title}
"Markdown" -> do
tag <- data_ .: "tag"
text <- data_ .: "text"
pure $ Markdown {tag, text}
_ -> Left $ TypeMismatch $ "Unsupported 'type' " <> type_
pure $ Field {name, typ}
instance encodeFTField :: EncodeJson (Field FieldType) where
encodeJson (Field {name, typ}) =
"data" := typ
~> "name" := name
~> "type" := typ' typ
~> jsonEmptyObject
where
typ' (Haskell _) = "Haskell"
typ' (Python _) = "Python"
typ' (JSON _) = "JSON"
typ' (Markdown _) = "Markdown"
instance encodeFieldType :: EncodeJson FieldType where
encodeJson (Haskell {haskell}) =
"haskell" := haskell
~> "tag" := "HaskellField"
~> jsonEmptyObject
encodeJson (Python {python}) =
"python" := python
~> "tag" := "PythonField"
~> jsonEmptyObject
encodeJson (JSON {authors, desc, query, tag, title}) =
"authors" := authors
~> "desc" := desc
~> "query" := query
~> "tag" := "JsonField"
~> "title" := title
~> jsonEmptyObject
encodeJson (Markdown {text}) =
"tag" := "MarkdownField"
~> "text" := text
~> jsonEmptyObject
defaultPython :: FieldType
defaultPython = Python defaultPython'
defaultPython' :: { python :: String, tag :: String }
defaultPython' = { python: "import Foo"
, tag : "PythonField"
}
defaultHaskell :: FieldType
defaultHaskell = Haskell defaultHaskell'
defaultHaskell' :: { haskell :: String, tag :: String }
defaultHaskell' = { haskell: ""
, tag : "HaskellField"
}
defaultJSON :: FieldType
defaultJSON = JSON defaultJSON'
defaultJSON' :: { authors :: String
, desc :: String
, query :: String
, tag :: String
, title :: String
}
defaultJSON' = { authors: ""
, desc: ""
, query: ""
, tag: "JSONField"
, title: ""
}
defaultMarkdown :: FieldType
defaultMarkdown = Markdown defaultMarkdown'
defaultMarkdown' :: { tag :: String
, text :: String
}
defaultMarkdown' = { tag: "MarkdownField"
, text: "# New file"
}
defaultField :: FTField
defaultField = Field { name: "New file"
, typ: defaultMarkdown
}
newtype CorpusInfo = newtype CorpusInfo =
CorpusInfo { title :: String CorpusInfo { title :: String
, authors :: String , authors :: String
...@@ -232,3 +43,18 @@ instance decodeCorpusInfo :: DecodeJson CorpusInfo where ...@@ -232,3 +43,18 @@ instance decodeCorpusInfo :: DecodeJson CorpusInfo where
type CorpusData = { corpusId :: Int type CorpusData = { corpusId :: Int
, corpusNode :: NodePoly Hyperdata -- CorpusInfo , corpusNode :: NodePoly Hyperdata -- CorpusInfo
, defaultListId :: Int } , defaultListId :: Int }
getCorpusInfo :: List.List FTField -> CorpusInfo
getCorpusInfo as = case List.head (List.filter isJSON as) of
Just (Field {typ: JSON {authors, desc, query, title}}) -> CorpusInfo { title
, desc
, query
, authors
, totalRecords: 0
}
_ -> CorpusInfo { title:"Empty"
, desc:""
, query:""
, authors:""
, totalRecords: 0
}
module Gargantext.Components.Nodes.Dashboard.Types where module Gargantext.Components.Nodes.Dashboard.Types where
import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, (.:), (.:?), (:=), (~>), jsonEmptyObject) import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, (.:), (.:?), (:=), (~>), jsonEmptyObject)
import Data.List as List
import Data.Maybe (Maybe(..)) import Data.Maybe (Maybe(..))
import Effect.Aff (Aff) import Effect.Aff (Aff)
import Gargantext.Components.Nodes.Corpus.Chart.Predefined as P import Gargantext.Components.Nodes.Corpus.Chart.Predefined as P
import Gargantext.Components.Nodes.Types (FTField, Field(..), FieldType(..), isJSON)
import Gargantext.Prelude import Gargantext.Prelude
import Gargantext.Routes (SessionRoute(NodeAPI)) import Gargantext.Routes (SessionRoute(NodeAPI))
import Gargantext.Sessions (Session, get, put) import Gargantext.Sessions (Session, get, put)
...@@ -14,17 +17,20 @@ type Preferences = Maybe String ...@@ -14,17 +17,20 @@ type Preferences = Maybe String
newtype Hyperdata = newtype Hyperdata =
Hyperdata Hyperdata
{ charts :: Array P.PredefinedChart { charts :: Array P.PredefinedChart
, fields :: List.List FTField
, preferences :: Preferences , preferences :: Preferences
} }
instance decodeHyperdata :: DecodeJson Hyperdata where instance decodeHyperdata :: DecodeJson Hyperdata where
decodeJson json = do decodeJson json = do
obj <- decodeJson json obj <- decodeJson json
charts <- obj .: "charts" charts <- obj .: "charts"
fields <- obj .: "fields"
preferences <- obj .:? "preferences" preferences <- obj .:? "preferences"
pure $ Hyperdata {charts, preferences} pure $ Hyperdata {charts, fields, preferences}
instance encodeHyperdata :: EncodeJson Hyperdata where instance encodeHyperdata :: EncodeJson Hyperdata where
encodeJson (Hyperdata {charts, preferences}) = do encodeJson (Hyperdata {charts, fields, preferences}) = do
"charts" := charts "charts" := charts
~> "fields" := fields
~> "preferences" := preferences ~> "preferences" := preferences
~> jsonEmptyObject ~> jsonEmptyObject
......
module Gargantext.Components.Nodes.Types where
import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, (.:), (:=), (~>), jsonEmptyObject)
import Data.Argonaut.Decode.Error (JsonDecodeError(..))
import Data.Either (Either(..))
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Eq (genericEq)
import Data.Generic.Rep.Show (genericShow)
import Data.List as List
import Data.Tuple (Tuple)
import Gargantext.Prelude
type Author = String
type Description = String
type HaskellCode = String
type Hash = String
type MarkdownText = String
type Query = String
type Tag = String
type Title = String
-- We need FTFields with indices because it's the only way to identify the
-- FTField element inside a component (there are no UUIDs and such)
type Index = Int
type FTFieldWithIndex = Tuple Index FTField
type FTFieldsWithIndex = List.List FTFieldWithIndex
newtype Field a =
Field { name :: String
, typ :: a
}
type FTField = Field FieldType
derive instance genericFTField :: Generic (Field FieldType) _
instance eqFTField :: Eq (Field FieldType) where
eq = genericEq
instance showFTField :: Show (Field FieldType) where
show = genericShow
data FieldType =
Haskell { haskell :: HaskellCode
, tag :: Tag
}
| Python { python :: HaskellCode
, tag :: Tag
}
| JSON { authors :: Author
, desc :: Description
, query :: Query
, tag :: Tag
, title :: Title
}
| Markdown { tag :: Tag
, text :: MarkdownText
}
isJSON :: FTField -> Boolean
isJSON (Field {typ}) = isJSON' typ
where
isJSON' (JSON _) = true
isJSON' _ = false
derive instance genericFieldType :: Generic FieldType _
instance eqFieldType :: Eq FieldType where
eq = genericEq
instance showFieldType :: Show FieldType where
show = genericShow
instance decodeFTField :: DecodeJson (Field FieldType) where
decodeJson json = do
obj <- decodeJson json
name <- obj .: "name"
type_ <- obj .: "type"
data_ <- obj .: "data"
typ <- case type_ of
"Haskell" -> do
haskell <- data_ .: "haskell"
tag <- data_ .: "tag"
pure $ Haskell {haskell, tag}
"Python" -> do
python <- data_ .: "python"
tag <- data_ .: "tag"
pure $ Python {python, tag}
"JSON" -> do
authors <- data_ .: "authors"
desc <- data_ .: "desc"
query <- data_ .: "query"
tag <- data_ .: "tag"
title <- data_ .: "title"
pure $ JSON {authors, desc, query, tag, title}
"Markdown" -> do
tag <- data_ .: "tag"
text <- data_ .: "text"
pure $ Markdown {tag, text}
_ -> Left $ TypeMismatch $ "Unsupported 'type' " <> type_
pure $ Field {name, typ}
instance encodeFTField :: EncodeJson (Field FieldType) where
encodeJson (Field {name, typ}) =
"data" := typ
~> "name" := name
~> "type" := typ' typ
~> jsonEmptyObject
where
typ' (Haskell _) = "Haskell"
typ' (Python _) = "Python"
typ' (JSON _) = "JSON"
typ' (Markdown _) = "Markdown"
instance encodeFieldType :: EncodeJson FieldType where
encodeJson (Haskell {haskell}) =
"haskell" := haskell
~> "tag" := "HaskellField"
~> jsonEmptyObject
encodeJson (Python {python}) =
"python" := python
~> "tag" := "PythonField"
~> jsonEmptyObject
encodeJson (JSON {authors, desc, query, tag, title}) =
"authors" := authors
~> "desc" := desc
~> "query" := query
~> "tag" := "JsonField"
~> "title" := title
~> jsonEmptyObject
encodeJson (Markdown {text}) =
"tag" := "MarkdownField"
~> "text" := text
~> jsonEmptyObject
defaultPython :: FieldType
defaultPython = Python defaultPython'
defaultPython' :: { python :: String, tag :: String }
defaultPython' = { python: "import Foo"
, tag : "PythonField"
}
defaultHaskell :: FieldType
defaultHaskell = Haskell defaultHaskell'
defaultHaskell' :: { haskell :: String, tag :: String }
defaultHaskell' = { haskell: ""
, tag : "HaskellField"
}
defaultJSON :: FieldType
defaultJSON = JSON defaultJSON'
defaultJSON' :: { authors :: String
, desc :: String
, query :: String
, tag :: String
, title :: String
}
defaultJSON' = { authors: ""
, desc: ""
, query: ""
, tag: "JSONField"
, title: ""
}
defaultMarkdown :: FieldType
defaultMarkdown = Markdown defaultMarkdown'
defaultMarkdown' :: { tag :: String
, text :: String
}
defaultMarkdown' = { tag: "MarkdownField"
, text: "# New file"
}
defaultField :: FTField
defaultField = Field { name: "New file"
, typ: defaultMarkdown
}
...@@ -20,24 +20,16 @@ ...@@ -20,24 +20,16 @@
word-break: keep-all word-break: keep-all
.code-editor-heading .code-editor-heading
display: flex
//justify-content: space-between
.renameable .renameable
flex-grow: 2 flex-grow: 2
.text .text
padding-right: 10px padding-right: 10px
.buttons-right /* .buttons-right
display: flex /* display: flex
justify-content: flex-end /* justify-content: flex-end
.code-editor .code-editor
.toolbar
display: flex
justify-content: flex-start
width: 100%
.editor .editor
display: flex
width: 100%
.code-area .code-area
flex-grow: 1 flex-grow: 1
max-height: 200px max-height: 200px
......
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