Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
purescript-gargantext
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Grégoire Locqueville
purescript-gargantext
Commits
954a886c
Commit
954a886c
authored
Jan 26, 2021
by
Przemyslaw Kaminski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[dashboard] add code editor to dashboard, fix styling
parent
49179955
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
416 additions
and
377 deletions
+416
-377
sass.css
dist/styles/sass.css
+3
-14
sass.css.map
dist/styles/sass.css.map
+1
-1
App.purs
src/Gargantext/Components/App.purs
+1
-1
CodeEditor.purs
src/Gargantext/Components/CodeEditor.purs
+28
-26
InputWithEnter.purs
src/Gargantext/Components/InputWithEnter.purs
+4
-1
Corpus.purs
src/Gargantext/Components/Nodes/Corpus.purs
+75
-82
Dashboard.purs
src/Gargantext/Components/Nodes/Corpus/Dashboard.purs
+87
-48
Types.purs
src/Gargantext/Components/Nodes/Corpus/Types.purs
+17
-191
Types.purs
src/Gargantext/Components/Nodes/Dashboard/Types.purs
+8
-2
Types.purs
src/Gargantext/Components/Nodes/Types.purs
+189
-0
_code_editor.sass
src/sass/_code_editor.sass
+3
-11
No files found.
dist/styles/sass.css
View file @
954a886c
...
@@ -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
;
...
...
dist/styles/sass.css.map
View file @
954a886c
{"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
src/Gargantext/Components/App.purs
View file @
954a886c
...
@@ -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 $
...
...
src/Gargantext/Components/CodeEditor.purs
View file @
954a886c
...
@@ -117,25 +117,24 @@ codeEditorCpt = R.hooksComponentWithModule thisModule "codeEditor" cpt
...
@@ -117,25 +117,24 @@ 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 } [ ]
, H.pre { className: (langClass $ fst controls.codeType)
, H.pre { className: (langClass $ fst controls.codeType)
-- , contentEditable: "true"
-- , contentEditable: "true"
, ref: controls.codeOverlayElRef
, ref: controls.codeOverlayElRef
, rows: 30
, rows: 30
--, on: { input: onEditChange (fst codeType) codeElRef htmlRef codeRef error }
--, on: { input: onEditChange (fst codeType) codeElRef htmlRef codeRef error }
} []
} []
]
]
]
]
, H.div { className: "v-divider " <> (dividerHidden $ fst controls.viewType) } [ H.text " " ]
, H.div { className: "v-divider " <> (dividerHidden $ fst controls.viewType) } [ H.text " " ]
, H.div { className: "html " <> (langClass $ fst controls.codeType) <> (previewHidden $ fst controls.viewType)
, H.div { className: "html " <> (langClass $ fst controls.codeType) <> (previewHidden $ fst controls.viewType)
...
@@ -208,13 +207,16 @@ toolbarCpt = R.hooksComponentWithModule thisModule "toolbar" cpt
...
@@ -208,13 +207,16 @@ 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" }
codeType
[ codeTypeSelector {
, onChange: onChangeCodeType props
codeType
}
, 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
onChangeCodeType :: forall e. Record ToolbarProps -> e -> Effect Unit
onChangeCodeType :: forall e. Record ToolbarProps -> e -> Effect Unit
...
...
src/Gargantext/Components/InputWithEnter.purs
View file @
954a886c
...
@@ -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
onValueChanged $ R.unsafeEventValue e
if autoSave then
onValueChanged $ R.unsafeEventValue e
else
pure unit
onKeyPress e = do
onKeyPress e = do
char <- R2.keyCode e
char <- R2.keyCode e
...
...
src/Gargantext/Components/Nodes/Corpus.purs
View file @
954a886c
...
@@ -21,7 +21,8 @@ import Gargantext.Prelude
...
@@ -21,7 +21,8 @@ import Gargantext.Prelude
import Gargantext.Components.CodeEditor as CE
import Gargantext.Components.CodeEditor as CE
import Gargantext.Components.InputWithEnter (inputWithEnter)
import Gargantext.Components.InputWithEnter (inputWithEnter)
import Gargantext.Components.Node (NodePoly(..), HyperdataList)
import Gargantext.Components.Node (NodePoly(..), HyperdataList)
import Gargantext.Components.Nodes.Corpus.Types (CorpusData, FTField, Field(..), FieldType(..), Hash, Hyperdata(..), defaultField, defaultHaskell', defaultPython', defaultJSON', defaultMarkdown')
import Gargantext.Components.Nodes.Types
import Gargantext.Components.Nodes.Corpus.Types (CorpusData, Hyperdata(..))
import Gargantext.Data.Array as GDA
import Gargantext.Data.Array as GDA
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Routes (SessionRoute(NodeAPI, Children))
import Gargantext.Routes (SessionRoute(NodeAPI, Children))
...
@@ -46,10 +47,10 @@ type KeyProps =
...
@@ -46,10 +47,10 @@ type KeyProps =
corpusLayout :: Record Props -> R.Element
corpusLayout :: Record Props -> R.Element
corpusLayout props = R.createElement corpusLayoutCpt props []
corpusLayout props = R.createElement corpusLayoutCpt props []
corpusLayoutCpt :: R.Component Props
corpusLayoutCpt = R.hooksComponentWithModule thisModule "corpusLayout" cpt
where
where
corpusLayoutCpt :: R.Component Props
corpusLayoutCpt = R.hooksComponentWithModule thisModule "corpusLayout" cpt
cpt { nodeId, session } _ = do
cpt { nodeId, session } _ = do
let sid = sessionId session
let sid = sessionId session
...
@@ -58,10 +59,10 @@ corpusLayoutCpt = R.hooksComponentWithModule thisModule "corpusLayout" cpt
...
@@ -58,10 +59,10 @@ corpusLayoutCpt = R.hooksComponentWithModule thisModule "corpusLayout" cpt
corpusLayoutWithKey :: Record KeyProps -> R.Element
corpusLayoutWithKey :: Record KeyProps -> R.Element
corpusLayoutWithKey props = R.createElement corpusLayoutWithKeyCpt props []
corpusLayoutWithKey props = R.createElement corpusLayoutWithKeyCpt props []
corpusLayoutWithKeyCpt :: R.Component KeyProps
corpusLayoutWithKeyCpt = R.hooksComponentWithModule thisModule "corpusLayoutWithKey" cpt
where
where
corpusLayoutWithKeyCpt :: R.Component KeyProps
corpusLayoutWithKeyCpt = R.hooksComponentWithModule thisModule "corpusLayoutWithKey" cpt
cpt { nodeId, session } _ = do
cpt { nodeId, session } _ = do
reload <- GUR.new
reload <- GUR.new
...
@@ -74,18 +75,12 @@ type ViewProps =
...
@@ -74,18 +75,12 @@ type ViewProps =
| Props
| Props
)
)
-- 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
corpusLayoutView :: Record ViewProps -> R.Element
corpusLayoutView :: Record ViewProps -> R.Element
corpusLayoutView props = R.createElement corpusLayoutViewCpt props []
corpusLayoutView props = R.createElement corpusLayoutViewCpt props []
corpusLayoutViewCpt :: R.Component ViewProps
corpusLayoutViewCpt = R.hooksComponentWithModule thisModule "corpusLayoutView" cpt
where
where
corpusLayoutViewCpt :: R.Component ViewProps
corpusLayoutViewCpt = R.hooksComponentWithModule thisModule "corpusLayoutView" cpt
cpt {corpus: (NodePoly {hyperdata: Hyperdata {fields}}), nodeId, reload, session} _ = do
cpt {corpus: (NodePoly {hyperdata: Hyperdata {fields}}), nodeId, reload, session} _ = do
let fieldsWithIndex = List.mapWithIndex (\idx -> \t -> Tuple idx t) fields
let fieldsWithIndex = List.mapWithIndex (\idx -> \t -> Tuple idx t) fields
fieldsS <- R.useState' fieldsWithIndex
fieldsS <- R.useState' fieldsWithIndex
...
@@ -99,24 +94,25 @@ corpusLayoutViewCpt = R.hooksComponentWithModule thisModule "corpusLayoutView" c
...
@@ -99,24 +94,25 @@ corpusLayoutViewCpt = R.hooksComponentWithModule thisModule "corpusLayoutView" c
R.setRef fieldsRef fields
R.setRef fieldsRef fields
snd fieldsS $ const fieldsWithIndex
snd fieldsS $ const fieldsWithIndex
pure $ H.div {} [
pure $ H.div {}
H.div { className: "row" } [
[ H.div { className: "row" }
H.div { className: "btn btn-secondary " <> (saveEnabled fieldsWithIndex fieldsS)
[ H.div { className: "btn btn-secondary " <> (saveEnabled fieldsWithIndex fieldsS)
, on: { click: onClickSave {fields: fieldsS, nodeId, reload, session} }
, on: { click: onClickSave {fields: fieldsS, nodeId, reload, session} }
} [
}
H.span { className: "fa fa-floppy-o" } [ ]
[ H.span { className: "fa fa-floppy-o" } [ ]
]
]
]
]
, H.div {} [ fieldsCodeEditor { fields: fieldsS
, H.div {}
, nodeId
[ fieldsCodeEditor { fields: fieldsS
, session } ]
, nodeId
, H.div { className: "row" } [
, session } ]
H.div { className: "btn btn-secondary"
, H.div { className: "row" }
, on: { click: onClickAdd fieldsS }
[ H.div { className: "btn btn-secondary"
} [
, on: { click: onClickAdd fieldsS }
H.span { className: "fa fa-plus" } [ ]
}
]
[ H.span { className: "fa fa-plus" } [ ]
]
]
]
]
]
saveEnabled :: FTFieldsWithIndex -> R.State FTFieldsWithIndex -> String
saveEnabled :: FTFieldsWithIndex -> R.State FTFieldsWithIndex -> String
...
@@ -127,7 +123,6 @@ corpusLayoutViewCpt = R.hooksComponentWithModule thisModule "corpusLayoutView" c
...
@@ -127,7 +123,6 @@ corpusLayoutViewCpt = R.hooksComponentWithModule thisModule "corpusLayoutView" c
, reload :: GUR.ReloadS
, reload :: GUR.ReloadS
, session :: Session } -> e -> Effect Unit
, session :: Session } -> e -> Effect Unit
onClickSave {fields: (fieldsS /\ _), nodeId, reload, session} _ = do
onClickSave {fields: (fieldsS /\ _), nodeId, reload, session} _ = do
log2 "[corpusLayoutViewCpt] onClickSave fieldsS" fieldsS
launchAff_ do
launchAff_ do
saveCorpus $ { hyperdata: Hyperdata {fields: (\(Tuple _ f) -> f) <$> fieldsS}
saveCorpus $ { hyperdata: Hyperdata {fields: (\(Tuple _ f) -> f) <$> fieldsS}
, nodeId
, nodeId
...
@@ -146,10 +141,10 @@ type FieldsCodeEditorProps =
...
@@ -146,10 +141,10 @@ type FieldsCodeEditorProps =
fieldsCodeEditor :: Record FieldsCodeEditorProps -> R.Element
fieldsCodeEditor :: Record FieldsCodeEditorProps -> R.Element
fieldsCodeEditor props = R.createElement fieldsCodeEditorCpt props []
fieldsCodeEditor props = R.createElement fieldsCodeEditorCpt props []
fieldsCodeEditorCpt :: R.Component FieldsCodeEditorProps
fieldsCodeEditorCpt = R.hooksComponentWithModule thisModule "fieldsCodeEditorCpt" cpt
where
where
fieldsCodeEditorCpt :: R.Component FieldsCodeEditorProps
fieldsCodeEditorCpt = R.hooksComponentWithModule thisModule "fieldsCodeEditorCpt" cpt
cpt {nodeId, fields: fS@(fields /\ _), session} _ = do
cpt {nodeId, fields: fS@(fields /\ _), session} _ = do
masterKey <- R.useState' 0
masterKey <- R.useState' 0
...
@@ -215,27 +210,25 @@ type FieldCodeEditorProps =
...
@@ -215,27 +210,25 @@ type FieldCodeEditorProps =
fieldCodeEditorWrapper :: Record FieldCodeEditorProps -> R.Element
fieldCodeEditorWrapper :: Record FieldCodeEditorProps -> R.Element
fieldCodeEditorWrapper props = R.createElement fieldCodeEditorWrapperCpt props []
fieldCodeEditorWrapper props = R.createElement fieldCodeEditorWrapperCpt props []
fieldCodeEditorWrapperCpt :: R.Component FieldCodeEditorProps
fieldCodeEditorWrapperCpt = R.hooksComponentWithModule thisModule "fieldCodeEditorWrapperCpt" cpt
where
where
fieldCodeEditorWrapperCpt :: R.Component FieldCodeEditorProps
fieldCodeEditorWrapperCpt = R.hooksComponentWithModule thisModule "fieldCodeEditorWrapperCpt" cpt
cpt props@{canMoveDown, canMoveUp, field: Field {name, typ}, onMoveDown, onMoveUp, onRemove, onRename} _ = do
cpt props@{canMoveDown, canMoveUp, field: Field {name, typ}, onMoveDown, onMoveUp, onRemove, onRename} _ = do
pure $ H.div { className: "row card" } [
pure $ H.div { className: "row card" } [
H.div { className: "card-header" } [
H.div { className: "card-header" } [
H.div { className: "code-editor-heading row" } [
H.div { className: "code-editor-heading row" } [
H.div { className: "col-
sm-
4" } [
H.div { className: "col-4" } [
renameable {onRename, text: name}
renameable {onRename, text: name}
]
]
, H.div { className: "col-
sm-
7" } []
, H.div { className: "col-7" } []
, H.div { className: "buttons-right col-
sm-1" }
[
, H.div { className: "buttons-right col-
1" } (
[
H.div { className: "btn btn-danger"
H.div { className: "btn btn-danger"
, on: { click: \_ -> onRemove unit }
, on: { click: \_ -> onRemove unit }
} [
} [
H.span { className: "fa fa-trash" } [ ]
H.span { className: "fa fa-trash" } [ ]
]
]
, moveDownButton canMoveDown
] <> moveButtons)
, moveUpButton canMoveUp
]
]
]
]
]
, H.div { className: "card-body" } [
, H.div { className: "card-body" } [
...
@@ -243,15 +236,15 @@ fieldCodeEditorWrapperCpt = R.hooksComponentWithModule thisModule "fieldCodeEdit
...
@@ -243,15 +236,15 @@ fieldCodeEditorWrapperCpt = R.hooksComponentWithModule thisModule "fieldCodeEdit
]
]
]
]
where
where
moveDownButton false = H.div {} []
moveButtons = [] <> (if canMoveDown then [moveDownButton] else [])
moveDownButton true =
<> (if canMoveUp then [moveUpButton] else [])
moveDownButton =
H.div { className: "btn btn-secondary"
H.div { className: "btn btn-secondary"
, on: { click: \_ -> onMoveDown unit }
, on: { click: \_ -> onMoveDown unit }
} [
} [
H.span { className: "fa fa-arrow-down" } [ ]
H.span { className: "fa fa-arrow-down" } [ ]
]
]
moveUpButton false = H.div {} []
moveUpButton =
moveUpButton true =
H.div { className: "btn btn-secondary"
H.div { className: "btn btn-secondary"
, on: { click: \_ -> onMoveUp unit }
, on: { click: \_ -> onMoveUp unit }
} [
} [
...
@@ -266,10 +259,10 @@ type RenameableProps =
...
@@ -266,10 +259,10 @@ type RenameableProps =
renameable :: Record RenameableProps -> R.Element
renameable :: Record RenameableProps -> R.Element
renameable props = R.createElement renameableCpt props []
renameable props = R.createElement renameableCpt props []
renameableCpt :: R.Component RenameableProps
renameableCpt = R.hooksComponentWithModule thisModule "renameableCpt" cpt
where
where
renameableCpt :: R.Component RenameableProps
renameableCpt = R.hooksComponentWithModule thisModule "renameableCpt" cpt
cpt {onRename, text} _ = do
cpt {onRename, text} _ = do
isEditing <- R.useState' false
isEditing <- R.useState' false
state <- R.useState' text
state <- R.useState' text
...
@@ -296,37 +289,37 @@ type RenameableTextProps =
...
@@ -296,37 +289,37 @@ type RenameableTextProps =
renameableText :: Record RenameableTextProps -> R.Element
renameableText :: Record RenameableTextProps -> R.Element
renameableText props = R.createElement renameableTextCpt props []
renameableText props = R.createElement renameableTextCpt props []
renameableTextCpt :: R.Component RenameableTextProps
renameableTextCpt = R.hooksComponentWithModule thisModule "renameableTextCpt" cpt
where
where
renameableTextCpt :: R.Component RenameableTextProps
renameableTextCpt = R.hooksComponentWithModule thisModule "renameableTextCpt" cpt
cpt {isEditing: (false /\ setIsEditing), state: (text /\ _)} _ = do
cpt {isEditing: (false /\ setIsEditing), state: (text /\ _)} _ = do
pure $ H.div { className: "input-group" }
[
pure $ H.div { className: "input-group" }
H.input { className: "form-control"
[
H.input { className: "form-control"
, defaultValue: text
, defaultValue: text
, disabled: 1
, disabled: 1
, type: "text" }
, type: "text" }
, H.div { className: "btn input-group-append"
, H.div { className: "btn input-group-append"
, on: { click: \_ -> setIsEditing $ const true } }
[
, on: { click: \_ -> setIsEditing $ const true } }
H.span { className: "fa fa-pencil" } []
[
H.span { className: "fa fa-pencil" } []
]
]
]
]
cpt {isEditing: (true /\ setIsEditing), onRename, state: (text /\ setText)} _ = do
cpt {isEditing: (true /\ setIsEditing), onRename, state: (text /\ setText)} _ = do
pure $ H.div { className: "input-group" }
[
pure $ H.div { className: "input-group" }
inputWithEnter {
[
inputWithEnter {
autoFocus: false
autoFocus: false
, autoSave: false
, autoSave: false
, className: "form-control text"
, className: "form-control text"
, defaultValue: text
, defaultValue: text
, onEnter: submit
, onEnter: submit
, onValueChanged: setText <<< const
, onValueChanged: setText <<< const
, placeholder: ""
, placeholder: ""
, type: "text"
, type: "text"
}
}
, H.div { className: "btn input-group-append"
, H.div { className: "btn input-group-append"
, on: { click: submit } } [
, on: { click: submit } }
H.span { className: "fa fa-floppy-o" } []
[
H.span { className: "fa fa-floppy-o" } []
]
]
]
]
where
where
submit _ = do
submit _ = do
...
@@ -335,10 +328,10 @@ renameableTextCpt = R.hooksComponentWithModule thisModule "renameableTextCpt" cp
...
@@ -335,10 +328,10 @@ renameableTextCpt = R.hooksComponentWithModule thisModule "renameableTextCpt" cp
fieldCodeEditor :: Record FieldCodeEditorProps -> R.Element
fieldCodeEditor :: Record FieldCodeEditorProps -> R.Element
fieldCodeEditor props = R.createElement fieldCodeEditorCpt props []
fieldCodeEditor props = R.createElement fieldCodeEditorCpt props []
fieldCodeEditorCpt :: R.Component FieldCodeEditorProps
fieldCodeEditorCpt = R.hooksComponentWithModule thisModule "fieldCodeEditorCpt" cpt
where
where
fieldCodeEditorCpt :: R.Component FieldCodeEditorProps
fieldCodeEditorCpt = R.hooksComponentWithModule thisModule "fieldCodeEditorCpt" cpt
cpt {field: Field {typ: typ@(Haskell {haskell})}, onChange} _ = do
cpt {field: Field {typ: typ@(Haskell {haskell})}, onChange} _ = do
pure $ CE.codeEditor {code: haskell, defaultCodeType: CE.Haskell, onChange: changeCode onChange typ}
pure $ CE.codeEditor {code: haskell, defaultCodeType: CE.Haskell, onChange: changeCode onChange typ}
...
...
src/Gargantext/Components/Nodes/Corpus/Dashboard.purs
View file @
954a886c
...
@@ -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" ]
, H.p {} [ H.text "Summary of all your charts here" ]
cpt props@{ charts, corpusId, defaultListId, fields, nodeId, onChange, session } _ = do
] <> chartsEls <> [addNew])
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" ]
] <> 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: onClickAdd
Chart
}} [ H.span { className: "fa fa-plus" } [] ]
]
]
where
where
onClickAdd _ = onChange $ A.cons P.CDocsHistogram charts
onClickAdd
Chart
_ = 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,28 +153,32 @@ type PredefinedChartProps =
...
@@ -118,28 +153,32 @@ 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: "row" }
[ H.div { className: "card-header" }
[ H.div { className: "col-2" }
[ H.div { className: "row" }
[ R2.select { defaultValue: show chart
[ H.div { className: "col-2" }
, on: { change: onSelectChange }
[ R2.select { defaultValue: show chart
} (option <$> P.allPredefinedCharts)
, on: { change: onSelectChange }
]
} (option <$> P.allPredefinedCharts)
, H.div { className: "col-1" }
]
[ H.span { className: "btn btn-danger"
, H.div { className: "col-1" }
, on: { click: onRemoveClick }} [ H.span { className: "fa fa-trash" } [] ]
[ H.span { className: "btn btn-danger"
, on: { click: onRemoveClick }} [ H.span { className: "fa fa-trash" } [] ]
]
]
]
]
]
, H.div { className: "row" }
, H.div { className: "card-body" }
[ H.div { className: "col-12 chart" }
[ H.div { className: "row" }
[ P.render chart params ]
[ H.div { className: "col-12 chart" }
[ P.render chart params ]
]
]
]
]
]
where
where
...
...
src/Gargantext/Components/Nodes/Corpus/Types.purs
View file @
954a886c
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
}
src/Gargantext/Components/Nodes/Dashboard/Types.purs
View file @
954a886c
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
...
...
src/Gargantext/Components/Nodes/Types.purs
0 → 100644
View file @
954a886c
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
}
src/sass/_code_editor.sass
View file @
954a886c
...
@@ -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
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment