diff --git a/dist/styles/sass.css b/dist/styles/sass.css index d6d6824e0f996be79db3c209a8fc1a1b6f3cd46d..ee7d844fb044e5c45ccd41bfab4032e84a9b3fee 100644 --- a/dist/styles/sass.css +++ b/dist/styles/sass.css @@ -533,7 +533,9 @@ li .leaf:hover a.settings { } .code-editor-heading { - display: flex; + /* .buttons-right */ + /* display: flex */ + /* justify-content: flex-end */ } .code-editor-heading .renameable { flex-grow: 2; @@ -541,20 +543,7 @@ li .leaf:hover a.settings { .code-editor-heading .renameable .text { 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 { flex-grow: 1; max-height: 200px; @@ -785,4 +774,49 @@ ul li { width: 85%; } +.annotation-run { + cursor: pointer; +} +.annotation-run.candidate-term.graph-term.stop-term { + color: #000; + background-image: linear-gradient(rgba(184, 184, 184, 0.34), rgba(184, 184, 184, 0.34)), linear-gradient(rgba(149, 210, 149, 0.33), rgba(149, 210, 149, 0.33)), linear-gradient(rgba(245, 148, 153, 0.33), rgba(245, 148, 153, 0.33)); +} +.annotation-run.candidate-term.graph-term { + color: #000; + background-image: linear-gradient(rgba(184, 184, 184, 0.5), rgba(184, 184, 184, 0.5)), linear-gradient(rgba(149, 210, 149, 0.5), rgba(149, 210, 149, 0.5)); +} +.annotation-run.candidate-term.stop-term { + color: #000; + background-image: linear-gradient(rgba(184, 184, 184, 0.5), rgba(184, 184, 184, 0.5)), linear-gradient(rgba(245, 148, 153, 0.5), rgba(245, 148, 153, 0.5)); +} +.annotation-run.graph-term.stop-term { + color: #000; + background-image: linear-gradient(rgba(149, 210, 149, 0.5), rgba(149, 210, 149, 0.5)), linear-gradient(rgba(245, 148, 153, 0.5), rgba(245, 148, 153, 0.5)); +} +.annotation-run.candidate-term { + color: #000; + background-color: #B8B8B876; +} +.annotation-run.graph-term { + color: #000; + background-color: #95D29593; +} +.annotation-run.stop-term { + color: #000; + background-color: #F5949931; +} + +.context-menu .candidate-term { + color: #000; + background-color: #B8B8B876; +} +.context-menu .graph-term { + color: #000; + background-color: #95D29593; +} +.context-menu .stop-term { + color: #000; + background-color: #F5949931; +} + /*# sourceMappingURL=sass.css.map */ diff --git a/dist/styles/sass.css.map b/dist/styles/sass.css.map index ecb8c902e4b8d9221c5a09f5cc009d13f47bcd5d..262a40602d9283b54edb588061d04f83ee555c8c 100644 --- a/dist/styles/sass.css.map +++ b/dist/styles/sass.css.map @@ -1 +1 @@ -{"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;;;AAEF;AAGI;EACE;;AACF;EACE;;;AAEN;EACE;EACA;EACA;;;AAIA;EACE;;AACF;EACE;;;ACtEJ;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 +{"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","../../src/sass/_annotation.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;;;AAEF;AAGI;EACE;;AACF;EACE;;;AAEN;EACE;EACA;EACA;;;AAIA;EACE;;AACF;EACE;;;ACtEJ;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;;;ACzBJ;EACE;;AAEA;EANE;EACA;;AAQF;EAbE;EACA;;AAeF;EAhBE;EACA;;AAkBF;EAnBE;EACA;;AAqBF;EA1BE;EACA,kBALyB;;AAiC3B;EA7BE;EACA,kBANqB;;AAqCvB;EAhCE;EACA,kBAJoB;;;AAuCtB;EApCE;EACA,kBALyB;;AA2C3B;EAvCE;EACA,kBANqB;;AA+CvB;EA1CE;EACA,kBAJoB","file":"sass.css"} \ No newline at end of file diff --git a/package.json b/package.json index 88741745062e09f8f348290a05703abf03e643b8..ad63370c36539a5545c42cf6076a06c8c0590daf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Gargantext", - "version": "0.0.2.6", + "version": "0.0.2.7", "scripts": { "rebase-set": "spago package-set-upgrade && spago psc-package-insdhall", "rebuild-set": "spago psc-package-insdhall", diff --git a/src/Gargantext/Components/Annotation/AnnotatedField.purs b/src/Gargantext/Components/Annotation/AnnotatedField.purs index d01156826a2e2ad0bf97e44b7daae178470a6eb4..25f666b37a1a5d70524a183f46205b28d8cfc4e0 100644 --- a/src/Gargantext/Components/Annotation/AnnotatedField.purs +++ b/src/Gargantext/Components/Annotation/AnnotatedField.purs @@ -23,7 +23,7 @@ import Reactix.DOM.HTML as HTML import Reactix.SyntheticEvent as E import Gargantext.Types (CTabNgramType(..), TermList) -import Gargantext.Components.Annotation.Utils ( termBootstrapClass ) +import Gargantext.Components.Annotation.Utils ( termBootstrapClass, termClass ) import Gargantext.Components.NgramsTable.Core import Gargantext.Components.Annotation.Menu ( annotationMenu, MenuType(..) ) import Gargantext.Utils.Selection as Sel @@ -131,6 +131,7 @@ annotatedRunComponent = R.staticComponent "AnnotatedRun" cpt elt = case list of Nothing -> HTML.span { on: { mouseUp: cb } } - Just l -> HTML.span { className: "annotation-run bg-" <> termBootstrapClass l + Just l -> HTML.span { -- className: "annotation-run bg-" <> termBootstrapClass l + className: "annotation-run " <> termClass l , on: { click: cb } } diff --git a/src/Gargantext/Components/App.purs b/src/Gargantext/Components/App.purs index 070f022db274819d7c020de809a0f6db97065e3a..807359d00e39378896b921dcd4eea5515a21b60c 100644 --- a/src/Gargantext/Components/App.purs +++ b/src/Gargantext/Components/App.purs @@ -13,7 +13,8 @@ import Gargantext.Components.GraphExplorer (explorerLayout) import Gargantext.Components.Lang (LandingLang(..)) import Gargantext.Components.Login (login) import Gargantext.Components.Nodes.Annuaire (annuaireLayout) -import Gargantext.Components.Nodes.Annuaire.User.Contacts (annuaireUserLayout, userLayout) +import Gargantext.Components.Nodes.Annuaire.User (userLayout) +import Gargantext.Components.Nodes.Annuaire.User.Contact (contactLayout) import Gargantext.Components.Nodes.Corpus (corpusLayout) import Gargantext.Components.Nodes.Corpus.Dashboard (dashboardLayout) import Gargantext.Components.Nodes.Corpus.Document (documentMainLayout) @@ -101,17 +102,6 @@ appCpt = R.hooksComponentWithModule thisModule "app" cpt where Annuaire sid nodeId -> withSession sid $ \session -> forested [ annuaireLayout { frontends, nodeId, session } ] - ContactPage sid aId nodeId -> withSession sid $ \session -> forested [ - annuaireUserLayout { - annuaireId: aId - , appReload - , asyncTasksRef - , frontends - , nodeId - , session - , treeReloadRef - } - ] Corpus sid nodeId -> withSession sid $ \session -> forested [ corpusLayout { nodeId, session } ] @@ -119,7 +109,7 @@ appCpt = R.hooksComponentWithModule thisModule "app" cpt where documentMainLayout { listId, mCorpusId: Just corpusId, nodeId, session } [] ] Dashboard sid nodeId -> withSession sid $ \session -> forested [ - dashboardLayout { nodeId, session } + dashboardLayout { nodeId, session } [] ] Document sid listId nodeId -> withSession sid $ @@ -204,6 +194,8 @@ appCpt = R.hooksComponentWithModule thisModule "app" cpt where , sessionUpdate } } [] +---------------------------------------------------------------------------------------- +-- | TODO refact UserPage and ContactPage UserPage sid nodeId -> withSession sid $ \session -> forested [ userLayout { appReload @@ -214,3 +206,17 @@ appCpt = R.hooksComponentWithModule thisModule "app" cpt where , treeReloadRef } ] + + ContactPage sid aId nodeId -> withSession sid $ \session -> forested [ + contactLayout { + annuaireId: aId + , appReload + , asyncTasksRef + , frontends + , nodeId + , session + , treeReloadRef + } + ] + + diff --git a/src/Gargantext/Components/CodeEditor.purs b/src/Gargantext/Components/CodeEditor.purs index 2d9df1bdbc1c085c345abe8b08006ecdef40750a..699ab3ebb76fa214f368d29819387b1ef366e52b 100644 --- a/src/Gargantext/Components/CodeEditor.purs +++ b/src/Gargantext/Components/CodeEditor.purs @@ -24,6 +24,7 @@ import Gargantext.Prelude import Gargantext.Utils.HighlightJS as HLJS import Gargantext.Utils.Reactix as R2 +thisModule :: String thisModule = "Gargantext.Components.CodeEditor" type Code = String @@ -117,25 +118,24 @@ codeEditorCpt = R.hooksComponentWithModule thisModule "codeEditor" cpt setCodeOverlay controls code' renderHtml code' controls - pure $ H.div { className: "code-editor" } [ - toolbar {controls, onChange} - , H.div { className: "row error" } [ - errorComponent {error: controls.error} - ] - , H.div { className: "row editor" } [ - H.div { className: "code-area " <> (codeHidden $ fst controls.viewType) } [ - H.div { className: "code-container" } [ - H.textarea { defaultValue: code - , on: { change: onEditChange controls onChange } - , placeholder: "Type some code..." - , ref: controls.codeElRef } [ ] - , H.pre { className: (langClass $ fst controls.codeType) - -- , contentEditable: "true" - , ref: controls.codeOverlayElRef - , rows: 30 - --, on: { input: onEditChange (fst codeType) codeElRef htmlRef codeRef error } - } [] - ] + pure $ H.div { className: "code-editor" } + [ toolbar {controls, onChange} + , H.div { className: "row error" } + [ errorComponent {error: controls.error} ] + , H.div { className: "row editor" } + [ H.div { className: "code-area " <> (codeHidden $ fst controls.viewType) } + [ H.div { className: "code-container" } + [ H.textarea { defaultValue: code + , on: { change: onEditChange controls onChange } + , placeholder: "Type some code..." + , ref: controls.codeElRef } [ ] + , H.pre { className: (langClass $ fst controls.codeType) + -- , contentEditable: "true" + , ref: controls.codeOverlayElRef + , rows: 30 + --, on: { input: onEditChange (fst codeType) codeElRef htmlRef codeRef error } + } [] + ] ] , H.div { className: "v-divider " <> (dividerHidden $ fst controls.viewType) } [ H.text " " ] , H.div { className: "html " <> (langClass $ fst controls.codeType) <> (previewHidden $ fst controls.viewType) @@ -208,13 +208,16 @@ toolbarCpt = R.hooksComponentWithModule thisModule "toolbar" cpt where cpt props@{controls: {codeType, error, viewType}} _ = do pure $ - H.div { className: "row toolbar" } [ - codeTypeSelector { - codeType - , onChange: onChangeCodeType props - } - , viewTypeSelector {state: viewType} - ] + H.div { className: "row toolbar" } + [ H.div { className: "col-2" } + [ codeTypeSelector { + codeType + , onChange: onChangeCodeType props + } + ] + , H.div { className: "col-1" } + [ viewTypeSelector {state: viewType} ] + ] -- Handle rerendering of preview when viewType changed onChangeCodeType :: forall e. Record ToolbarProps -> e -> Effect Unit diff --git a/src/Gargantext/Components/FacetsTable.purs b/src/Gargantext/Components/FacetsTable.purs index 09e27dc0fb1bae929fc8bc94bce4be85b56c4f72..035ac04222244133ba167ec9f99a38684611fec2 100644 --- a/src/Gargantext/Components/FacetsTable.purs +++ b/src/Gargantext/Components/FacetsTable.purs @@ -13,6 +13,7 @@ import Data.Sequence (Seq) import Data.Sequence as Seq import Data.Set (Set) import Data.Set as Set +import Data.String (Pattern(..), split) import Data.String as String import Data.Tuple (fst, snd) import Data.Tuple.Nested ((/\)) @@ -59,6 +60,7 @@ type Deletions = { pending :: Set Int initialDeletions :: Deletions initialDeletions = { pending: mempty, deleted: mempty } +---------------------------------------------------------------------- newtype Pair = Pair { id :: Int , label :: String @@ -69,6 +71,7 @@ derive instance genericPair :: Generic Pair _ instance showPair :: Show Pair where show = genericShow +---------------------------------------------------------------------- newtype DocumentsView = DocumentsView { id :: Int @@ -85,15 +88,32 @@ newtype DocumentsView = , publication_day :: Int } -publicationDate :: DocumentsView -> String -publicationDate (DocumentsView {publication_year, publication_month, publication_day}) = - (zeroPad 2 publication_year) <> "-" <> (zeroPad 2 publication_month) <> "-" <> (zeroPad 2 publication_day) - derive instance genericDocumentsView :: Generic DocumentsView _ instance showDocumentsView :: Show DocumentsView where show = genericShow +---------------------------------------------------------------------- +newtype ContactsView = + ContactsView + { id :: Int + , hyperdata :: HyperdataRowContact + , score :: Int + , annuaireId :: Int + , delete :: Boolean + } + +derive instance genericContactsView :: Generic ContactsView _ + +instance showContactsView :: Show ContactsView where + show = genericShow + +---------------------------------------------------------------------- +data Rows = Docs { docs :: Seq DocumentsView } + | Contacts { contacts :: Seq ContactsView } + +---------------------------------------------------------------------- + -- | Main layout of the Documents Tab of a Corpus docView :: Record Props -> R.Element docView props = R.createElement docViewCpt props [] @@ -163,7 +183,7 @@ docViewGraphCpt = R.hooksComponentWithModule thisModule "docViewGraph" cpt path <- R.useState' $ initialPagePath { nodeId, listId, query, session } pure $ R.fragment [ H.br {} - , H.p {} [ H.text "" ] + , H.p {} [ H.text "" ] , H.br {} , H.div { className: "container-fluid" } [ R2.row @@ -190,7 +210,7 @@ type PagePath = { nodeId :: Int initialPagePath :: {session :: Session, nodeId :: Int, listId :: Int, query :: SearchQuery} -> PagePath initialPagePath {session, nodeId, listId, query} = {session, nodeId, listId, query, params: T.initialParams} -loadPage :: PagePath -> Aff (Seq DocumentsView) +loadPage :: PagePath -> Aff Rows loadPage {session, nodeId, listId, query, params: {limit, offset, orderBy, searchType}} = do let convOrderBy (T.ASC (T.ColumnName "Date")) = DateAsc @@ -206,21 +226,21 @@ loadPage {session, nodeId, listId, query, params: {limit, offset, orderBy, searc --SearchResult {result} <- post session p $ SearchQuery {query: concat query, expected:searchType} SearchResult {result} <- post session p query -- $ SearchQuery {query: concat query, expected: SearchDoc} - pure case result of - SearchResultDoc {docs} -> doc2view <$> Seq.fromFoldable docs - SearchResultContact {contacts} -> contact2view <$> Seq.fromFoldable contacts - errMessage -> pure $ err2view errMessage + pure $ case result of + SearchResultDoc {docs} -> Docs {docs: doc2view <$> Seq.fromFoldable docs} + SearchResultContact {contacts} -> Contacts {contacts: contact2view <$> Seq.fromFoldable contacts} + errMessage -> Docs {docs: Seq.fromFoldable [err2view errMessage]} -- TODO better error view doc2view :: Document -> DocumentsView doc2view ( Document { id , created: date , hyperdata: HyperdataRowDocument { authors - , title - , source - , publication_year - , publication_month - , publication_day - } + , title + , source + , publication_year + , publication_month + , publication_day + } , category , score } @@ -238,36 +258,27 @@ doc2view ( Document { id , publication_day : fromMaybe 1 publication_day } -contact2view :: Contact -> DocumentsView +contact2view :: Contact -> ContactsView contact2view (Contact { c_id , c_created: date - , c_hyperdata: HyperdataRowContact { firstname - , lastname - , labs - } + , c_hyperdata + , c_annuaireId , c_score } - ) = DocumentsView { id: c_id - , date - , title : firstname <> lastname - , source: labs - , score: c_score - , authors: labs - , category: decodeCategory 1 - , pairs: [] - , delete: false - , publication_year: 2020 - , publication_month: 10 - , publication_day: 1 - } + ) = ContactsView { id: c_id + , hyperdata: c_hyperdata + , score: c_score + , annuaireId : c_annuaireId + , delete: false + } err2view message = DocumentsView { id: 1 - , date: "2020-01-01" + , date: "" , title : "SearchNoResult" - , source: "Source" + , source: "" , score: 1 - , authors: "Authors" + , authors: "" , category: decodeCategory 1 , pairs: [] , delete: false @@ -276,9 +287,6 @@ err2view message = , publication_day: 1 } - - - type PageLayoutProps = ( frontends :: Frontends , totalRecords :: Int @@ -288,7 +296,7 @@ type PageLayoutProps = , path :: R.State PagePath ) -type PageProps = ( documents :: Seq DocumentsView | PageLayoutProps ) +type PageProps = ( rowsLoaded :: Rows | PageLayoutProps ) -- | Loads and renders a page pageLayout :: Record PageLayoutProps -> R.Element @@ -298,8 +306,8 @@ pageLayoutCpt :: R.Component PageLayoutProps pageLayoutCpt = R.hooksComponentWithModule thisModule "pageLayout" cpt where cpt {frontends, totalRecords, deletions, container, session, path} _ = do - useLoader (fst path) loadPage $ \documents -> - page {frontends, totalRecords, deletions, container, session, path, documents} + useLoader (fst path) loadPage $ \rowsLoaded -> + page {frontends, totalRecords, deletions, container, session, path, rowsLoaded} page :: Record PageProps -> R.Element page props = R.createElement pageCpt props [] @@ -307,7 +315,7 @@ page props = R.createElement pageCpt props [] pageCpt :: R.Component PageProps pageCpt = R.hooksComponentWithModule thisModule "page" cpt where - cpt {frontends, totalRecords, container, deletions, documents, session, path: path@({nodeId, listId, query} /\ setPath)} _ = do + cpt {frontends, totalRecords, container, deletions, rowsLoaded, session, path: path@({nodeId, listId, query} /\ setPath)} _ = do pure $ T.table { syncResetButton : [ H.div {} [] ] , rows, container, colNames , totalRecords, params, wrapColElts @@ -315,44 +323,75 @@ pageCpt = R.hooksComponentWithModule thisModule "page" cpt where setParams f = setPath $ \p@{params: ps} -> p {params = f ps} params = (fst path).params /\ setParams - colNames = T.ColumnName <$> [ "", "Date", "Title", "Source", "Authors", "Delete" ] + colNames = case rowsLoaded of + Docs _ -> T.ColumnName <$> [ "", "Date", "Title", "Journal", "", "" ] + Contacts _ -> T.ColumnName <$> [ "", "Contact", "Organization", "", "", "" ] + wrapColElts = const identity -- TODO: how to interprete other scores? - gi Favorite = "fa fa-star-empty" + gi Trash = "fa fa-star-empty" gi _ = "fa fa-star" + isChecked id = Set.member id (fst deletions).pending isDeleted (DocumentsView {id}) = Set.member id (fst deletions).deleted + pairUrl (Pair {id,label}) | id > 1 = H.a { href, target: "blank" } [ H.text label ] where href = url session $ NodePath (sessionId session) NodeContact (Just id) | otherwise = H.text label documentUrl id = url frontends $ Routes.CorpusDocument (sessionId session) nodeId listId id - comma = H.span {} [ H.text ", " ] - rows = row <$> Seq.filter (not <<< isDeleted) documents - row dv@(DocumentsView {id, score, title, source, authors, pairs, delete, category}) = + + rows = case rowsLoaded of + Docs {docs} -> docRow <$> Seq.filter (not <<< isDeleted) docs + Contacts {contacts} -> contactRow <$> contacts + + contactRow (ContactsView { id, hyperdata: HyperdataRowContact { firstname, lastname, labs} + , score, annuaireId, delete + }) = { row: - T.makeRow [ - H.div {} [ H.a { className: gi category, on: {click: markClick} } [] ] - -- TODO show date: Year-Month-Day only - , maybeStricken delete [ H.text $ publicationDate dv ] - , maybeStricken delete [ H.a {target: "_blank", href: documentUrl id} [ H.text title ] ] - , maybeStricken delete [ H.text source ] - , maybeStricken delete [ H.text authors ] - -- , maybeStricken $ intercalate [comma] (pairUrl <$> pairs) - , H.input { defaultChecked: isChecked id - , on: { click: toggleClick } - , type: "checkbox" - } - ] + T.makeRow [ H.div {} [ H.a { className: gi Favorite, on: {click: markClick} } [] ] + , maybeStricken delete [ H.a {target: "_blank", href: contactUrl annuaireId id} + [ H.text $ firstname <> " " <> lastname ] + ] + , maybeStricken delete [ H.text labs ] + ] + , delete: true + } + where + markClick _ = markCategory session nodeId Favorite [id] + contactUrl aId id = url frontends $ Routes.ContactPage (sessionId session) annuaireId id + + docRow dv@(DocumentsView {id, score, title, source, authors, pairs, delete, category}) = + { row: + T.makeRow [ H.div {} [ H.a { className: gi category, on: {click: markClick} } [] ] + , maybeStricken delete [ H.text $ publicationDate dv ] + , maybeStricken delete [ H.a {target: "_blank", href: documentUrl id} [ H.text title ] ] + , maybeStricken delete [ H.text source ] + -- , maybeStricken delete [ H.text authors ] + -- , maybeStricken $ intercalate [comma] (pairUrl <$> pairs) + {-, H.input { defaultChecked: isChecked id + , on: { click: toggleClick } + , type: "checkbox" + } + -} + ] , delete: true } where markClick _ = markCategory session nodeId category [id] toggleClick _ = togglePendingDeletion deletions id + -- comma = H.span {} [ H.text ", " ] + maybeStricken delete - | delete = H.div { style: { textDecoration: "line-through" } } + | delete = H.div { style: { textDecoration: "line-through" } } | otherwise = H.div {} +publicationDate :: DocumentsView -> String +publicationDate (DocumentsView {publication_year, publication_month, publication_day}) = + (zeroPad 2 publication_year) <> "-" <> (zeroPad 2 publication_month) + -- <> "-" <> (zeroPad 2 publication_day) + + --------------------------------------------------------- newtype DeleteDocumentQuery = DeleteDocumentQuery { documents :: Array Int } diff --git a/src/Gargantext/Components/Forest.purs b/src/Gargantext/Components/Forest.purs index 5286e9c453099564ed91f484e8499537126e8bc8..00655aafc38383a8f0200e4a7498535a5b0ff80a 100644 --- a/src/Gargantext/Components/Forest.purs +++ b/src/Gargantext/Components/Forest.purs @@ -38,10 +38,10 @@ type Props = ( forest :: R2.Component Props forest = R.createElement forestCpt - where - forestCpt :: R.Component Props - forestCpt = R.hooksComponentWithModule thisModule "forest" cpt +forestCpt :: R.Component Props +forestCpt = R.hooksComponentWithModule thisModule "forest" cpt + where cpt { appReload , asyncTasksRef , backend @@ -124,10 +124,10 @@ type ForestLayoutProps = ( forestLayout :: R2.Component ForestLayoutProps forestLayout props = R.createElement forestLayoutCpt props - where - forestLayoutCpt :: R.Component ForestLayoutProps - forestLayoutCpt = R.hooksComponentWithModule thisModule "forestLayout" cpt +forestLayoutCpt :: R.Component ForestLayoutProps +forestLayoutCpt = R.hooksComponentWithModule thisModule "forestLayout" cpt + where cpt props@{ handed } children = do pure $ R.fragment [ topBar { handed } [], forestLayoutMain props children ] @@ -135,10 +135,10 @@ forestLayout props = R.createElement forestLayoutCpt props -- while the remaining ones are put into the main view forestLayoutWithTopBar :: R2.Component ForestLayoutProps forestLayoutWithTopBar props = R.createElement forestLayoutWithTopBarCpt props - where - forestLayoutWithTopBarCpt :: R.Component ForestLayoutProps - forestLayoutWithTopBarCpt = R.hooksComponentWithModule thisModule "forestLayoutWithTopBar" cpt +forestLayoutWithTopBarCpt :: R.Component ForestLayoutProps +forestLayoutWithTopBarCpt = R.hooksComponentWithModule thisModule "forestLayoutWithTopBar" cpt + where cpt props@{ handed } children = do let { head: topBarChild, tail: mainChildren } = fromMaybe { head: H.div {} [], tail: [] } $ A.uncons children @@ -149,10 +149,10 @@ forestLayoutWithTopBar props = R.createElement forestLayoutWithTopBarCpt props forestLayoutMain :: R2.Component ForestLayoutProps forestLayoutMain props = R.createElement forestLayoutMainCpt props - where - forestLayoutMainCpt :: R.Component ForestLayoutProps - forestLayoutMainCpt = R.hooksComponentWithModule thisModule "forestLayoutMain" cpt +forestLayoutMainCpt :: R.Component ForestLayoutProps +forestLayoutMainCpt = R.hooksComponentWithModule thisModule "forestLayoutMain" cpt + where cpt props children = do pure $ forestLayoutRaw props [ mainPage {} children @@ -160,10 +160,10 @@ forestLayoutMain props = R.createElement forestLayoutMainCpt props forestLayoutRaw :: R2.Component ForestLayoutProps forestLayoutRaw props = R.createElement forestLayoutRawCpt props - where - forestLayoutRawCpt :: R.Component ForestLayoutProps - forestLayoutRawCpt = R.hooksComponentWithModule thisModule "forestLayoutRaw" cpt +forestLayoutRawCpt :: R.Component ForestLayoutProps +forestLayoutRawCpt = R.hooksComponentWithModule thisModule "forestLayoutRaw" cpt + where cpt { appReload , asyncTasksRef , backend @@ -194,10 +194,10 @@ forestLayoutRaw props = R.createElement forestLayoutRawCpt props mainPage :: R2.Component () mainPage = R.createElement mainPageCpt - where - mainPageCpt :: R.Component () - mainPageCpt = R.hooksComponentWithModule thisModule "mainPage" cpt +mainPageCpt :: R.Component () +mainPageCpt = R.hooksComponentWithModule thisModule "mainPage" cpt + where cpt {} children = do pure $ H.div {className: "col-md-10"} [ H.div {id: "page-wrapper"} [ diff --git a/src/Gargantext/Components/Forest/Tree.purs b/src/Gargantext/Components/Forest/Tree.purs index b5c829f9cdb3f83117bfb08f34cbef41e696f30e..3011b0e13768e1fb82cdc776061d0359dcf2d856 100644 --- a/src/Gargantext/Components/Forest/Tree.purs +++ b/src/Gargantext/Components/Forest/Tree.purs @@ -63,11 +63,11 @@ type Props = ( ) treeView :: R2.Component Props -treeView = R.createElement elCpt - where - elCpt :: R.Component Props - elCpt = R.hooksComponentWithModule thisModule "treeView" cpt +treeView = R.createElement treeViewCpt +treeViewCpt :: R.Component Props +treeViewCpt = R.hooksComponentWithModule thisModule "treeView" cpt + where cpt { appReload , asyncTasks , currentRoute @@ -90,11 +90,11 @@ treeView = R.createElement elCpt } [] treeLoadView :: R2.Component Props -treeLoadView = R.createElement elCpt - where - elCpt :: R.Component Props - elCpt = R.hooksComponentWithModule thisModule "treeLoadView" cpt +treeLoadView = R.createElement treeLoadViewCpt +treeLoadViewCpt :: R.Component Props +treeLoadViewCpt = R.hooksComponentWithModule thisModule "treeLoadView" cpt + where cpt { appReload , asyncTasks , currentRoute @@ -135,11 +135,11 @@ type TreeViewProps = ( ) loadedTreeViewFirstLevel :: R2.Component TreeViewProps -loadedTreeViewFirstLevel = R.createElement elCpt - where - elCpt :: R.Component TreeViewProps - elCpt = R.hooksComponentWithModule thisModule "loadedTreeViewFirstLevel" cpt +loadedTreeViewFirstLevel = R.createElement loadedTreeViewFirstLevelCpt +loadedTreeViewFirstLevelCpt :: R.Component TreeViewProps +loadedTreeViewFirstLevelCpt = R.hooksComponentWithModule thisModule "loadedTreeViewFirstLevel" cpt + where cpt { appReload , asyncTasks , currentRoute @@ -153,54 +153,64 @@ loadedTreeViewFirstLevel = R.createElement elCpt } _ = do pure $ H.ul { className: "tree " <> if handed == GT.RightHanded then "mr-auto" else "ml-auto" } [ H.div { className: if handed == GT.RightHanded then "righthanded" else "lefthanded" } [ - toHtmlFirstLevel { appReload - , asyncTasks - , currentRoute - , frontends - , handed - , openNodes - , reload - , reloadTree: reload - , session - -- , tasks - , tree - } [] + toHtmlFirstLevel (ToHtmlProps { appReload + , asyncTasks + , currentRoute + , frontends + , handed + , openNodes + , reload + , reloadTree: reload + , render: toHtmlFirstLevel + , session + -- , tasks + , tree + }) [] ] ] ------------------------------------------------------------------------ -type ToHtmlProps = ( +newtype ToHtmlProps = ToHtmlProps { asyncTasks :: GAT.Reductor , reloadTree :: GUR.ReloadS + , render :: ToHtmlProps -> Array R.Element -> R.Element -- , tasks :: Record Tasks , tree :: FTree - | CommonProps - ) + -- | CommonProps + , appReload :: GUR.ReloadS + , currentRoute :: AppRoute + , frontends :: Frontends + , handed :: GT.Handed + , openNodes :: R.State OpenNodes + , reload :: GUR.ReloadS + , session :: Session + } -toHtmlFirstLevel :: R2.Component ToHtmlProps -toHtmlFirstLevel = R.createElement elCpt +toHtmlFirstLevel :: ToHtmlProps -> Array R.Element -> R.Element +toHtmlFirstLevel = R2.ntCreateElement toHtmlFirstLevelCpt + +toHtmlFirstLevelCpt :: R2.NTComponent ToHtmlProps +toHtmlFirstLevelCpt = R2.ntHooksComponentWithModule thisModule "toHtmlFirstLevel" cpt where - elCpt :: R.Component ToHtmlProps - elCpt = R.hooksComponentWithModule thisModule "toHtmlFirstLevel" cpt - - cpt p@{ appReload - , asyncTasks - , currentRoute - , frontends - , handed - , openNodes - , reload - , reloadTree - , session - , tree: tree@(NTree (LNode { id - , name - , nodeType - } - ) ary - ) - } _ = do + cpt (ToHtmlProps p@{ appReload + , asyncTasks + , currentRoute + , frontends + , handed + , openNodes + , reload + , reloadTree + , render + , session + , tree: tree@(NTree (LNode { id + , name + , nodeType + } + ) ary + ) + }) _ = do setPopoverRef <- R.useRef Nothing let pAction a = performAction a (RecordE.pick (Record.merge p { setPopoverRef }) :: Record PerformActionProps) @@ -250,6 +260,7 @@ toHtmlFirstLevel = R.createElement elCpt , handed , id: cId , reloadTree + , render } ) [] ) $ sorted publicizedChildren @@ -264,15 +275,19 @@ type ChildNodeFirstLevelProps = ( , folderOpen :: R.State Boolean , id :: ID , reloadTree :: GUR.ReloadS + , render :: ToHtmlProps -> Array R.Element -> R.Element | CommonProps ) childNodeFirstLevel :: R2.Component ChildNodeFirstLevelProps -childNodeFirstLevel = R.createElement elCpt - where - elCpt :: R.Component ChildNodeFirstLevelProps - elCpt = R.hooksComponentWithModule thisModule "childNodeFirstLevel" cpt +childNodeFirstLevel = R.createElement childNodeFirstLevelCpt +-- TODO This shouldn't be here: make it a top-level function but be careful +-- about cyclic defines +-- https://discourse.purescript.org/t/strange-compiler-error-with-an-undefined-reference/2060/3 +childNodeFirstLevelCpt :: R.Component ChildNodeFirstLevelProps +childNodeFirstLevelCpt = R.hooksComponentWithModule thisModule "childNodeFirstLevel" cpt + where cpt props@{ appReload , asyncTasks , currentRoute @@ -283,6 +298,7 @@ childNodeFirstLevel = R.createElement elCpt , openNodes , reload , reloadTree + , render , session } _ = do cptReload <- GUR.new @@ -296,6 +312,7 @@ childNodeFirstLevel = R.createElement elCpt , openNodes , reload: cptReload , reloadTree + , render , session , tree: loaded } [] @@ -308,28 +325,33 @@ type ChildNodeFirstLevelPaintProps = ( asyncTasks :: GAT.Reductor , folderOpen :: R.State Boolean , reloadTree :: GUR.ReloadS + , render :: ToHtmlProps -> Array R.Element -> R.Element , tree :: FTree | CommonProps ) childNodeFirstLevelPaint :: R2.Component ChildNodeFirstLevelPaintProps -childNodeFirstLevelPaint = R.createElement elCpt +childNodeFirstLevelPaint = R.createElement childNodeFirstLevelPaintCpt + +-- TODO This shouldn't be here: make it a top-level function but be careful +-- about cyclic defines +-- https://discourse.purescript.org/t/strange-compiler-error-with-an-undefined-reference/2060/3 +childNodeFirstLevelPaintCpt :: R.Component ChildNodeFirstLevelPaintProps +childNodeFirstLevelPaintCpt = R.hooksComponentWithModule thisModule "childNodeFirstLevelPaint" cpt +-- TODO folderOpen is unused where - elCpt :: R.Component ChildNodeFirstLevelPaintProps - elCpt = R.hooksComponentWithModule thisModule "childNodeFirstLevelPaint" cpt - - -- TODO folderOpen is unused - cpt props@{ asyncTasks , handed , reload , reloadTree + , render , tree: ctree@(NTree (LNode { id }) _) } _ = do pure $ H.ul {} [ - toHtmlFirstLevel (Record.merge commonProps { asyncTasks - , handed - , reloadTree - , tree: ctree } + render (ToHtmlProps (Record.merge commonProps { asyncTasks + , handed + , reloadTree + , render + , tree: ctree }) ) [] ] -- pure $ H.div { } [ H.text $ "[closed] Node id " <> show id ] diff --git a/src/Gargantext/Components/Forest/Tree/Node.purs b/src/Gargantext/Components/Forest/Tree/Node.purs index 7f27ff50d84f647d0d73a21e10473b5073603e1d..c0e4071fdb97475e79ef4c7e81139f9c1f9e488d 100644 --- a/src/Gargantext/Components/Forest/Tree/Node.purs +++ b/src/Gargantext/Components/Forest/Tree/Node.purs @@ -60,19 +60,19 @@ type IsLeaf = Boolean nodeSpan :: R2.Component NodeMainSpanProps nodeSpan = R.createElement nodeSpanCpt - where - nodeSpanCpt :: R.Component NodeMainSpanProps - nodeSpanCpt = R.hooksComponentWithModule thisModule "nodeSpan" cpt +nodeSpanCpt :: R.Component NodeMainSpanProps +nodeSpanCpt = R.hooksComponentWithModule thisModule "nodeSpan" cpt + where cpt props children = do pure $ H.div {} ([ nodeMainSpan props [] ] <> children) nodeMainSpan :: R2.Component NodeMainSpanProps nodeMainSpan = R.createElement nodeMainSpanCpt - where - nodeMainSpanCpt :: R.Component NodeMainSpanProps - nodeMainSpanCpt = R.hooksComponentWithModule thisModule "nodeMainSpan" cpt +nodeMainSpanCpt :: R.Component NodeMainSpanProps +nodeMainSpanCpt = R.hooksComponentWithModule thisModule "nodeMainSpan" cpt + where cpt props@{ appReload , asyncTasks: (asyncTasks /\ dispatchAsyncTasks) , currentRoute @@ -249,10 +249,10 @@ type NodeActionsProps = nodeActions :: Record NodeActionsProps -> R.Element nodeActions p = R.createElement nodeActionsCpt p [] - where - nodeActionsCpt :: R.Component NodeActionsProps - nodeActionsCpt = R.hooksComponentWithModule thisModule "nodeActions" cpt +nodeActionsCpt :: R.Component NodeActionsProps +nodeActionsCpt = R.hooksComponentWithModule thisModule "nodeActions" cpt + where cpt { id , nodeType: GT.Graph , session diff --git a/src/Gargantext/Components/Forest/Tree/Node/Action/Add.purs b/src/Gargantext/Components/Forest/Tree/Node/Action/Add.purs index 12dd023cca10176d16ae4bbb7fefed7acef23c07..6b75ea5803c9c6161c81a2131f7c405f7ec3ea18 100644 --- a/src/Gargantext/Components/Forest/Tree/Node/Action/Add.purs +++ b/src/Gargantext/Components/Forest/Tree/Node/Action/Add.purs @@ -86,7 +86,6 @@ addNodeView p@{ dispatch, nodeType, nodeTypes } = R.createElement el p [] onEnter: \_ -> launchAff_ $ dispatch (AddNode name' nt') , onValueChanged: \val -> setNodeName $ const val , autoFocus: true - , autoSave: false , className: "form-control" , defaultValue: name' , placeholder: name' diff --git a/src/Gargantext/Components/Forest/Tree/Node/Action/Link.purs b/src/Gargantext/Components/Forest/Tree/Node/Action/Link.purs index 34a09b2d45320212beb0eb6b175f063e65c7acdb..b57cb1494d0dc63c195185ac53650514f9dfe81b 100644 --- a/src/Gargantext/Components/Forest/Tree/Node/Action/Link.purs +++ b/src/Gargantext/Components/Forest/Tree/Node/Action/Link.purs @@ -55,8 +55,8 @@ linkNodeType (Just GT.Annuaire) = GT.Corpus linkNodeType _ = GT.Error -linkNode :: Record SubTreeParamsIn -> R.Element -linkNode p = R.createElement linkNodeCpt p [] +linkNode :: R2.Component SubTreeParamsIn +linkNode = R.createElement linkNodeCpt linkNodeCpt :: R.Component SubTreeParamsIn linkNodeCpt = R.hooksComponentWithModule thisModule "linkNode" cpt diff --git a/src/Gargantext/Components/Forest/Tree/Node/Action/Merge.purs b/src/Gargantext/Components/Forest/Tree/Node/Action/Merge.purs index a53e371f88e64c76a97ebe65185e2416c414ca6e..0800bd7d054840eb2e0bdd13d8b2a06479e8cc3e 100644 --- a/src/Gargantext/Components/Forest/Tree/Node/Action/Merge.purs +++ b/src/Gargantext/Components/Forest/Tree/Node/Action/Merge.purs @@ -22,12 +22,12 @@ mergeNodeReq :: Session -> GT.ID -> GT.ID -> Aff (Array GT.ID) mergeNodeReq session fromId toId = put_ session $ NodeAPI GT.Node (Just fromId) ("merge/" <> show toId) -mergeNode :: Record SubTreeParamsIn -> R.Element -mergeNode p = R.createElement mergeNodeCpt p [] - where - mergeNodeCpt :: R.Component SubTreeParamsIn - mergeNodeCpt = R.hooksComponentWithModule thisModule "mergeNode" cpt +mergeNode :: R2.Component SubTreeParamsIn +mergeNode = R.createElement mergeNodeCpt +mergeNodeCpt :: R.Component SubTreeParamsIn +mergeNodeCpt = R.hooksComponentWithModule thisModule "mergeNode" cpt + where cpt p@{dispatch, subTreeParams, id, nodeType, session, handed} _ = do action@(valAction /\ setAction) :: R.State Action <- R.useState' (MergeNode {params:Nothing}) diff --git a/src/Gargantext/Components/Forest/Tree/Node/Action/Move.purs b/src/Gargantext/Components/Forest/Tree/Node/Action/Move.purs index 33985a4b77b6d8841fe3125f6684b5bafa32ac12..da463ffa8ba1031a8f48e4128de159f6a12a93db 100644 --- a/src/Gargantext/Components/Forest/Tree/Node/Action/Move.purs +++ b/src/Gargantext/Components/Forest/Tree/Node/Action/Move.purs @@ -14,6 +14,7 @@ import Gargantext.Components.Forest.Tree.Node.Tools.SubTree (subTreeView, SubTre import Gargantext.Routes (SessionRoute(..)) import Gargantext.Sessions (Session, put_) import Gargantext.Types as GT +import Gargantext.Utils.Reactix as R2 thisModule :: String thisModule = "Gargantext.Components.Forest.Tree.Node.Action.Move" @@ -22,12 +23,12 @@ moveNodeReq :: Session -> GT.ID -> GT.ID -> Aff (Array GT.ID) moveNodeReq session fromId toId = put_ session $ NodeAPI GT.Node (Just fromId) ("move/" <> show toId) -moveNode :: Record SubTreeParamsIn -> R.Element -moveNode p = R.createElement moveNodeCpt p [] - where - moveNodeCpt :: R.Component SubTreeParamsIn - moveNodeCpt = R.hooksComponentWithModule thisModule "moveNode" cpt +moveNode :: R2.Component SubTreeParamsIn +moveNode = R.createElement moveNodeCpt +moveNodeCpt :: R.Component SubTreeParamsIn +moveNodeCpt = R.hooksComponentWithModule thisModule "moveNode" cpt + where cpt { dispatch, handed, id, nodeType, session, subTreeParams } _ = do action@(valAction /\ setAction) :: R.State Action <- R.useState' (MoveNode {params: Nothing}) diff --git a/src/Gargantext/Components/Forest/Tree/Node/Action/Search/Frame.purs b/src/Gargantext/Components/Forest/Tree/Node/Action/Search/Frame.purs index f3ed62c7aac4ec969f26e62a3313c192640e4bac..e3c6be0db9eb2729e39eb6dc2571707a207cb714 100644 --- a/src/Gargantext/Components/Forest/Tree/Node/Action/Search/Frame.purs +++ b/src/Gargantext/Components/Forest/Tree/Node/Action/Search/Frame.purs @@ -41,10 +41,10 @@ type SearchIFramesProps = ( searchIframes :: Record SearchIFramesProps -> R.Element searchIframes props = R.createElement searchIframesCpt props [] - where - searchIframesCpt :: R.Component SearchIFramesProps - searchIframesCpt = R.hooksComponentWithModule thisModule "searchIframes" cpt +searchIframesCpt :: R.Component SearchIFramesProps +searchIframesCpt = R.hooksComponentWithModule thisModule "searchIframes" cpt + where cpt { iframeRef, search: search@(search' /\ _) } _ = do pure $ if isIsTex_Advanced search'.datafield then divIframe { frameSource: Istex, iframeRef, search } @@ -62,10 +62,10 @@ type IFrameProps = ( divIframe :: Record IFrameProps -> R.Element divIframe props = R.createElement divIframeCpt props [] - where - divIframeCpt :: R.Component IFrameProps - divIframeCpt = R.hooksComponentWithModule thisModule "divIframe" cpt +divIframeCpt :: R.Component IFrameProps +divIframeCpt = R.hooksComponentWithModule thisModule "divIframe" cpt + where cpt { frameSource, iframeRef, search: search@(search' /\ _) } _ = do pure $ H.div { className: "frame-search card" } [ iframeWith { frameSource, iframeRef, search } ] @@ -77,10 +77,10 @@ frameUrl Searx = "https://searx.frame.gargantext.org" -- 192.168.1.4:8080" iframeWith :: Record IFrameProps -> R.Element iframeWith props = R.createElement iframeWithCpt props [] - where - iframeWithCpt :: R.Component IFrameProps - iframeWithCpt = R.hooksComponentWithModule thisModule "iframeWith" cpt +iframeWithCpt :: R.Component IFrameProps +iframeWithCpt = R.hooksComponentWithModule thisModule "iframeWith" cpt + where cpt { frameSource, iframeRef, search: (search /\ setSearch) } _ = pure $ H.iframe { src: src frameSource search.term , width: "100%" diff --git a/src/Gargantext/Components/Forest/Tree/Node/Action/Search/SearchBar.purs b/src/Gargantext/Components/Forest/Tree/Node/Action/Search/SearchBar.purs index 1cc82cff88c81c5216284aedb66204253c17c93f..a1cf0c987fd54d52997ef6e53fb43de8345a77b5 100644 --- a/src/Gargantext/Components/Forest/Tree/Node/Action/Search/SearchBar.purs +++ b/src/Gargantext/Components/Forest/Tree/Node/Action/Search/SearchBar.purs @@ -26,10 +26,10 @@ type Props = ( langs :: Array Lang searchBar :: Record Props -> R.Element searchBar props = R.createElement searchBarCpt props [] - where - searchBarCpt :: R.Component Props - searchBarCpt = R.hooksComponentWithModule thisModule "searchBar" cpt +searchBarCpt :: R.Component Props +searchBarCpt = R.hooksComponentWithModule thisModule "searchBar" cpt + where cpt {langs, onSearch, search: search@(s /\ _), session} _ = do --onSearchChange session s pure $ H.div { className: "search-bar" } diff --git a/src/Gargantext/Components/Forest/Tree/Node/Action/Search/SearchField.purs b/src/Gargantext/Components/Forest/Tree/Node/Action/Search/SearchField.purs index 8df1b8f64fa6841c4ac50167a18764d65b23df37..376fc28fcb5617955b902870a06b0211a4f7cb7a 100644 --- a/src/Gargantext/Components/Forest/Tree/Node/Action/Search/SearchField.purs +++ b/src/Gargantext/Components/Forest/Tree/Node/Action/Search/SearchField.purs @@ -266,10 +266,10 @@ type DatabaseInputProps = ( databaseInput :: R2.Component DatabaseInputProps databaseInput = R.createElement databaseInputCpt - where - databaseInputCpt :: R.Component DatabaseInputProps - databaseInputCpt = R.hooksComponentWithModule thisModule "databaseInput" cpt +databaseInputCpt :: R.Component DatabaseInputProps +databaseInputCpt = R.hooksComponentWithModule thisModule "databaseInput" cpt + where cpt { databases , search: (search /\ setSearch) } _ = do pure $ @@ -338,10 +338,10 @@ type SearchInputProps = searchInput :: Record SearchInputProps -> R.Element searchInput p = R.createElement searchInputCpt p [] - where - searchInputCpt :: R.Component SearchInputProps - searchInputCpt = R.hooksComponentWithModule thisModule "searchInput" cpt +searchInputCpt :: R.Component SearchInputProps +searchInputCpt = R.hooksComponentWithModule thisModule "searchInput" cpt + where cpt {search: (search@{ term } /\ setSearch)} _ = do valueRef <- R.useRef term @@ -349,7 +349,6 @@ searchInput p = R.createElement searchInputCpt p [] inputWithEnter { onEnter: onEnter valueRef setSearch , onValueChanged: onValueChanged valueRef , autoFocus: false - , autoSave: true , className: "form-control" , defaultValue: R.readRef valueRef , placeholder: "Your query here" @@ -380,10 +379,10 @@ type SubmitButtonProps = submitButton :: Record SubmitButtonProps -> R.Element submitButton p = R.createElement submitButtonComponent p [] - where - submitButtonComponent :: R.Component SubmitButtonProps - submitButtonComponent = R.hooksComponentWithModule thisModule "submitButton" cpt +submitButtonComponent :: R.Component SubmitButtonProps +submitButtonComponent = R.hooksComponentWithModule thisModule "submitButton" cpt + where cpt {onSearch, search: (mySearch /\ _), session} _ = pure $ H.button { className: "btn btn-primary" diff --git a/src/Gargantext/Components/Forest/Tree/Node/Action/Share.purs b/src/Gargantext/Components/Forest/Tree/Node/Action/Share.purs index 11f5b2fc308ac41f087ade59c0e157fceba32114..4fd7ac3c887d1513605cf45ea946aef0c15f4363 100644 --- a/src/Gargantext/Components/Forest/Tree/Node/Action/Share.purs +++ b/src/Gargantext/Components/Forest/Tree/Node/Action/Share.purs @@ -57,10 +57,10 @@ instance encodeJsonShareNodeParams :: Argonaut.EncodeJson ShareNodeParams where ------------------------------------------------------------------------ shareNode :: Record SubTreeParamsIn -> R.Element shareNode p = R.createElement shareNodeCpt p [] - where - shareNodeCpt :: R.Component SubTreeParamsIn - shareNodeCpt = R.hooksComponentWithModule thisModule "shareNode" cpt +shareNodeCpt :: R.Component SubTreeParamsIn +shareNodeCpt = R.hooksComponentWithModule thisModule "shareNode" cpt + where cpt p@{dispatch, subTreeParams, id, nodeType, session, handed} _ = do action@(valAction /\ setAction) :: R.State Action <- R.useState' (Action.SharePublic {params: Nothing}) diff --git a/src/Gargantext/Components/Forest/Tree/Node/Action/Upload.purs b/src/Gargantext/Components/Forest/Tree/Node/Action/Upload.purs index 2cc4192b6c310901d36c421fe059ba37df7cd75b..7768375c2d4bd89f74cafddde358c5f5d76f3c53 100644 --- a/src/Gargantext/Components/Forest/Tree/Node/Action/Upload.purs +++ b/src/Gargantext/Components/Forest/Tree/Node/Action/Upload.purs @@ -71,10 +71,10 @@ type UploadFile = uploadFileView :: Record Props -> R.Element uploadFileView props = R.createElement uploadFileViewCpt props [] - where - uploadFileViewCpt :: R.Component Props - uploadFileViewCpt = R.hooksComponentWithModule thisModule "uploadFileView" cpt +uploadFileViewCpt :: R.Component Props +uploadFileViewCpt = R.hooksComponentWithModule thisModule "uploadFileView" cpt + where cpt {dispatch, id, nodeType} _ = do mFile :: R.State (Maybe UploadFile) <- R.useState' Nothing fileType@(_ /\ setFileType) <- R.useState' CSV diff --git a/src/Gargantext/Components/Forest/Tree/Node/Box.purs b/src/Gargantext/Components/Forest/Tree/Node/Box.purs index c5f4a3da249529fd8a9a9a2c293db0ccd43162e9..0f6e7a49a94544e35bdaedb4c33d460223e27efc 100644 --- a/src/Gargantext/Components/Forest/Tree/Node/Box.purs +++ b/src/Gargantext/Components/Forest/Tree/Node/Box.purs @@ -48,10 +48,10 @@ type CommonProps = nodePopupView :: Record NodePopupProps -> R.Element nodePopupView p = R.createElement nodePopupCpt p [] - where - nodePopupCpt :: R.Component NodePopupProps - nodePopupCpt = R.hooksComponentWithModule thisModule "nodePopupView" cpt +nodePopupCpt :: R.Component NodePopupProps +nodePopupCpt = R.hooksComponentWithModule thisModule "nodePopupView" cpt + where cpt p _ = do renameIsOpen <- R.useState' false @@ -254,10 +254,10 @@ type PanelActionProps = panelAction :: Record PanelActionProps -> R.Element panelAction p = R.createElement panelActionCpt p [] - where - panelActionCpt :: R.Component PanelActionProps - panelActionCpt = R.hooksComponentWithModule thisModule "panelAction" cpt +panelActionCpt :: R.Component PanelActionProps +panelActionCpt = R.hooksComponentWithModule thisModule "panelAction" cpt + where cpt {action: Documentation nodeType} _ = actionDoc nodeType cpt {action: Download, id, nodeType, session} _ = actionDownload nodeType id session cpt {action: Upload, dispatch, id, nodeType, session} _ = actionUpload nodeType id session dispatch @@ -274,13 +274,13 @@ panelAction p = R.createElement panelActionCpt p [] ----------- -- Functions using SubTree cpt {action: Merge {subTreeParams}, dispatch, id, nodeType, session, handed} _ = do - pure $ mergeNode {dispatch, id, nodeType, session, subTreeParams, handed} + pure $ mergeNode {dispatch, id, nodeType, session, subTreeParams, handed} [] cpt {action: Move {subTreeParams}, dispatch, id, nodeType, session, handed} _ = do - pure $ moveNode {dispatch, id, nodeType, session, subTreeParams, handed} + pure $ moveNode {dispatch, id, nodeType, session, subTreeParams, handed} [] cpt {action: Link {subTreeParams}, dispatch, id, nodeType, session, handed} _ = do - pure $ linkNode {dispatch, id, nodeType, session, subTreeParams, handed} + pure $ linkNode {dispatch, id, nodeType, session, subTreeParams, handed} [] ----------- cpt {action : Share, dispatch, id, name } _ = do diff --git a/src/Gargantext/Components/Forest/Tree/Node/Settings.purs b/src/Gargantext/Components/Forest/Tree/Node/Settings.purs index dbbb8ba0225c391a84f0090e45527c5d8bd2c599..e08ff08d519cf918dfff6fb0096830ee0e9786c5 100644 --- a/src/Gargantext/Components/Forest/Tree/Node/Settings.purs +++ b/src/Gargantext/Components/Forest/Tree/Node/Settings.purs @@ -130,7 +130,7 @@ settingsBox Team = , Annuaire , NodeFrameWrite , NodeFrameCalc - , NodeFrameNotebook + -- , NodeFrameNotebook , Team , FolderShared ] diff --git a/src/Gargantext/Components/Forest/Tree/Node/Tools.purs b/src/Gargantext/Components/Forest/Tree/Node/Tools.purs index 7a926fd8db275a471b130a723100f4949c9aa042..8fcd1981bc77ed115dd8fffe2163d85a75940199 100644 --- a/src/Gargantext/Components/Forest/Tree/Node/Tools.purs +++ b/src/Gargantext/Components/Forest/Tree/Node/Tools.purs @@ -65,12 +65,12 @@ type TextInputBoxProps = ) textInputBox :: R2.Component TextInputBoxProps -textInputBox props@{ boxName } = R.createElement el props - where - el :: R.Component TextInputBoxProps - el = R.hooksComponentWithModule thisModule (boxName <> "Box") cpt +textInputBox = R.createElement textInputBoxCpt - cpt p@{ boxAction, dispatch, id, isOpen: (true /\ setIsOpen), text } _ = do +textInputBoxCpt :: R.Component TextInputBoxProps +textInputBoxCpt = R.hooksComponentWithModule thisModule "textInputBox" cpt + where + cpt p@{ boxAction, boxName, dispatch, id, isOpen: (true /\ setIsOpen), text } _ = do renameNodeNameRef <- R.useRef text pure $ H.div { className: "from-group row" } @@ -85,7 +85,6 @@ textInputBox props@{ boxName } = R.createElement el props onEnter: submit renameNodeNameRef , onValueChanged: R.setRef renameNodeNameRef , autoFocus: true - , autoSave: false , className: "form-control" , defaultValue: text , placeholder: (boxName <> " Node") @@ -105,8 +104,8 @@ textInputBox props@{ boxName } = R.createElement el props , title: "Cancel" } [] submit renameNodeNameRef _ = do - setIsOpen $ const false launchAff_ $ dispatch ( boxAction $ R.readRef renameNodeNameRef ) + setIsOpen $ const false cpt { isOpen: (false /\ _) } _ = pure $ H.div {} [] -- | END Rename Box @@ -292,10 +291,10 @@ type NodeLinkProps = ( nodeLink :: R2.Component NodeLinkProps nodeLink = R.createElement nodeLinkCpt - where - nodeLinkCpt :: R.Component NodeLinkProps - nodeLinkCpt = R.hooksComponentWithModule thisModule "nodeLink" cpt +nodeLinkCpt :: R.Component NodeLinkProps +nodeLinkCpt = R.hooksComponentWithModule thisModule "nodeLink" cpt + where cpt { folderOpen: (_ /\ setFolderOpen) , frontends , handed @@ -348,10 +347,10 @@ type NodeTextProps = nodeText :: Record NodeTextProps -> R.Element nodeText p = R.createElement nodeTextCpt p [] - where - nodeTextCpt :: R.Component NodeTextProps - nodeTextCpt = R.hooksComponentWithModule thisModule "nodeText" cpt +nodeTextCpt :: R.Component NodeTextProps +nodeTextCpt = R.hooksComponentWithModule thisModule "nodeText" cpt + where cpt { isSelected: true, name } _ = do pure $ H.u {} [ H.b {} [ diff --git a/src/Gargantext/Components/Forest/Tree/Node/Tools/SubTree.purs b/src/Gargantext/Components/Forest/Tree/Node/Tools/SubTree.purs index 84a4556513ec21c822ec46038281e2d07176f65b..277b903ac2a6eb1a7dc6db2479e8a54e2b1a9845 100644 --- a/src/Gargantext/Components/Forest/Tree/Node/Tools/SubTree.purs +++ b/src/Gargantext/Components/Forest/Tree/Node/Tools/SubTree.purs @@ -36,10 +36,10 @@ type SubTreeParamsProps = subTreeView :: Record SubTreeParamsProps -> R.Element subTreeView props = R.createElement subTreeViewCpt props [] - where - subTreeViewCpt :: R.Component SubTreeParamsProps - subTreeViewCpt = R.hooksComponentWithModule thisModule "subTreeView" cpt +subTreeViewCpt :: R.Component SubTreeParamsProps +subTreeViewCpt = R.hooksComponentWithModule thisModule "subTreeView" cpt + where cpt params@{ action , dispatch , handed diff --git a/src/Gargantext/Components/Forest/Tree/Node/Tools/Sync.purs b/src/Gargantext/Components/Forest/Tree/Node/Tools/Sync.purs index 34be1f3a4ed863b7f32844d33540e11937dc9413..9b6fcfd633ec1a2e7f40d09f22e166832ece1ec7 100644 --- a/src/Gargantext/Components/Forest/Tree/Node/Tools/Sync.purs +++ b/src/Gargantext/Components/Forest/Tree/Node/Tools/Sync.purs @@ -110,7 +110,7 @@ nodeListUpdateButtonCpt = R.hooksComponentWithModule thisModule "nodeListUpdateB cpt { listId, nodeId, nodeType, session, triggerRefresh } _ = do enabled <- R.useState' true - pure $ H.div { className: "update-button " + pure $ H.div {} [] {- { className: "update-button " <> if (fst enabled) then "enabled" else "disabled text-muted" } [ H.span { className: "fa fa-refresh" , on: { click: onClick enabled } } [] @@ -124,3 +124,4 @@ nodeListUpdateButtonCpt = R.hooksComponentWithModule thisModule "nodeListUpdateB liftEffect $ setEnabled $ const true triggerRefresh unit pure unit + -} diff --git a/src/Gargantext/Components/Graph.purs b/src/Gargantext/Components/Graph.purs index 52d94a2cf7f8d4f12c3f263c9065d05060c6eeb7..e0a4359941dc32c06442a222479e1e36447deae8 100644 --- a/src/Gargantext/Components/Graph.purs +++ b/src/Gargantext/Components/Graph.purs @@ -225,60 +225,60 @@ type SigmaSettings = -- selected nodes <=> special label sigmaSettings :: {|SigmaSettings} sigmaSettings = - { animationsTime: 30000.0 - , autoRescale: true - , autoResize: true - , batchEdgesDrawing: true - , borderSize: 1.0 -- for ex, bigger border when hover - , defaultEdgeHoverColor: "#f00" - , defaultEdgeType: "curve" -- 'curve' or 'line' (curve iff ourRendering) - , defaultHoverLabelBGColor: "#fff" - , defaultHoverLabelColor: "#000" - , defaultLabelColor: "#000" -- labels text color - , defaultLabelSize: 15.0 -- (old tina: showLabelsIfZoom) - , defaultNodeBorderColor : "#000" -- <- if nodeBorderColor = 'default' - , defaultNodeColor: "#FFF" - , doubleClickEnabled: false -- indicates whether or not the graph can be zoomed on double-click - , drawEdgeLabels: true - , drawEdges: true - , drawLabels: true - , drawNodes: true - , enableEdgeHovering: false - , edgeHoverExtremities: true - , edgeHoverColor: "edge" - , edgeHoverPrecision: 2.0 - , edgeHoverSizeRatio: 2.0 - , enableHovering: true - , font: "arial" -- font params - , fontStyle: "bold" - , hideEdgesOnMove: true - --, labelSize : "proportional" -- alt : proportional, fixed - , labelSize: "fixed" - , labelSizeRatio: 2.0 -- label size in ratio of node size - , labelThreshold: 7.0 -- min node cam size to start showing label - , maxEdgeSize: 1.0 - , maxNodeSize: 8.0 - , minEdgeSize: 0.5 -- in fact used in tina as edge size - , minNodeSize: 1.0 - , mouseEnabled: true - , mouseSelectorSize: 15.0 - , mouseZoomDuration: 150.0 - , nodeBorderColor: "default" -- choices: "default" color vs. "node" color - --, nodesPowRatio : 10.8 - , rescaleIgnoreSize : false - , singleHover : true - , touchEnabled : true - , twBorderGreyColor : "rgba(100, 100, 100, 0.9)" - , twEdgeDefaultOpacity : 0.4 -- initial opacity added to src/tgt colors - , twEdgeGreyColor : "rgba(100, 100, 100, 0.25)" - , twNodeRendBorderColor : "#FFF" - , twNodeRendBorderSize : 2.5 -- node borders (only iff ourRendering) - , twNodesGreyOpacity : 5.5 -- smaller value: more grey - , twSelectedColor : "node" -- "node" for a label bg like the node color, "default" for white background - , verbose : true - , zoomMax: 1.7 - , zoomMin: 0.0 - , zoomingRatio: 1.7 + { animationsTime : 30000.0 + , autoRescale : true + , autoResize : true + , batchEdgesDrawing : true + , borderSize : 1.0 -- for ex, bigger border when hover + , defaultEdgeHoverColor : "#f00" + , defaultEdgeType : "curve" -- 'curve' or 'line' (curve iff ourRendering) + , defaultHoverLabelBGColor : "#fff" + , defaultHoverLabelColor : "#000" + , defaultLabelColor : "#000" -- labels text color + , defaultLabelSize : 15.0 -- (old tina: showLabelsIfZoom) + , defaultNodeBorderColor : "#000" -- <- if nodeBorderColor = 'default' + , defaultNodeColor : "#FFF" + , doubleClickEnabled : false -- indicates whether or not the graph can be zoomed on double-click + , drawEdgeLabels : true + , drawEdges : true + , drawLabels : true + , drawNodes : true + , enableEdgeHovering : false + , edgeHoverExtremities : true + , edgeHoverColor : "edge" + , edgeHoverPrecision : 2.0 + , edgeHoverSizeRatio : 2.0 + , enableHovering : true + , font : "arial" + , fontStyle : "" + , hideEdgesOnMove : true + , labelSize : "proportional" -- alt : proportional, fixed + -- , labelSize : "fixed" + , labelSizeRatio : 2.0 -- label size in ratio of node size + , labelThreshold : 9.0 -- 5.0 for more labels -- min node cam size to start showing label + , maxEdgeSize : 1.0 + , maxNodeSize : 10.0 + , minEdgeSize : 0.5 -- in fact used in tina as edge size + , minNodeSize : 1.0 + , mouseEnabled : true + , mouseSelectorSize : 15.0 + , mouseZoomDuration : 150.0 + , nodeBorderColor : "default" -- choices: "default" color vs. "node" color + --, nodesPowRatio : 10.8 + , rescaleIgnoreSize : false + , singleHover : true + , touchEnabled : true + , twBorderGreyColor : "rgba(100, 100, 100, 0.9)" + , twEdgeDefaultOpacity : 0.4 -- initial opacity added to src/tgt colors + , twEdgeGreyColor : "rgba(100, 100, 100, 0.25)" + , twNodeRendBorderColor : "#FFF" + , twNodeRendBorderSize : 2.5 -- node borders (only iff ourRendering) + , twNodesGreyOpacity : 5.5 -- smaller value: more grey + , twSelectedColor : "node" -- "node" for a label bg like the node color, "default" for white background + , verbose : true + , zoomMax : 1.7 + , zoomMin : 0.0 + , zoomingRatio : 1.4 } type ForceAtlas2Settings = @@ -306,11 +306,11 @@ forceAtlas2Settings = , barnesHutOptimize : true , edgeWeightInfluence : 1.0 -- fixedY : false - , gravity : 1.0 - , iterationsPerRender : 10.0 + , gravity : 0.01 + , iterationsPerRender : 50.0 -- 10.0 , linLogMode : false -- false , outboundAttractionDistribution: false - , scalingRatio : 10.0 + , scalingRatio : 1000.0 , skipHidden: false , slowDown : 1.0 , startingIterations : 10.0 diff --git a/src/Gargantext/Components/GraphExplorer/Sidebar.purs b/src/Gargantext/Components/GraphExplorer/Sidebar.purs index f8fb65e680a95bfa7f7ec8e01dddcaafa86364ee..c411d26f5c2758e88098fefa90361a2c617acca3 100644 --- a/src/Gargantext/Components/GraphExplorer/Sidebar.purs +++ b/src/Gargantext/Components/GraphExplorer/Sidebar.purs @@ -54,10 +54,10 @@ type Props = sidebar :: Record Props -> R.Element sidebar props = R.createElement sidebarCpt props [] - where - sidebarCpt :: R.Component Props - sidebarCpt = R.hooksComponentWithModule thisModule "sidebar" cpt +sidebarCpt :: R.Component Props +sidebarCpt = R.hooksComponentWithModule thisModule "sidebar" cpt + where cpt {showSidePanel: (GET.Closed /\ _)} _children = do pure $ RH.div {} [] cpt {showSidePanel: (GET.InitialClosed /\ _)} _children = do @@ -70,7 +70,7 @@ sidebar props = R.createElement sidebarCpt props [] sideTabNav :: R.State SidePanelState -> Array SideTab -> R.Element sideTabNav (sidePanel /\ setSidePanel) sideTabs = - R.fragment [ H.div { className: "text-primary center"} [H.text "SideTab"] + R.fragment [ H.div { className: "text-primary center"} [H.text ""] , H.div {className: "nav nav-tabs"} (liItem <$> sideTabs) -- , H.div {className: "center"} [ H.text "Doc sideTabs"] ] @@ -133,36 +133,46 @@ sideTab _ _ = H.div {} [] ------------------------------------------- -- TODO -- selectedNodes :: Record Props -> Map.Map String Nodes -> R.Element -selectedNodes props nodesMap = R2.row [ R2.col 12 - [ RH.ul { id: "myTab", className: "nav nav-tabs", role: "tablist"} - [ RH.div { className: "tab-content" } - [ RH.div { className: "", role: "tabpanel" } - ( Seq.toUnfoldable - $ ( Seq.map (badge props.selectedNodeIds) - (badges props.graph props.selectedNodeIds) - ) - ) - ] - , RH.div { className: "tab-content flex-space-between" } - [ removeButton "Move as candidate" CandidateTerm props nodesMap - , removeButton "Move as stop" StopTerm props nodesMap - ] - ] - ] - ] +selectedNodes props nodesMap = + R2.row [ R2.col 12 + [ RH.ul { className: "nav nav-tabs d-flex justify-content-center" + , id: "myTab" + , role: "tablist" } + [ RH.div { className: "tab-content" } + [ RH.div { className: "d-flex flex-wrap justify-content-center" + , role: "tabpanel" } + ( Seq.toUnfoldable + $ ( Seq.map (badge props.selectedNodeIds) + (badges props.graph props.selectedNodeIds) + ) + ) + , H.br {} + ] + ] + , RH.div { className: "tab-content flex-space-between" } + [ removeButton "primary" "Move as candidate" CandidateTerm props nodesMap + , H.br {} + , removeButton "danger" "Move as stop" StopTerm props nodesMap + ] + ] + ] neighborhood props = RH.div { className: "tab-content", id: "myTabContent" } - [ RH.div { className: "", id: "home", role: "tabpanel" } + [ RH.div { -- className: "flex-space-around d-flex justify-content-center" + className: "d-flex flex-wrap flex-space-around" + , id: "home" + , role: "tabpanel" + } (Seq.toUnfoldable $ Seq.map (badge props.selectedNodeIds) $ neighbourBadges props.graph props.selectedNodeIds ) ] -removeButton text rType props' nodesMap' = +removeButton btnType text rType props' nodesMap' = if Set.isEmpty $ fst props'.selectedNodeIds then RH.div {} [] else - RH.button { className: "btn btn-info" + RH.button { className: "btn btn-sm btn-" <> btnType , on: { click: onClickRemove rType props' nodesMap' } } [ RH.text text ] @@ -183,9 +193,9 @@ onClickRemove rType props' nodesMap' e = do badge :: R.State SigmaxT.NodeIds -> Record SigmaxT.Node -> R.Element badge (_ /\ setNodeIds) {id, label} = - RH.a { className: "badge badge-light" + RH.a { className: "badge badge-pill badge-light" , on: { click: onClick } - } [ RH.text label ] + } [ RH.h6 {} [ RH.text label ] ] where onClick e = do setNodeIds $ const $ Set.singleton id @@ -200,11 +210,11 @@ neighbourBadges graph (selectedNodeIds /\ _) = SigmaxT.neighbours graph selected type DeleteNodes = - ( graphId :: Int - , metaData :: GET.MetaData - , nodes :: Array (Record SigmaxT.Node) - , session :: Session - , termList :: TermList + ( graphId :: Int + , metaData :: GET.MetaData + , nodes :: Array (Record SigmaxT.Node) + , session :: Session + , termList :: TermList , treeReload :: GUR.ReloadS ) @@ -332,6 +342,3 @@ Global/local view: To explore the neighborhood of a selection click on the 'change level' button. -} - - - diff --git a/src/Gargantext/Components/GraphExplorer/SlideButton.purs b/src/Gargantext/Components/GraphExplorer/SlideButton.purs index 611724824d6c046afd148801f37447ea25621128..960db598990103efea7ce512240d2d4a97b9a6b0 100644 --- a/src/Gargantext/Components/GraphExplorer/SlideButton.purs +++ b/src/Gargantext/Components/GraphExplorer/SlideButton.purs @@ -51,7 +51,7 @@ labelSizeButton sigmaRef state = sizeButton { state , caption: "Label Size" - , min: 5.0 + , min: 1.0 , max: 30.0 , onChange: \e -> do let sigma = R.readRef sigmaRef @@ -61,7 +61,8 @@ labelSizeButton sigmaRef state = Sigma.setSettings s { defaultLabelSize: newValue , drawLabels: true - , labelSizeRatio: newValue / 2.5 + , maxNodeSize: newValue / 2.5 + --, labelSizeRatio: newValue / 2.5 } setValue $ const newValue } diff --git a/src/Gargantext/Components/InputWithEnter.purs b/src/Gargantext/Components/InputWithEnter.purs index 9fa798b3c831a567fe0fca24f9a6464572861c3d..320fac2ba7034edbc0abc043410662abdc1d9289 100644 --- a/src/Gargantext/Components/InputWithEnter.purs +++ b/src/Gargantext/Components/InputWithEnter.purs @@ -1,7 +1,5 @@ module Gargantext.Components.InputWithEnter where -import Data.Tuple.Nested ((/\)) -import DOM.Simple.Console (log2) import Effect (Effect) import Reactix as R import Reactix.DOM.HTML as H @@ -9,6 +7,7 @@ import Reactix.DOM.HTML as H import Gargantext.Prelude import Gargantext.Utils.Reactix as R2 +thisModule :: String thisModule = "Gargantext.Components.InputWithEnter" type Props a = ( @@ -16,7 +15,6 @@ type Props a = ( , onValueChanged :: String -> Effect Unit , autoFocus :: Boolean - , autoSave :: Boolean , className :: String , defaultValue :: String , placeholder :: String @@ -25,14 +23,13 @@ type Props a = ( inputWithEnter :: forall a. Record (Props a) -> R.Element inputWithEnter props = R.createElement inputWithEnterCpt props [] - where - inputWithEnterCpt :: forall a. R.Component (Props a) - inputWithEnterCpt = R.hooksComponentWithModule thisModule "inputWithEnter" cpt +inputWithEnterCpt :: forall a. R.Component (Props a) +inputWithEnterCpt = R.hooksComponentWithModule thisModule "inputWithEnter" cpt + where cpt props@{ onEnter, onValueChanged - , autoFocus, autoSave, className, defaultValue, placeholder } _ = do - pure $ H.input { on: { blur: \_ -> if autoSave then onEnter unit else pure unit - , input: onInput + , autoFocus, className, defaultValue, placeholder } _ = do + pure $ H.input { on: { input: onInput , keyPress: onKeyPress } , autoFocus , className @@ -41,8 +38,7 @@ inputWithEnter props = R.createElement inputWithEnterCpt props [] , type: props.type } where - onInput e = do - onValueChanged $ R.unsafeEventValue e + onInput e = onValueChanged $ R.unsafeEventValue e onKeyPress e = do char <- R2.keyCode e diff --git a/src/Gargantext/Components/NgramsTable.purs b/src/Gargantext/Components/NgramsTable.purs index f2b607a6e665ae4a74db304228ef2af7ca987c0f..b0a060f67559048d487368867f3ff1655eda57c8 100644 --- a/src/Gargantext/Components/NgramsTable.purs +++ b/src/Gargantext/Components/NgramsTable.purs @@ -274,10 +274,9 @@ type Props = ( loadedNgramsTable :: R2.Component Props loadedNgramsTable = R.createElement loadedNgramsTableCpt +loadedNgramsTableCpt :: R.Component Props +loadedNgramsTableCpt = R.hooksComponentWithModule thisModule "loadedNgramsTable" cpt where - loadedNgramsTableCpt :: R.Component Props - loadedNgramsTableCpt = R.hooksComponentWithModule thisModule "loadedNgramsTable" cpt - cpt props@{ afterSync , appReload , asyncTasksRef @@ -524,10 +523,9 @@ type MainNgramsTableProps = ( mainNgramsTable :: R2.Component MainNgramsTableProps mainNgramsTable = R.createElement mainNgramsTableCpt +mainNgramsTableCpt :: R.Component MainNgramsTableProps +mainNgramsTableCpt = R.hooksComponentWithModule thisModule "mainNgramsTable" cpt where - mainNgramsTableCpt :: R.Component MainNgramsTableProps - mainNgramsTableCpt = R.hooksComponentWithModule thisModule "mainNgramsTable" cpt - cpt props@{ afterSync , appReload , asyncTasksRef @@ -631,10 +629,10 @@ type MainNgramsTablePaintProps = ( mainNgramsTablePaint :: R2.Component MainNgramsTablePaintProps mainNgramsTablePaint = R.createElement mainNgramsTablePaintCpt - where - mainNgramsTablePaintCpt :: R.Component MainNgramsTablePaintProps - mainNgramsTablePaintCpt = R.hooksComponentWithModule thisModule "mainNgramsTablePaint" cpt +mainNgramsTablePaintCpt :: R.Component MainNgramsTablePaintProps +mainNgramsTablePaintCpt = R.hooksComponentWithModule thisModule "mainNgramsTablePaint" cpt + where cpt props@{ afterSync , appReload , asyncTasksRef @@ -670,10 +668,10 @@ type MainNgramsTablePaintNoCacheProps = ( mainNgramsTablePaintNoCache :: R2.Component MainNgramsTablePaintNoCacheProps mainNgramsTablePaintNoCache = R.createElement mainNgramsTablePaintNoCacheCpt - where - mainNgramsTablePaintNoCacheCpt :: R.Component MainNgramsTablePaintNoCacheProps - mainNgramsTablePaintNoCacheCpt = R.hooksComponentWithModule thisModule "mainNgramsTablePaintNoCache" cpt +mainNgramsTablePaintNoCacheCpt :: R.Component MainNgramsTablePaintNoCacheProps +mainNgramsTablePaintNoCacheCpt = R.hooksComponentWithModule thisModule "mainNgramsTablePaintNoCache" cpt + where cpt props@{ afterSync , appReload , asyncTasksRef diff --git a/src/Gargantext/Components/NgramsTable/Core.purs b/src/Gargantext/Components/NgramsTable/Core.purs index ce7836a7039b7c50faba7c686d2febc9b61b28ba..71fe576ee5e5e4e9ea41f5df3fed33be5d73f549 100644 --- a/src/Gargantext/Components/NgramsTable/Core.purs +++ b/src/Gargantext/Components/NgramsTable/Core.purs @@ -1129,10 +1129,10 @@ type SyncResetButtonsProps = syncResetButtons :: Record SyncResetButtonsProps -> R.Element syncResetButtons p = R.createElement syncResetButtonsCpt p [] - where - syncResetButtonsCpt :: R.Component SyncResetButtonsProps - syncResetButtonsCpt = R.hooksComponentWithModule thisModule "syncResetButtons" cpt +syncResetButtonsCpt :: R.Component SyncResetButtonsProps +syncResetButtonsCpt = R.hooksComponentWithModule thisModule "syncResetButtons" cpt + where cpt { afterSync, ngramsLocalPatch, performAction } _ = do synchronizing@(s /\ setSynchronizing) <- R.useState' false diff --git a/src/Gargantext/Components/Nodes/Annuaire.purs b/src/Gargantext/Components/Nodes/Annuaire.purs index 31985610e6c3ef7d966272067c600c49b11ddda7..3e9b4f4438bef105484fd5395ecfe09078ca501f 100644 --- a/src/Gargantext/Components/Nodes/Annuaire.purs +++ b/src/Gargantext/Components/Nodes/Annuaire.purs @@ -104,8 +104,7 @@ annuaireCpt = R.hooksComponentWithModule thisModule "annuaire" cpt , title: name , user: "" } , H.p {} [] - , H.div {className: "col-md-3"} - [ H.text " Filter ", H.input { className: "form-control", style } ] + -- , H.div {className: "col-md-3"} [ H.text " Filter ", H.input { className: "form-control", style } ] , H.br {} , pageLayout { info, session, pagePath, frontends} ] where @@ -164,7 +163,7 @@ pageCpt = R.hooksComponentWithModule thisModule "page" cpt , session } , delete: false }) <$> Seq.fromFoldable docs container = T.defaultContainer { title: "Annuaire" } -- TODO - colNames = T.ColumnName <$> [ "", "First Name", "Last Name", "Company", "Lab", "Role"] + colNames = T.ColumnName <$> [ "", "First Name", "Last Name", "Company", "Role"] wrapColElts = const identity setParams f = snd pagePath $ \pp@{params: ps} -> pp {params = f ps} @@ -199,26 +198,27 @@ contactCellsCpt = R.hooksComponentWithModule thisModule "contactCells" cpt ] cpt { annuaireId , contact: (CT.NodeContact { id - , hyperdata: ( CT.HyperdataContact { who : Just (CT.ContactWho { firstName - , lastName - } - ) - } - ) - } + , hyperdata: ( CT.HyperdataContact + { who : Just (CT.ContactWho { firstName + , lastName + } + ) + , ou : ou + } + ) + } ) , frontends , session } _ = do pure $ T.makeRow [ H.text "" - , H.text $ fromMaybe "First Name" firstName + , H.a { target: "_blank", href: contactUrl annuaireId id} [H.text $ fromMaybe "First Name" firstName] , H.text $ fromMaybe "First Name" lastName - , H.text "CNRS" -- , H.a { href } [ H.text $ fromMaybe "name" contact.title ] --, H.a { href, target: "blank" } [ H.text $ fromMaybe "name" contact.title ] - --, H.text $ maybe "No ContactWhere" contactWhereOrg (A.head $ ou) - -- , H.text $ maybe "No ContactWhereDept" contactWhereDept (A.head $ ou) + , H.text $ maybe "No ContactWhere" contactWhereOrg (A.head $ ou) + , H.text $ maybe "No ContactWhereDept" contactWhereDept (A.head $ ou) -- , H.div {className: "nooverflow"} [ -- H.text $ maybe "No ContactWhereRole" contactWhereRole (A.head $ ou) ] @@ -226,6 +226,7 @@ contactCellsCpt = R.hooksComponentWithModule thisModule "contactCells" cpt --nodepath = NodePath (sessionId session) NodeContact (Just id) nodepath = Routes.ContactPage (sessionId session) annuaireId id href = url frontends nodepath + contactUrl aId id = url frontends $ Routes.ContactPage (sessionId session) annuaireId id contactWhereOrg (CT.ContactWhere { organization: [] }) = "No Organization" contactWhereOrg (CT.ContactWhere { organization: orga }) = diff --git a/src/Gargantext/Components/Nodes/Annuaire/Tabs.purs b/src/Gargantext/Components/Nodes/Annuaire/Tabs.purs new file mode 100644 index 0000000000000000000000000000000000000000..99f6f70bd5e502b229078586360454b792008ee5 --- /dev/null +++ b/src/Gargantext/Components/Nodes/Annuaire/Tabs.purs @@ -0,0 +1,179 @@ +-- TODO copy of Gargantext.Components.Nodes.Corpus.Tabs.Specs +module Gargantext.Components.Nodes.Annuaire.User.Tabs where + +import Prelude hiding (div) +import Data.Generic.Rep (class Generic) +import Data.Generic.Rep.Show (genericShow) +import Data.Maybe (Maybe(..)) +import Data.Tuple (fst) +import Data.Tuple.Nested ((/\)) +import Effect (Effect) +import Reactix as R + +import Gargantext.AsyncTasks as GAT +import Gargantext.Components.DocsTable as DT +import Gargantext.Components.NgramsTable as NT +import Gargantext.Components.NgramsTable.Core as NTC +import Gargantext.Components.Tab as Tab +import Gargantext.Components.Nodes.Annuaire.User.Contacts.Types (ContactData) +import Gargantext.Components.Nodes.Lists.Types as LTypes +import Gargantext.Components.Nodes.Texts.Types as TTypes +import Gargantext.Ends (Frontends) +import Gargantext.Sessions (Session) +import Gargantext.Types (CTabNgramType(..), NodeID, PTabNgramType(..), TabType(..), TabSubType(..)) +import Gargantext.Utils.Reactix as R2 +import Gargantext.Utils.Reload as GUR + +thisModule :: String +thisModule = "Gargantext.Components.Nodes.Annuaire.User.Contacts.Tabs" + + +data Mode = Patents | Books | Communication + +derive instance genericMode :: Generic Mode _ + +instance showMode :: Show Mode where + show = genericShow + +derive instance eqMode :: Eq Mode + +modeTabType :: Mode -> PTabNgramType +modeTabType Patents = PTabPatents +modeTabType Books = PTabBooks +modeTabType Communication = PTabCommunication + +-- TODO fix this type +modeTabType' :: Mode -> CTabNgramType +modeTabType' Patents = CTabAuthors +modeTabType' Books = CTabAuthors +modeTabType' Communication = CTabAuthors + +type TabsProps = ( + appReload :: GUR.ReloadS + , asyncTasksRef :: R.Ref (Maybe GAT.Reductor) + , cacheState :: R.State LTypes.CacheState + , contactData :: ContactData + , frontends :: Frontends + , nodeId :: Int + , session :: Session + , sidePanelTriggers :: Record LTypes.SidePanelTriggers + , treeReloadRef :: GUR.ReloadWithInitializeRef + ) + +tabs :: Record TabsProps -> R.Element +tabs props = R.createElement tabsCpt props [] + +tabsCpt :: R.Component TabsProps +tabsCpt = R.hooksComponentWithModule thisModule "tabs" cpt + where + cpt { appReload + , asyncTasksRef + , cacheState + , contactData: {defaultListId} + , frontends + , nodeId + , session + , sidePanelTriggers + , treeReloadRef } _ = do + active <- R.useState' 0 + textsSidePanelTriggers <- TTypes.emptySidePanelTriggers + pure $ Tab.tabs { selected: fst active, tabs: tabs' textsSidePanelTriggers } + where + tabs' trg = + [ "Documents" /\ docs trg + , "Patents" /\ ngramsView patentsView [] + , "Books" /\ ngramsView booksView [] + , "Communication" /\ ngramsView commView [] + , "Trash" /\ docs trg -- TODO pass-in trash mode + ] + where + patentsView = { appReload + , asyncTasksRef + , cacheState + , defaultListId + , mode: Patents + , nodeId + , session + , sidePanelTriggers + , treeReloadRef } + booksView = { appReload + , asyncTasksRef + , cacheState + , defaultListId + , mode: Books + , nodeId + , session + , sidePanelTriggers + , treeReloadRef } + commView = { appReload, asyncTasksRef + , cacheState + , defaultListId + , mode: Communication + , nodeId + , session + , sidePanelTriggers + , treeReloadRef } + chart = mempty + totalRecords = 4736 -- TODO + docs sidePanelTriggers = DT.docViewLayout + { cacheState + , chart + , frontends + , listId: defaultListId + , mCorpusId: Nothing + , nodeId + , session + , showSearch: true + , sidePanelTriggers + , tabType: TabPairing TabDocs + , totalRecords + } + + +type NgramsViewTabsProps = ( + appReload :: GUR.ReloadS + , asyncTasksRef :: R.Ref (Maybe GAT.Reductor) + , cacheState :: R.State LTypes.CacheState + , defaultListId :: Int + , mode :: Mode + , nodeId :: Int + , session :: Session + , sidePanelTriggers :: Record LTypes.SidePanelTriggers + , treeReloadRef :: GUR.ReloadWithInitializeRef + ) + +ngramsView :: R2.Component NgramsViewTabsProps +ngramsView = R.createElement ngramsViewCpt + +ngramsViewCpt :: R.Component NgramsViewTabsProps +ngramsViewCpt = R.hooksComponentWithModule thisModule "ngramsView" cpt + where + cpt { appReload + , asyncTasksRef + , cacheState + , defaultListId + , mode + , nodeId + , session + , sidePanelTriggers + , treeReloadRef } _ = do + pathS <- R.useState' $ NTC.initialPageParams session nodeId [defaultListId] (TabDocument TabDocs) + + pure $ NT.mainNgramsTable { + appReload + , afterSync: \_ -> pure unit + , asyncTasksRef + , cacheState + , defaultListId + , nodeId + , pathS + , tabType + , session + , sidePanelTriggers + , tabNgramType + , treeReloadRef + , withAutoUpdate: false + } [] + where + tabNgramType = modeTabType' mode + tabType = TabPairing $ TabNgramType $ modeTabType mode diff --git a/src/Gargantext/Components/Nodes/Annuaire/User/Contacts.purs b/src/Gargantext/Components/Nodes/Annuaire/User.purs similarity index 77% rename from src/Gargantext/Components/Nodes/Annuaire/User/Contacts.purs rename to src/Gargantext/Components/Nodes/Annuaire/User.purs index a2197c80273d1b9899a1010eae5ebabea466d24f..e45c0c6653e19de016374cd1270dcefe1b62b7b3 100644 --- a/src/Gargantext/Components/Nodes/Annuaire/User/Contacts.purs +++ b/src/Gargantext/Components/Nodes/Annuaire/User.purs @@ -1,7 +1,7 @@ -module Gargantext.Components.Nodes.Annuaire.User.Contacts +module Gargantext.Components.Nodes.Annuaire.User ( module Gargantext.Components.Nodes.Annuaire.User.Contacts.Types - , annuaireUserLayout - , userLayout ) + , userLayout + ) where import DOM.Simple.Console (log2) @@ -17,7 +17,7 @@ import Reactix.DOM.HTML as H import Gargantext.AsyncTasks as GAT import Gargantext.Components.InputWithEnter (inputWithEnter) -import Gargantext.Components.Nodes.Annuaire.User.Contacts.Tabs as Tabs +import Gargantext.Components.Nodes.Annuaire.User.Tabs as Tabs import Gargantext.Components.Nodes.Annuaire.User.Contacts.Types (Contact(..), ContactData, ContactTouch(..), ContactWhere(..), ContactWho(..), HyperdataContact(..), HyperdataUser(..), _city, _country, _firstName, _labTeamDeptsJoinComma, _lastName, _mail, _office, _organizationJoinComma, _ouFirst, _phone, _role, _shared, _touch, _who, defaultContactTouch, defaultContactWhere, defaultContactWho, defaultHyperdataContact, defaultHyperdataUser) import Gargantext.Components.Nodes.Lists.Types as LT import Gargantext.Ends (Frontends) @@ -30,7 +30,7 @@ import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reload as GUR thisModule :: String -thisModule = "Gargantext.Components.Nodes.Annuaire.User.Contacts" +thisModule = "Gargantext.Components.Nodes.Annuaire.User" type DisplayProps = ( title :: String @@ -128,7 +128,6 @@ contactInfoItemCpt = R.hooksComponentWithModule thisModule "contactInfoItem" cpt H.div { className: "input-group col-sm-6" } [ inputWithEnter { autoFocus: true - , autoSave: false , className: "form-control" , defaultValue: R.readRef valueRef , onEnter: onClick @@ -150,8 +149,8 @@ contactInfoItemCpt = R.hooksComponentWithModule thisModule "contactInfoItem" cpt listElement :: Array R.Element -> R.Element listElement = H.li { className: "list-group-item justify-content-between" } -type LayoutProps = ( - appReload :: GUR.ReloadS +type LayoutProps = + ( appReload :: GUR.ReloadS , asyncTasksRef :: R.Ref (Maybe GAT.Reductor) , frontends :: Frontends , nodeId :: Int @@ -196,10 +195,11 @@ userLayoutWithKeyCpt = R.hooksComponentWithModule thisModule "userLayoutWithKey" sidePanelTriggers <- LT.emptySidePanelTriggers - useLoader {nodeId, reload: GUR.value reload, session} getContactWithReload $ + useLoader {nodeId, reload: GUR.value reload, session} getUserWithReload $ \contactData@{contactNode: Contact {name, hyperdata}} -> H.ul { className: "col-md-12 list-group" } [ - display { title: fromMaybe "no name" name } (contactInfos hyperdata (onUpdateHyperdata reload)) + display { title: fromMaybe "no name" name } + (contactInfos hyperdata (onUpdateHyperdata reload)) , Tabs.tabs { appReload , asyncTasksRef @@ -219,10 +219,10 @@ userLayoutWithKeyCpt = R.hooksComponentWithModule thisModule "userLayoutWithKey" _ <- saveContactHyperdata session nodeId hd liftEffect $ GUR.bump reload --- | toUrl to get data +-- | toUrl to get data XXX getContact :: Session -> Int -> Aff ContactData getContact session id = do - contactNode <- get session $ Routes.NodeAPI Node (Just id) "" + contactNode :: Contact <- get session $ Routes.NodeAPI Node (Just id) "" -- TODO: we need a default list for the pairings --defaultListIds <- get $ toUrl endConfigStateful Back (Children NodeList 0 1 Nothing) $ Just id --case (head defaultListIds :: Maybe (NodePoly HyperdataList)) of @@ -232,59 +232,10 @@ getContact session id = do -- throwError $ error "Missing default list" pure {contactNode, defaultListId: 424242} -getContactWithReload :: {nodeId :: Int, reload :: GUR.Reload, session :: Session} -> Aff ContactData -getContactWithReload {nodeId, session} = getContact session nodeId +getUserWithReload :: {nodeId :: Int, reload :: GUR.Reload, session :: Session} -> Aff ContactData +getUserWithReload {nodeId, session} = getContact session nodeId saveContactHyperdata :: Session -> Int -> HyperdataUser -> Aff Int saveContactHyperdata session id h = do put session (Routes.NodeAPI Node (Just id) "") h - -type AnnuaireLayoutProps = ( - annuaireId :: Int - | LayoutProps ) - - -annuaireUserLayout :: Record AnnuaireLayoutProps -> R.Element -annuaireUserLayout props = R.createElement annuaireUserLayoutCpt props [] - -annuaireUserLayoutCpt :: R.Component AnnuaireLayoutProps -annuaireUserLayoutCpt = R.hooksComponentWithModule thisModule "annuaireUserLayout" cpt - where - cpt { annuaireId, appReload, asyncTasksRef, frontends, nodeId, session, treeReloadRef } _ = do - cacheState <- R.useState' LT.CacheOn - - sidePanelTriggers <- LT.emptySidePanelTriggers - - useLoader nodeId (getAnnuaireContact session annuaireId) $ - \contactData@{contactNode: Contact {name, hyperdata}} -> - H.ul { className: "col-md-12 list-group" } [ - display { title: fromMaybe "no name" name } (contactInfos hyperdata onUpdateHyperdata) - , Tabs.tabs { - appReload - , asyncTasksRef - , cacheState - , contactData - , frontends - , nodeId - , session - , sidePanelTriggers - , treeReloadRef - } - ] - - where - onUpdateHyperdata :: HyperdataUser -> Effect Unit - onUpdateHyperdata _ = pure unit - -getAnnuaireContact :: Session -> Int -> Int -> Aff ContactData -getAnnuaireContact session annuaireId id = do - contactNode <- get session $ Routes.NodeAPI Annuaire (Just annuaireId) $ "contact/" <> (show id) - -- TODO: we need a default list for the pairings - --defaultListIds <- get $ toUrl endConfigStateful Back (Children NodeList 0 1 Nothing) $ Just id - --case (head defaultListIds :: Maybe (NodePoly HyperdataList)) of - -- Just (NodePoly { id: defaultListId }) -> - -- pure {contactNode, defaultListId} - -- Nothing -> - -- throwError $ error "Missing default list" - pure {contactNode, defaultListId: 424242} diff --git a/src/Gargantext/Components/Nodes/Annuaire/User/Contact.purs b/src/Gargantext/Components/Nodes/Annuaire/User/Contact.purs new file mode 100644 index 0000000000000000000000000000000000000000..654a88ea9c2fb4b226215d594c49596add78606f --- /dev/null +++ b/src/Gargantext/Components/Nodes/Annuaire/User/Contact.purs @@ -0,0 +1,244 @@ +module Gargantext.Components.Nodes.Annuaire.User.Contact + ( module Gargantext.Components.Nodes.Annuaire.User.Contacts.Types + , contactLayout + ) + where + +import DOM.Simple.Console (log2) +import Data.Lens as L +import Data.Maybe (Maybe(..), fromMaybe) +import Data.Tuple (Tuple(..), fst, snd) +import Data.Tuple.Nested ((/\)) +import Effect (Effect) +import Effect.Aff (Aff, launchAff_) +import Effect.Class (liftEffect) +import Reactix as R +import Reactix.DOM.HTML as H + +import Gargantext.AsyncTasks as GAT +import Gargantext.Components.InputWithEnter (inputWithEnter) +import Gargantext.Components.Nodes.Annuaire.User.Contacts.Tabs as Tabs +import Gargantext.Components.Nodes.Annuaire.User.Contacts.Types (Contact'(..), ContactData', ContactTouch(..), ContactWhere(..), ContactWho(..), HyperdataContact(..), HyperdataUser(..), _city, _country, _firstName, _labTeamDeptsJoinComma, _lastName, _mail, _office, _organizationJoinComma, _ouFirst, _phone, _role, _shared, _touch, _who, defaultContactTouch, defaultContactWhere, defaultContactWho, defaultHyperdataContact, defaultHyperdataUser) +import Gargantext.Components.Nodes.Lists.Types as LT +import Gargantext.Ends (Frontends) +import Gargantext.Hooks.Loader (useLoader) +import Gargantext.Prelude (Unit, bind, const, discard, pure, show, unit, ($), (+), (<$>), (<<<), (<>), (==)) +import Gargantext.Routes as Routes +import Gargantext.Sessions (Session, get, put, sessionId) +import Gargantext.Types (NodeType(..)) +import Gargantext.Utils.Reactix as R2 +import Gargantext.Utils.Reload as GUR + +thisModule :: String +thisModule = "Gargantext.Components.Nodes.Annuaire.User.Contacts" + +type DisplayProps = ( + title :: String + ) + +display :: R2.Component DisplayProps +display = R.createElement displayCpt + +displayCpt :: R.Component DisplayProps +displayCpt = R.hooksComponentWithModule thisModule "display" cpt + where + cpt { title } children = do + pure $ H.div { className: "container-fluid" } + [ H.div { className: "row", id: "contact-page-header" } + [ H.div { className: "col-md-6"} [ H.h3 {} [ H.text title ] ] + , H.div { className: "col-md-8"} [] + , H.div { className: "col-md-2"} [ H.span {} [ H.text "" ] ] + ] + , H.div { className: "row", id: "contact-page-info" } + [ H.div { className: "col-md-12" } + [ H.div { className: "row" } + [ H.div { className: "col-md-2" } [ H.img { src: "/images/Gargantextuel-212x300.jpg"} ] + , H.div { className: "col-md-1"} [] + , H.div { className: "col-md-8"} children + ]]]] + +-- | TODO format data in better design (UI) shape +contactInfos :: HyperdataContact -> (HyperdataContact -> Effect Unit) -> Array R.Element +contactInfos h onUpdateHyperdata = item <$> contactInfoItems + where + item {label, defaultVal, lens} = + contactInfoItem { hyperdata: h + , label + , lens + , onUpdateHyperdata + , placeholder: defaultVal } + +contactInfoItems :: Array {label:: String, defaultVal:: String, lens:: HyperdataContactLens} +contactInfoItems = + [ {label: "Last Name" , defaultVal: "Empty Last Name" , lens: _who <<< _lastName } + , {label: "First Name" , defaultVal: "Empty First Name" , lens: _who <<< _firstName } + , {label: "Organisation" , defaultVal: "Empty Organisation" , lens: _ouFirst <<< _organizationJoinComma} + , {label: "Lab/Team/Dept", defaultVal: "Empty Lab/Team/Dept", lens: _ouFirst <<< _labTeamDeptsJoinComma} + , {label: "Office" , defaultVal: "Empty Office" , lens: _ouFirst <<< _office } + , {label: "City" , defaultVal: "Empty City" , lens: _ouFirst <<< _city } + , {label: "Country" , defaultVal: "Empty Country" , lens: _ouFirst <<< _country } + , {label: "Role" , defaultVal: "Empty Role" , lens: _ouFirst <<< _role } + , {label: "Phone" , defaultVal: "Empty Phone" , lens: _ouFirst <<< _touch <<< _phone } + , {label: "Mail" , defaultVal: "Empty Mail" , lens: _ouFirst <<< _touch <<< _mail } + ] + +type HyperdataContactLens = L.ALens' HyperdataContact String + +type ContactInfoItemProps = + ( hyperdata :: HyperdataContact + , label :: String + , lens :: HyperdataContactLens + , onUpdateHyperdata :: HyperdataContact -> Effect Unit + , placeholder :: String + ) + +contactInfoItem :: Record ContactInfoItemProps -> R.Element +contactInfoItem props = R.createElement contactInfoItemCpt props [] + +contactInfoItemCpt :: R.Component ContactInfoItemProps +contactInfoItemCpt = R.hooksComponentWithModule thisModule "contactInfoItem" cpt + where + cpt {hyperdata, label, lens, onUpdateHyperdata, placeholder} _ = do + isEditing <- R.useState' false + let value = (L.view cLens hyperdata) :: String + valueRef <- R.useRef value + + pure $ H.div { className: "form-group row" } [ + H.span { className: "col-sm-2 col-form-label" } [ H.text label ] + , item isEditing valueRef + ] + + where + cLens = L.cloneLens lens + item (false /\ setIsEditing) valueRef = + H.div { className: "input-group col-sm-6" } [ + H.input { className: "form-control" + , defaultValue: placeholder + , disabled: 1 + , type: "text" } + , H.div { className: "btn input-group-append" + , on: { click: onClick } } [ + H.div { className: "input-group-text fa fa-pencil" } [] + ] + ] + where + placeholder = R.readRef valueRef + onClick _ = setIsEditing $ const true + item (true /\ setIsEditing) valueRef = + H.div { className: "input-group col-sm-6" } [ + inputWithEnter { + autoFocus: true + , className: "form-control" + , defaultValue: R.readRef valueRef + , onEnter: onClick + , onValueChanged: R.setRef valueRef + , placeholder + , type: "text" + } + , H.div { className: "btn input-group-append" + , on: { click: onClick } } [ + H.div { className: "input-group-text fa fa-floppy-o" } [] + ] + ] + where + onClick _ = do + setIsEditing $ const false + let newHyperdata = (L.over cLens (\_ -> R.readRef valueRef) hyperdata) :: HyperdataContact + onUpdateHyperdata newHyperdata + +listElement :: Array R.Element -> R.Element +listElement = H.li { className: "list-group-item justify-content-between" } + +type LayoutProps = + ( appReload :: GUR.ReloadS + , asyncTasksRef :: R.Ref (Maybe GAT.Reductor) + , frontends :: Frontends + , nodeId :: Int + , session :: Session + , treeReloadRef :: GUR.ReloadWithInitializeRef + ) + +type KeyLayoutProps = ( + key :: String + | LayoutProps + ) + + +saveContactHyperdata :: Session -> Int -> HyperdataContact -> Aff Int +saveContactHyperdata session id h = do + put session (Routes.NodeAPI Node (Just id) "") h + + +type AnnuaireLayoutProps = ( annuaireId :: Int | LayoutProps ) +type AnnuaireKeyLayoutProps = ( key :: String | AnnuaireLayoutProps ) + + +contactLayout :: Record AnnuaireLayoutProps -> R.Element +contactLayout props = R.createElement contactLayoutCpt props [] + +contactLayoutCpt :: R.Component AnnuaireLayoutProps +contactLayoutCpt = R.hooksComponentWithModule thisModule "contactLayout" cpt + where + cpt { annuaireId, appReload, asyncTasksRef, frontends, nodeId, session, treeReloadRef } _ = do + let sid = sessionId session + + pure $ contactLayoutWithKey { annuaireId, + appReload + , asyncTasksRef + , frontends + , key: show sid <> "-" <> show nodeId + , nodeId + , session + , treeReloadRef + } + +contactLayoutWithKey :: Record AnnuaireKeyLayoutProps -> R.Element +contactLayoutWithKey props = R.createElement contactLayoutWithKeyCpt props [] + +contactLayoutWithKeyCpt :: R.Component AnnuaireKeyLayoutProps +contactLayoutWithKeyCpt = R.hooksComponentWithModule thisModule "contactLayoutWithKey" cpt + where + cpt { annuaireId, appReload, asyncTasksRef, frontends, nodeId, session, treeReloadRef } _ = do + reload <- GUR.new + + cacheState <- R.useState' LT.CacheOn + + sidePanelTriggers <- LT.emptySidePanelTriggers + + useLoader nodeId (getAnnuaireContact session annuaireId) $ + \contactData@{contactNode: Contact' {name, hyperdata}} -> + H.ul { className: "col-md-12 list-group" } + [ display { title: fromMaybe "no name" name } + (contactInfos hyperdata (onUpdateHyperdata reload)) + , Tabs.tabs { + appReload + , asyncTasksRef + , cacheState + , contactData + , frontends + , nodeId + , session + , sidePanelTriggers + , treeReloadRef + } + ] + where + onUpdateHyperdata :: GUR.ReloadS -> HyperdataContact -> Effect Unit + onUpdateHyperdata reload hd = do + launchAff_ $ do + _ <- saveContactHyperdata session nodeId hd + liftEffect $ GUR.bump reload + + + +getAnnuaireContact :: Session -> Int -> Int -> Aff ContactData' +getAnnuaireContact session annuaireId id = do + contactNode :: Contact' <- get session $ Routes.NodeAPI Annuaire (Just annuaireId) $ show id + -- TODO: we need a default list for the pairings + --defaultListIds <- get $ toUrl endConfigStateful Back (Children NodeList 0 1 Nothing) $ Just id + --case (head defaultListIds :: Maybe (NodePoly HyperdataList)) of + -- Just (NodePoly { id: defaultListId }) -> + -- pure {contactNode, defaultListId} + -- Nothing -> + -- throwError $ error "Missing default list" + pure {contactNode, defaultListId: 424242} diff --git a/src/Gargantext/Components/Nodes/Annuaire/User/Contacts/Tabs.purs b/src/Gargantext/Components/Nodes/Annuaire/User/Contacts/Tabs.purs index 501c959df5290efceb88772c3edfb131c63321a1..d23818faf20e289bdcea2bb10bb9c14478713f62 100644 --- a/src/Gargantext/Components/Nodes/Annuaire/User/Contacts/Tabs.purs +++ b/src/Gargantext/Components/Nodes/Annuaire/User/Contacts/Tabs.purs @@ -15,7 +15,7 @@ import Gargantext.Components.DocsTable as DT import Gargantext.Components.NgramsTable as NT import Gargantext.Components.NgramsTable.Core as NTC import Gargantext.Components.Tab as Tab -import Gargantext.Components.Nodes.Annuaire.User.Contacts.Types (ContactData) +import Gargantext.Components.Nodes.Annuaire.User.Contacts.Types (ContactData') import Gargantext.Components.Nodes.Lists.Types as LTypes import Gargantext.Components.Nodes.Texts.Types as TTypes import Gargantext.Ends (Frontends) @@ -52,7 +52,7 @@ type TabsProps = ( appReload :: GUR.ReloadS , asyncTasksRef :: R.Ref (Maybe GAT.Reductor) , cacheState :: R.State LTypes.CacheState - , contactData :: ContactData + , contactData :: ContactData' , frontends :: Frontends , nodeId :: Int , session :: Session @@ -144,10 +144,10 @@ type NgramsViewTabsProps = ( ngramsView :: R2.Component NgramsViewTabsProps ngramsView = R.createElement ngramsViewCpt - where - ngramsViewCpt :: R.Component NgramsViewTabsProps - ngramsViewCpt = R.hooksComponentWithModule thisModule "ngramsView" cpt +ngramsViewCpt :: R.Component NgramsViewTabsProps +ngramsViewCpt = R.hooksComponentWithModule thisModule "ngramsView" cpt + where cpt { appReload , asyncTasksRef , cacheState diff --git a/src/Gargantext/Components/Nodes/Annuaire/User/Contacts/Types.purs b/src/Gargantext/Components/Nodes/Annuaire/User/Contacts/Types.purs index 9d5d278214ab14c94c78c9f96d21e1707efc4f6c..d33d3350511a3f9262cd6127839a557f71035572 100644 --- a/src/Gargantext/Components/Nodes/Annuaire/User/Contacts/Types.purs +++ b/src/Gargantext/Components/Nodes/Annuaire/User/Contacts/Types.purs @@ -23,14 +23,14 @@ newtype NodeContact = instance decodeNodeContact :: DecodeJson NodeContact where decodeJson json = do - obj <- decodeJson json - date <- obj .?| "date" + obj <- decodeJson json + date <- obj .?| "date" hyperdata <- obj .: "hyperdata" - id <- obj .: "id" - name <- obj .:! "name" - parentId <- obj .?| "parentId" - typename <- obj .?| "typename" - userId <- obj .:! "userId" + id <- obj .: "id" + name <- obj .:! "name" + parentId <- obj .?| "parentId" + typename <- obj .?| "typename" + userId <- obj .:! "userId" pure $ NodeContact { id , date @@ -43,8 +43,43 @@ instance decodeNodeContact :: DecodeJson NodeContact where derive instance newtypeNodeContact :: Newtype NodeContact _ +---------------------------------------------------------------------------- +newtype Contact' = + Contact' + { id :: Int + , date :: Maybe String + , hyperdata :: HyperdataContact + , name :: Maybe String + , parentId :: Maybe Int + , typename :: Maybe Int + , userId :: Maybe Int + } + + +instance decodeContact' :: DecodeJson Contact' where + decodeJson json = do + obj <- decodeJson json + date <- obj .?| "date" + hyperdata <- obj .: "hyperdata" + id <- obj .: "id" + name <- obj .:! "name" + parentId <- obj .?| "parentId" + typename <- obj .?| "typename" + userId <- obj .:! "userId" + + pure $ Contact' { id + , date + , hyperdata + , name + , parentId + , typename + , userId + } + +-- | TODO rename Contact with User +-- and fix shared decodeJson newtype Contact = Contact { id :: Int @@ -57,17 +92,16 @@ newtype Contact = } - -instance decodeUser :: DecodeJson Contact where +instance decodeContact :: DecodeJson Contact where decodeJson json = do - obj <- decodeJson json - date <- obj .?| "date" + obj <- decodeJson json + date <- obj .?| "date" hyperdata <- obj .: "hyperdata" - id <- obj .: "id" - name <- obj .:! "name" - parentId <- obj .?| "parentId" - typename <- obj .?| "typename" - userId <- obj .:! "userId" + id <- obj .: "id" + name <- obj .:! "name" + parentId <- obj .?| "parentId" + typename <- obj .?| "typename" + userId <- obj .:! "userId" pure $ Contact { id , date @@ -78,7 +112,39 @@ instance decodeUser :: DecodeJson Contact where , userId } -derive instance newtypeContact :: Newtype Contact _ +---------------------------------------------------------------------------- +newtype User = + User + { id :: Int + , date :: Maybe String + , hyperdata :: HyperdataUser + , name :: Maybe String + , parentId :: Maybe Int + , typename :: Maybe Int + , userId :: Maybe Int + } + + +instance decodeUser :: DecodeJson User where + decodeJson json = do + obj <- decodeJson json + date <- obj .?| "date" + hyperdata <- obj .: "hyperdata" + id <- obj .: "id" + name <- obj .:! "name" + parentId <- obj .?| "parentId" + typename <- obj .?| "typename" + userId <- obj .:! "userId" + + pure $ User { id + , date + , hyperdata + , name + , parentId + , typename + , userId + } + newtype ContactWho = ContactWho @@ -130,15 +196,15 @@ newtype ContactWhere = ContactWhere { organization :: (Array String) , labTeamDepts :: (Array String) - + , role :: Maybe String - + , office :: Maybe String , country :: Maybe String , city :: Maybe String - + , touch :: Maybe ContactTouch - + , entry :: Maybe String , exit :: Maybe String } @@ -226,15 +292,15 @@ defaultContactTouch = newtype HyperdataContact = - HyperdataContact { bdd :: Maybe String + HyperdataContact { bdd :: Maybe String , lastValidation :: Maybe String - , ou :: (Array ContactWhere) - , source :: Maybe String - , title :: Maybe String - , uniqId :: Maybe String - , uniqIdBdd :: Maybe String - , who :: Maybe ContactWho - } + , ou :: (Array ContactWhere) + , source :: Maybe String + , title :: Maybe String + , uniqId :: Maybe String + , uniqIdBdd :: Maybe String + , who :: Maybe ContactWho + } derive instance newtypeHyperdataContact :: Newtype HyperdataContact _ instance decodeHyperdataContact :: DecodeJson HyperdataContact @@ -321,6 +387,7 @@ defaultHyperdataUser = -- pure $ HyperData {common, shared, specific} type ContactData = {contactNode :: Contact, defaultListId :: Int} +type ContactData' = {contactNode :: Contact', defaultListId :: Int} _shared :: Lens' HyperdataUser HyperdataContact _shared = lens getter setter diff --git a/src/Gargantext/Components/Nodes/Corpus.purs b/src/Gargantext/Components/Nodes/Corpus.purs index b1986f4132c03e19bd1f1fee8048c147ee960884..117b3f64edb412836f4526376388767bbb45c26a 100644 --- a/src/Gargantext/Components/Nodes/Corpus.purs +++ b/src/Gargantext/Components/Nodes/Corpus.purs @@ -21,7 +21,8 @@ import Gargantext.Prelude import Gargantext.Components.CodeEditor as CE import Gargantext.Components.InputWithEnter (inputWithEnter) 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.Hooks.Loader (useLoader) import Gargantext.Routes (SessionRoute(NodeAPI, Children)) @@ -58,7 +59,6 @@ corpusLayoutCpt = R.hooksComponentWithModule thisModule "corpusLayout" cpt corpusLayoutWithKey :: Record KeyProps -> R.Element corpusLayoutWithKey props = R.createElement corpusLayoutWithKeyCpt props [] - corpusLayoutWithKeyCpt :: R.Component KeyProps corpusLayoutWithKeyCpt = R.hooksComponentWithModule thisModule "corpusLayoutWithKey" cpt where @@ -74,12 +74,6 @@ type ViewProps = | 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 props = R.createElement corpusLayoutViewCpt props [] @@ -99,24 +93,25 @@ corpusLayoutViewCpt = R.hooksComponentWithModule thisModule "corpusLayoutView" c R.setRef fieldsRef fields snd fieldsS $ const fieldsWithIndex - pure $ H.div {} [ - H.div { className: "row" } [ - H.div { className: "btn btn-secondary " <> (saveEnabled fieldsWithIndex fieldsS) - , on: { click: onClickSave {fields: fieldsS, nodeId, reload, session} } - } [ - H.span { className: "fa fa-floppy-o" } [ ] - ] - ] - , H.div {} [ fieldsCodeEditor { fields: fieldsS - , nodeId - , session } ] - , H.div { className: "row" } [ - H.div { className: "btn btn-secondary" - , on: { click: onClickAdd fieldsS } - } [ - H.span { className: "fa fa-plus" } [ ] - ] - ] + pure $ H.div {} + [ H.div { className: "row" } + [ H.div { className: "btn btn-secondary " <> (saveEnabled fieldsWithIndex fieldsS) + , on: { click: onClickSave {fields: fieldsS, nodeId, reload, session} } + } + [ H.span { className: "fa fa-floppy-o" } [ ] + ] + ] + , H.div {} + [ fieldsCodeEditor { fields: fieldsS + , nodeId + , session } [] ] + , H.div { className: "row" } + [ H.div { className: "btn btn-secondary" + , on: { click: onClickAdd fieldsS } + } + [ H.span { className: "fa fa-plus" } [ ] + ] + ] ] saveEnabled :: FTFieldsWithIndex -> R.State FTFieldsWithIndex -> String @@ -127,7 +122,6 @@ corpusLayoutViewCpt = R.hooksComponentWithModule thisModule "corpusLayoutView" c , reload :: GUR.ReloadS , session :: Session } -> e -> Effect Unit onClickSave {fields: (fieldsS /\ _), nodeId, reload, session} _ = do - log2 "[corpusLayoutViewCpt] onClickSave fieldsS" fieldsS launchAff_ do saveCorpus $ { hyperdata: Hyperdata {fields: (\(Tuple _ f) -> f) <$> fieldsS} , nodeId @@ -144,14 +138,14 @@ type FieldsCodeEditorProps = | LoadProps ) -fieldsCodeEditor :: Record FieldsCodeEditorProps -> R.Element -fieldsCodeEditor props = R.createElement fieldsCodeEditorCpt props [] +fieldsCodeEditor :: R2.Component FieldsCodeEditorProps +fieldsCodeEditor = R.createElement fieldsCodeEditorCpt fieldsCodeEditorCpt :: R.Component FieldsCodeEditorProps fieldsCodeEditorCpt = R.hooksComponentWithModule thisModule "fieldsCodeEditorCpt" cpt where cpt {nodeId, fields: fS@(fields /\ _), session} _ = do - masterKey <- R.useState' 0 + masterKey <- GUR.new pure $ H.div {} $ List.toUnfoldable (editors masterKey) where @@ -175,13 +169,13 @@ fieldsCodeEditorCpt = R.hooksComponentWithModule thisModule "fieldsCodeEditorCpt List.modifyAt idx (\(Tuple _ (Field f)) -> Tuple idx (Field $ f { typ = typ })) fields onMoveDown :: GUR.ReloadS -> R.State FTFieldsWithIndex -> Index -> Unit -> Effect Unit - onMoveDown (_ /\ setMasterKey) (fs /\ setFields) idx _ = do - setMasterKey $ (+) 1 + onMoveDown masterKey (_ /\ setFields) idx _ = do + GUR.bump masterKey setFields $ recomputeIndices <<< (GDA.swapList idx (idx + 1)) onMoveUp :: GUR.ReloadS -> R.State FTFieldsWithIndex -> Index -> Unit -> Effect Unit - onMoveUp (_ /\ setMasterKey) (_ /\ setFields) idx _ = do - setMasterKey $ (+) 1 + onMoveUp masterKey (_ /\ setFields) idx _ = do + GUR.bump masterKey setFields $ recomputeIndices <<< (GDA.swapList idx (idx - 1)) onRemove :: R.State FTFieldsWithIndex -> Index -> Unit -> Effect Unit @@ -223,19 +217,17 @@ fieldCodeEditorWrapperCpt = R.hooksComponentWithModule thisModule "fieldCodeEdit pure $ H.div { className: "row card" } [ H.div { className: "card-header" } [ H.div { className: "code-editor-heading row" } [ - H.div { className: "col-sm-4" } [ + H.div { className: "col-4" } [ renameable {onRename, text: name} ] - , H.div { className: "col-sm-7" } [] - , H.div { className: "buttons-right col-sm-1" } [ + , H.div { className: "col-7" } [] + , H.div { className: "buttons-right col-1" } ([ H.div { className: "btn btn-danger" , on: { click: \_ -> onRemove unit } } [ H.span { className: "fa fa-trash" } [ ] ] - , moveDownButton canMoveDown - , moveUpButton canMoveUp - ] + ] <> moveButtons) ] ] , H.div { className: "card-body" } [ @@ -243,15 +235,15 @@ fieldCodeEditorWrapperCpt = R.hooksComponentWithModule thisModule "fieldCodeEdit ] ] where - moveDownButton false = H.div {} [] - moveDownButton true = + moveButtons = [] <> (if canMoveDown then [moveDownButton] else []) + <> (if canMoveUp then [moveUpButton] else []) + moveDownButton = H.div { className: "btn btn-secondary" , on: { click: \_ -> onMoveDown unit } } [ H.span { className: "fa fa-arrow-down" } [ ] ] - moveUpButton false = H.div {} [] - moveUpButton true = + moveUpButton = H.div { className: "btn btn-secondary" , on: { click: \_ -> onMoveUp unit } } [ @@ -301,32 +293,31 @@ renameableTextCpt :: R.Component RenameableTextProps renameableTextCpt = R.hooksComponentWithModule thisModule "renameableTextCpt" cpt where cpt {isEditing: (false /\ setIsEditing), state: (text /\ _)} _ = do - pure $ H.div { className: "input-group" } [ - H.input { className: "form-control" - , defaultValue: text - , disabled: 1 - , type: "text" } + pure $ H.div { className: "input-group" } + [ H.input { className: "form-control" + , defaultValue: text + , disabled: 1 + , type: "text" } , H.div { className: "btn input-group-append" - , on: { click: \_ -> setIsEditing $ const true } } [ - H.span { className: "fa fa-pencil" } [] - ] + , on: { click: \_ -> setIsEditing $ const true } } + [ H.span { className: "fa fa-pencil" } [] + ] ] cpt {isEditing: (true /\ setIsEditing), onRename, state: (text /\ setText)} _ = do - pure $ H.div { className: "input-group" } [ - inputWithEnter { - autoFocus: false - , autoSave: false - , className: "form-control text" - , defaultValue: text - , onEnter: submit - , onValueChanged: setText <<< const - , placeholder: "" - , type: "text" - } + pure $ H.div { className: "input-group" } + [ inputWithEnter { + autoFocus: false + , className: "form-control text" + , defaultValue: text + , onEnter: submit + , onValueChanged: setText <<< const + , placeholder: "" + , type: "text" + } , H.div { className: "btn input-group-append" - , on: { click: submit } } [ - H.span { className: "fa fa-floppy-o" } [] - ] + , on: { click: submit } } + [ H.span { className: "fa fa-floppy-o" } [] + ] ] where submit _ = do diff --git a/src/Gargantext/Components/Nodes/Corpus/Chart/Common.purs b/src/Gargantext/Components/Nodes/Corpus/Chart/Common.purs index 1667a3816e56ccabbe2b553e9c985f908b9310de..f376a08413b1c57617abf6e52a5ec1c954cfbd96 100644 --- a/src/Gargantext/Components/Nodes/Corpus/Chart/Common.purs +++ b/src/Gargantext/Components/Nodes/Corpus/Chart/Common.purs @@ -29,10 +29,10 @@ cacheName = "metrics" metricsLoadView :: forall a. Record (MetricsLoadViewProps a) -> R.Element metricsLoadView p = R.createElement metricsLoadViewCpt p [] - where - metricsLoadViewCpt :: R.Component (MetricsLoadViewProps a) - metricsLoadViewCpt = R.hooksComponentWithModule thisModule "metricsLoadView" cpt +metricsLoadViewCpt :: forall a. R.Component (MetricsLoadViewProps a) +metricsLoadViewCpt = R.hooksComponentWithModule thisModule "metricsLoadView" cpt + where cpt { getMetrics, loaded, path, reload, session } _ = do useLoader (fst reload /\ path) (getMetrics session) $ \l -> loaded { path, reload, session } l @@ -48,10 +48,11 @@ type MetricsWithCacheLoadViewProps res ret = ( metricsWithCacheLoadView :: forall res ret. DecodeJson res => Record (MetricsWithCacheLoadViewProps res ret) -> R.Element metricsWithCacheLoadView p = R.createElement metricsWithCacheLoadViewCpt p [] - where - metricsWithCacheLoadViewCpt :: R.Component (MetricsWithCacheLoadViewProps res ret) - metricsWithCacheLoadViewCpt = R.hooksComponentWithModule thisModule "metricsWithCacheLoadView" cpt +metricsWithCacheLoadViewCpt :: forall res ret. DecodeJson res => + R.Component (MetricsWithCacheLoadViewProps res ret) +metricsWithCacheLoadViewCpt = R.hooksComponentWithModule thisModule "metricsWithCacheLoadView" cpt + where cpt { getMetricsHash, handleResponse, loaded, mkRequest, path, reload, session } _ = do useLoaderWithCacheAPI { cacheEndpoint: (getMetricsHash session) , handleResponse diff --git a/src/Gargantext/Components/Nodes/Corpus/Chart/Histo.purs b/src/Gargantext/Components/Nodes/Corpus/Chart/Histo.purs index 5e5db7fdae686cf03e0815a2af434bd8f9763b32..cb0aed769cb71ff8ece8e81eeda828eabaf56240 100644 --- a/src/Gargantext/Components/Nodes/Corpus/Chart/Histo.purs +++ b/src/Gargantext/Components/Nodes/Corpus/Chart/Histo.purs @@ -81,10 +81,10 @@ mkRequest session (_ /\ path@{ corpusId, limit, listId, tabType }) = GUC.makeGet histo :: Record Props -> R.Element histo props = R.createElement histoCpt props [] - where - histoCpt :: R.Component Props - histoCpt = R.hooksComponentWithModule thisModule "histo" cpt +histoCpt :: R.Component Props +histoCpt = R.hooksComponentWithModule thisModule "histo" cpt + where cpt { path, session } _ = do reload <- R.useState' 0 pure $ metricsWithCacheLoadView { diff --git a/src/Gargantext/Components/Nodes/Corpus/Dashboard.purs b/src/Gargantext/Components/Nodes/Corpus/Dashboard.purs index dcf918c1e19761efbb24b8a4d2efcc1e20d91620..3a186b5973e8646dd83dcf72ae71b72900c68d54 100644 --- a/src/Gargantext/Components/Nodes/Corpus/Dashboard.purs +++ b/src/Gargantext/Components/Nodes/Corpus/Dashboard.purs @@ -1,25 +1,29 @@ module Gargantext.Components.Nodes.Corpus.Dashboard where -import DOM.Simple.Console (log2) +import Gargantext.Components.Nodes.Types +import Gargantext.Prelude + +import DOM.Simple.Console (log, log2) import Data.Array as A +import Data.List as List import Data.Maybe (Maybe(..), fromMaybe) -import Data.Tuple (fst) +import Data.Tuple (Tuple(..), snd) import Data.Tuple.Nested ((/\)) import Effect (Effect) import Effect.Aff (launchAff_) import Effect.Class (liftEffect) -import Reactix as R -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.Dashboard.Types as DT import Gargantext.Hooks.Loader (useLoader) -import Gargantext.Prelude import Gargantext.Sessions (Session, sessionId) import Gargantext.Types (NodeID) import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reload as GUR +import Reactix as R +import Reactix.DOM.HTML as H +thisModule :: String thisModule = "Gargantext.Components.Nodes.Corpus.Dashboard" type Props = @@ -27,8 +31,8 @@ type Props = , session :: Session ) -dashboardLayout :: Record Props -> R.Element -dashboardLayout props = R.createElement dashboardLayoutCpt props [] +dashboardLayout :: R2.Component Props +dashboardLayout = R.createElement dashboardLayoutCpt dashboardLayoutCpt :: R.Component Props dashboardLayoutCpt = R.hooksComponentWithModule thisModule "dashboardLayout" cpt @@ -36,15 +40,15 @@ dashboardLayoutCpt = R.hooksComponentWithModule thisModule "dashboardLayout" cpt cpt { nodeId, session } _ = do let sid = sessionId session - pure $ dashboardLayoutWithKey { key: show sid <> "-" <> show nodeId, nodeId, session } + pure $ dashboardLayoutWithKey { key: show sid <> "-" <> show nodeId, nodeId, session } [] type KeyProps = ( key :: String | Props ) -dashboardLayoutWithKey :: Record KeyProps -> R.Element -dashboardLayoutWithKey props = R.createElement dashboardLayoutWithKeyCpt props [] +dashboardLayoutWithKey :: R2.Component KeyProps +dashboardLayoutWithKey = R.createElement dashboardLayoutWithKeyCpt dashboardLayoutWithKeyCpt :: R.Component KeyProps dashboardLayoutWithKeyCpt = R.hooksComponentWithModule thisModule "dashboardLayoutWithKey" cpt @@ -54,20 +58,20 @@ dashboardLayoutWithKeyCpt = R.hooksComponentWithModule thisModule "dashboardLayo useLoader {nodeId, reload: GUR.value reload, session} DT.loadDashboardWithReload $ \dashboardData@{hyperdata: DT.Hyperdata h, parentId} -> do - let { charts } = h + let { charts, fields } = h dashboardLayoutLoaded { charts , corpusId: parentId , defaultListId: 0 - , key: show $ GUR.value reload + , fields , nodeId , onChange: onChange nodeId reload (DT.Hyperdata h) - , session } - + , session } [] where - onChange :: NodeID -> GUR.ReloadS -> DT.Hyperdata -> Array P.PredefinedChart -> Effect Unit - onChange nodeId' reload (DT.Hyperdata h) charts = do + onChange :: NodeID -> GUR.ReloadS -> DT.Hyperdata -> { charts :: Array P.PredefinedChart + , fields :: List.List FTField } -> Effect Unit + onChange nodeId' reload (DT.Hyperdata h) { charts, fields } = do launchAff_ do - DT.saveDashboard { hyperdata: DT.Hyperdata $ h { charts = charts } + DT.saveDashboard { hyperdata: DT.Hyperdata $ h { charts = charts, fields = fields } , nodeId:nodeId' , session } liftEffect $ GUR.bump reload @@ -76,38 +80,113 @@ type LoadedProps = ( charts :: Array P.PredefinedChart , corpusId :: NodeID , defaultListId :: Int - , key :: String - , onChange :: Array P.PredefinedChart -> Effect Unit + , fields :: List.List FTField + , onChange :: { charts :: Array P.PredefinedChart + , fields :: List.List FTField } -> Effect Unit | Props ) -dashboardLayoutLoaded :: Record LoadedProps -> R.Element -dashboardLayoutLoaded props = R.createElement dashboardLayoutLoadedCpt props [] +dashboardLayoutLoaded :: R2.Component LoadedProps +dashboardLayoutLoaded = R.createElement dashboardLayoutLoadedCpt dashboardLayoutLoadedCpt :: R.Component LoadedProps dashboardLayoutLoadedCpt = R.hooksComponentWithModule thisModule "dashboardLayoutLoaded" cpt where - cpt props@{ charts, corpusId, defaultListId, onChange, session } _ = do - pure $ - H.div {} ([ H.h1 {} [ H.text "Board" ] - , H.p {} [ H.text "Summary of all your charts here" ] - ] <> chartsEls <> [addNew]) + cpt props@{ charts, corpusId, defaultListId, fields, nodeId, onChange, session } _ = do + 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]) + ] + , dashboardCodeEditor { fields + , nodeId + , onChange: \fs -> onChange { charts, fields: fs } + , session } [] + ] where addNew = H.div { className: "row" } [ 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 - onClickAdd _ = onChange $ A.cons P.CDocsHistogram charts + onClickAddChart _ = onChange { charts: A.cons P.CDocsHistogram charts + , fields } chartsEls = A.mapWithIndex chartIdx charts chartIdx idx chart = - renderChart { chart, corpusId, defaultListId, onChange: onChangeChart, onRemove, session } + renderChart { chart, corpusId, defaultListId, onChange: onChangeChart, onRemove, session } [] where onChangeChart c = do - log2 "[dashboardLayout] idx" idx - log2 "[dashboardLayout] new chart" c - onChange $ fromMaybe charts (A.modifyAt idx (\_ -> c) charts) - onRemove _ = onChange $ fromMaybe charts $ A.deleteAt idx charts + onChange { charts: fromMaybe charts (A.modifyAt idx (\_ -> c) charts) + , fields } + onRemove _ = onChange { charts: fromMaybe charts $ A.deleteAt idx charts + , fields } + +type CodeEditorProps = + ( fields :: List.List FTField + , onChange :: List.List FTField -> Effect Unit + | Props + ) + +dashboardCodeEditor :: R2.Component CodeEditorProps +dashboardCodeEditor = R.createElement dashboardCodeEditorCpt + +dashboardCodeEditorCpt :: R.Component CodeEditorProps +dashboardCodeEditorCpt = R.hooksComponentWithModule thisModule "dashboardCodeEditor" cpt + where + cpt props@{ 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 $ R.fragment + [ H.div { className: "row" } + [ H.div { className: "btn btn-secondary " <> (saveEnabled fieldsWithIndex fieldsS) + , on: { click: onClickSave fieldsS } + } + [ H.span { className: "fa fa-floppy-o" } [ ] + ] + ] + , 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 + saveEnabled :: FTFieldsWithIndex -> R.State FTFieldsWithIndex -> String + saveEnabled fs (fsS /\ _) = if fs == fsS then "disabled" else "enabled" + + onClickSave :: forall e. R.State FTFieldsWithIndex -> e -> Effect Unit + onClickSave (fields /\ _) _ = do + log "[dashboardCodeEditor] saving (TODO)" + onChange $ snd <$> fields + -- launchAff_ do + -- saveCorpus $ { hyperdata: Hyperdata {fields: (\(Tuple _ f) -> f) <$> fieldsS} + -- , nodeId + -- , session } + + onClickAddField :: forall e. R.State FTFieldsWithIndex -> e -> Effect Unit + onClickAddField (_ /\ setFieldsS) _ = do + setFieldsS $ \fieldsS -> List.snoc fieldsS $ Tuple (List.length fieldsS) defaultField type PredefinedChartProps = ( chart :: P.PredefinedChart @@ -118,28 +197,33 @@ type PredefinedChartProps = , session :: Session ) -renderChart :: Record PredefinedChartProps -> R.Element -renderChart props = R.createElement renderChartCpt props [] +renderChart :: R2.Component PredefinedChartProps +renderChart = R.createElement renderChartCpt renderChartCpt :: R.Component PredefinedChartProps renderChartCpt = R.hooksComponentWithModule thisModule "renderChart" cpt where cpt { chart, corpusId, defaultListId, onChange, onRemove, session } _ = do - pure $ H.div { className: "chart" } - [ H.div { className: "row" } - [ H.div { className: "col-2" } - [ R2.select { defaultValue: show chart - , on: { change: onSelectChange } - } (option <$> P.allPredefinedCharts) - ] - , H.div { className: "col-1" } - [ H.span { className: "btn btn-danger" - , on: { click: onRemoveClick }} [ H.span { className: "fa fa-trash" } [] ] + pure $ H.div { className: "row chart card" } + [ H.div { className: "card-header" } + [ H.div { className: "row" } + [ H.div { className: "col-2" } + [ R2.select { defaultValue: show chart + , on: { change: onSelectChange } + } (option <$> P.allPredefinedCharts) + ] + , H.div { className: "col-9" } [] + , H.div { className: "col-1" } + [ H.span { className: "btn btn-danger" + , on: { click: onRemoveClick }} [ H.span { className: "fa fa-trash" } [] ] + ] ] ] - , H.div { className: "row" } - [ H.div { className: "col-12 chart" } - [ P.render chart params ] + , H.div { className: "card-body" } + [ H.div { className: "row" } + [ H.div { className: "col-12 chart" } + [ P.render chart params ] + ] ] ] where diff --git a/src/Gargantext/Components/Nodes/Corpus/Document.purs b/src/Gargantext/Components/Nodes/Corpus/Document.purs index f09c9caafacd000b852d6134c9b3d524dca839f8..90e70f63ae71cf89ee7039fe2ef2915b4587c517 100644 --- a/src/Gargantext/Components/Nodes/Corpus/Document.purs +++ b/src/Gargantext/Components/Nodes/Corpus/Document.purs @@ -54,10 +54,10 @@ type DocViewProps = ( docView :: R2.Component DocViewProps docView = R.createElement docViewCpt - where - docViewCpt :: R.Component DocViewProps - docViewCpt = R.hooksComponentWithModule thisModule "docView" cpt +docViewCpt :: R.Component DocViewProps +docViewCpt = R.hooksComponentWithModule thisModule "docView" cpt + where cpt { path , loaded: loaded@{ ngramsTable: Versioned { data: initTable }, document } , state: state@({ ngramsVersion: version, ngramsLocalPatch } /\ _) diff --git a/src/Gargantext/Components/Nodes/Corpus/Types.purs b/src/Gargantext/Components/Nodes/Corpus/Types.purs index 38efb6e5393c5107a4a39383c46837dc607f89c7..ed628c295dd5bd469718035a6924d6d0cec9a058 100644 --- a/src/Gargantext/Components/Nodes/Corpus/Types.purs +++ b/src/Gargantext/Components/Nodes/Corpus/Types.purs @@ -1,25 +1,12 @@ module Gargantext.Components.Nodes.Corpus.Types where import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, (.:), (:=), (~>), jsonEmptyObject) -import Data.Argonaut.Decode.Error (JsonDecodeError(..)) 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 Gargantext.Components.Node (NodePoly) -import Gargantext.Prelude - -type Author = String -type Description = String -type Query = String -type Tag = String -type Title = String -type HaskellCode = String -type MarkdownText = String -type Hash = String +import Gargantext.Components.Nodes.Types (FTField, Field(..), FieldType(..), isJSON) +import Gargantext.Prelude (bind, pure, ($)) newtype Hyperdata = Hyperdata { fields :: List.List FTField } @@ -35,182 +22,6 @@ instance encodeHyperdata :: EncodeJson Hyperdata where "fields" := fields ~> 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 = CorpusInfo { title :: String , authors :: String @@ -232,3 +43,18 @@ instance decodeCorpusInfo :: DecodeJson CorpusInfo where type CorpusData = { corpusId :: Int , corpusNode :: NodePoly Hyperdata -- CorpusInfo , 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 + } diff --git a/src/Gargantext/Components/Nodes/Dashboard/Types.purs b/src/Gargantext/Components/Nodes/Dashboard/Types.purs index 13066d4566c82aac7ce3efc3169a6258fcfcb42a..3b38d5382314dc367c14157a7b60c556cdf85928 100644 --- a/src/Gargantext/Components/Nodes/Dashboard/Types.purs +++ b/src/Gargantext/Components/Nodes/Dashboard/Types.purs @@ -1,9 +1,12 @@ module Gargantext.Components.Nodes.Dashboard.Types where import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, (.:), (.:?), (:=), (~>), jsonEmptyObject) +import Data.List as List import Data.Maybe (Maybe(..)) import Effect.Aff (Aff) + import Gargantext.Components.Nodes.Corpus.Chart.Predefined as P +import Gargantext.Components.Nodes.Types (FTField, Field(..), FieldType(..), isJSON) import Gargantext.Prelude import Gargantext.Routes (SessionRoute(NodeAPI)) import Gargantext.Sessions (Session, get, put) @@ -14,17 +17,20 @@ type Preferences = Maybe String newtype Hyperdata = Hyperdata { charts :: Array P.PredefinedChart + , fields :: List.List FTField , preferences :: Preferences } instance decodeHyperdata :: DecodeJson Hyperdata where decodeJson json = do obj <- decodeJson json charts <- obj .: "charts" + fields <- obj .: "fields" preferences <- obj .:? "preferences" - pure $ Hyperdata {charts, preferences} + pure $ Hyperdata {charts, fields, preferences} instance encodeHyperdata :: EncodeJson Hyperdata where - encodeJson (Hyperdata {charts, preferences}) = do + encodeJson (Hyperdata {charts, fields, preferences}) = do "charts" := charts + ~> "fields" := fields ~> "preferences" := preferences ~> jsonEmptyObject diff --git a/src/Gargantext/Components/Nodes/Lists.purs b/src/Gargantext/Components/Nodes/Lists.purs index 4d09837d96dcbfac4882b4bee771820aab971609..668fa11689f8860f63f653ebeb36598214056492 100644 --- a/src/Gargantext/Components/Nodes/Lists.purs +++ b/src/Gargantext/Components/Nodes/Lists.purs @@ -35,10 +35,10 @@ type ListsWithForest = ( listsWithForest :: R2.Component ListsWithForest listsWithForest = R.createElement listsWithForestCpt - where - listsWithForestCpt :: R.Component ListsWithForest - listsWithForestCpt = R.hooksComponentWithModule thisModule "listsWithForest" cpt +listsWithForestCpt :: R.Component ListsWithForest +listsWithForestCpt = R.hooksComponentWithModule thisModule "listsWithForest" cpt + where cpt { forestProps , listsProps: listsProps@{ session } } _ = do controls <- initialControls @@ -58,10 +58,10 @@ type TopBarProps = ( topBar :: R2.Component TopBarProps topBar = R.createElement topBarCpt - where - topBarCpt :: R.Component TopBarProps - topBarCpt = R.hooksComponentWithModule thisModule "topBar" cpt +topBarCpt :: R.Component TopBarProps +topBarCpt = R.hooksComponentWithModule thisModule "topBar" cpt + where cpt { controls } _ = do -- empty for now because the button is moved to the side panel pure $ H.div {} [] @@ -93,10 +93,10 @@ type WithTreeProps = ( listsLayout :: R2.Component Props listsLayout = R.createElement listsLayoutCpt - where - listsLayoutCpt :: R.Component Props - listsLayoutCpt = R.hooksComponentWithModule thisModule "listsLayout" cpt +listsLayoutCpt :: R.Component Props +listsLayoutCpt = R.hooksComponentWithModule thisModule "listsLayout" cpt + where cpt path@{ nodeId, session } _ = do let sid = sessionId session @@ -109,10 +109,10 @@ type KeyProps = ( listsLayoutWithKey :: Record KeyProps -> R.Element listsLayoutWithKey props = R.createElement listsLayoutWithKeyCpt props [] - where - listsLayoutWithKeyCpt :: R.Component KeyProps - listsLayoutWithKeyCpt = R.hooksComponentWithModule thisModule "listsLayoutWithKey" cpt +listsLayoutWithKeyCpt :: R.Component KeyProps +listsLayoutWithKeyCpt = R.hooksComponentWithModule thisModule "listsLayoutWithKey" cpt + where cpt { appReload , asyncTasksRef , controls @@ -122,7 +122,7 @@ listsLayoutWithKey props = R.createElement listsLayoutWithKeyCpt props [] , treeReloadRef } _ = do let path = { nodeId, session } - cacheState <- R.useState' $ getCacheState CacheOff session nodeId + cacheState <- R.useState' $ getCacheState CacheOn session nodeId useLoader path loadCorpusWithChild $ \corpusData@{ corpusId, corpusNode: NodePoly poly, defaultListId } -> @@ -164,10 +164,10 @@ type SidePanelProps = ( sidePanel :: R2.Component SidePanelProps sidePanel = R.createElement sidePanelCpt - where - sidePanelCpt :: R.Component SidePanelProps - sidePanelCpt = R.hooksComponentWithModule thisModule "sidePanel" cpt +sidePanelCpt :: R.Component SidePanelProps +sidePanelCpt = R.hooksComponentWithModule thisModule "sidePanel" cpt + where cpt { controls: { triggers: { toggleSidePanel , triggerSidePanel } } @@ -208,10 +208,10 @@ type SidePanelDocView = ( sidePanelDocView :: R2.Component SidePanelDocView sidePanelDocView = R.createElement sidePanelDocViewCpt - where - sidePanelDocViewCpt :: R.Component SidePanelDocView - sidePanelDocViewCpt = R.hooksComponentWithModule thisModule "sidePanelDocView" cpt +sidePanelDocViewCpt :: R.Component SidePanelDocView +sidePanelDocViewCpt = R.hooksComponentWithModule thisModule "sidePanelDocView" cpt + where cpt { session } _ = do -- pure $ H.h4 {} [ H.text txt ] pure $ H.div {} [ H.text "Hello ngrams" ] diff --git a/src/Gargantext/Components/Nodes/Types.purs b/src/Gargantext/Components/Nodes/Types.purs new file mode 100644 index 0000000000000000000000000000000000000000..f2e59ffce3c12b9cc86fd08f9b89ed2ebdb255f6 --- /dev/null +++ b/src/Gargantext/Components/Nodes/Types.purs @@ -0,0 +1,189 @@ +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 + } diff --git a/src/Gargantext/Components/Search.purs b/src/Gargantext/Components/Search.purs index a2c2fd76c14b8bef0900881a6c0556c22cde6c27..774f488bdd72169561dbbcb909aa18e6a8087481 100644 --- a/src/Gargantext/Components/Search.purs +++ b/src/Gargantext/Components/Search.purs @@ -58,9 +58,8 @@ instance encodeJsonSearchResult :: Argonaut.EncodeJson SearchResult where ------------------------------------------------------------------------ -data SearchResultTypes = - SearchResultDoc { docs :: Array Document} - | SearchNoResult { message :: String } +data SearchResultTypes = SearchResultDoc { docs :: Array Document} + | SearchNoResult { message :: String } | SearchResultContact { contacts :: Array Contact } derive instance eqSearchResultTypes :: Eq SearchResultTypes @@ -132,6 +131,7 @@ data Contact = , c_created :: String , c_hyperdata :: HyperdataRowContact , c_score :: Int + , c_annuaireId :: Int } derive instance eqContact :: Eq Contact diff --git a/src/Gargantext/Components/Tab.purs b/src/Gargantext/Components/Tab.purs index 71c97fbd35253bbd20ac4bf40c23df44ff410bb7..58a8824151afc4ef4d667cc6aa18b6ccd71a3cc1 100644 --- a/src/Gargantext/Components/Tab.purs +++ b/src/Gargantext/Components/Tab.purs @@ -14,7 +14,7 @@ thisModule = "Gargantext.Components.Tab" type TabsProps = ( selected :: Int - , tabs :: Array (Tuple String R.Element) + , tabs :: Array (Tuple String R.Element) ) tabs :: Record TabsProps -> R.Element @@ -29,17 +29,23 @@ tabsCpt = R.hooksComponentWithModule thisModule "tabs" cpt pure $ H.div {} [ H.nav {} - [ H.div { className: "nav nav-tabs" - , title : "Tab for ngrams" - } - (mapWithIndex (button setActiveTab activeTab) props.tabs) ] - , H.div { className: "tab-content" } $ mapWithIndex (item activeTab) props.tabs ] + [ H.br {} + , H.div { className: "nav nav-tabs" + , title : "Search result" + } -- [H.text "" ] + (mapWithIndex (button setActiveTab activeTab) props.tabs) + ] + , H.div { className: "tab-content" } + $ mapWithIndex (item activeTab) props.tabs + ] + --{- button setActiveTab selected index (name /\ _) = H.a { className, on: { click } } [ H.text name ] where eq = index == selected className = "nav-item nav-link" <> (if eq then " active" else "") click e = setActiveTab (const index) + --} item selected index (_ /\ cpt') = tab { selected, index } [ cpt' ] -- TODO: document what these are (selection, item indices) diff --git a/src/Gargantext/Components/Table.purs b/src/Gargantext/Components/Table.purs index ed36d7ec2a82f1ed06ff429dce482871c152c016..18aca2d80a45a482bb43c9f98c8aa8bb538054d7 100644 --- a/src/Gargantext/Components/Table.purs +++ b/src/Gargantext/Components/Table.purs @@ -58,10 +58,9 @@ initialParams = stateParams {page: 1, pageSize: PS10, orderBy: Nothing, searchTy tableHeaderLayout :: Record TableHeaderLayoutProps -> R.Element tableHeaderLayout props = R.createElement tableHeaderLayoutCpt props [] +tableHeaderLayoutCpt :: R.Component TableHeaderLayoutProps +tableHeaderLayoutCpt = R.hooksComponentWithModule thisModule "tableHeaderLayout" cpt where - tableHeaderLayoutCpt :: R.Component TableHeaderLayoutProps - tableHeaderLayoutCpt = R.hooksComponentWithModule thisModule "tableHeaderLayout" cpt - cpt { afterCacheStateChange, cacheState, date, desc, query, title, user } _ = pure $ R.fragment [ R2.row @@ -115,10 +114,9 @@ tableHeaderLayout props = R.createElement tableHeaderLayoutCpt props [] table :: Record Props -> R.Element table props = R.createElement tableCpt props [] +tableCpt :: R.Component Props +tableCpt = R.hooksComponentWithModule thisModule "table" cpt where - tableCpt :: R.Component Props - tableCpt = R.hooksComponentWithModule thisModule "table" cpt - cpt {container, syncResetButton, colNames, wrapColElts, totalRecords, rows, params} _ = do let state = paramsState $ fst params @@ -194,10 +192,10 @@ type SizeDDProps = sizeDD :: Record SizeDDProps -> R.Element sizeDD p = R.createElement sizeDDCpt p [] - where - sizeDDCpt :: R.Component SizeDDProps - sizeDDCpt = R.hooksComponentWithModule thisModule "sizeDD" cpt +sizeDDCpt :: R.Component SizeDDProps +sizeDDCpt = R.hooksComponentWithModule thisModule "sizeDD" cpt + where cpt {params: params /\ setParams} _ = do pure $ H.span {} [ R2.select { className, defaultValue: show pageSize, on: {change} } sizes diff --git a/src/Gargantext/Components/TopBar.purs b/src/Gargantext/Components/TopBar.purs index 7b7c17c6f1754ecd20e803925ec61508ddcadf39..51c47f62bd1d203449920641303ee0f4a7f5b5fd 100644 --- a/src/Gargantext/Components/TopBar.purs +++ b/src/Gargantext/Components/TopBar.purs @@ -151,10 +151,10 @@ type MenuButtonProps = ( menuButton :: R2.Component MenuButtonProps menuButton = R.createElement menuButtonCpt - where - menuButtonCpt :: R.Component MenuButtonProps - menuButtonCpt = R.hooksComponentWithModule thisModule "menuButton" cpt +menuButtonCpt :: R.Component MenuButtonProps +menuButtonCpt = R.hooksComponentWithModule thisModule "menuButton" cpt + where cpt { element: LiNav { title, href, icon, text }, show: (_ /\ setShow) } _ = do pure $ H.a { className: "dropdown-toggle navbar-text" -- , data: {toggle: "dropdown"} @@ -173,10 +173,10 @@ type MenuElementsProps = ( menuElements :: R2.Component MenuElementsProps menuElements = R.createElement menuElementsCpt - where - menuElementsCpt :: R.Component MenuElementsProps - menuElementsCpt = R.hooksComponentWithModule thisModule "menuElements" cpt +menuElementsCpt :: R.Component MenuElementsProps +menuElementsCpt = R.hooksComponentWithModule thisModule "menuElements" cpt + where cpt { show: false /\ _ } _ = do pure $ H.div {} [] cpt { elements, show: (true /\ setShow) } _ = do diff --git a/src/Gargantext/Ends.purs b/src/Gargantext/Ends.purs index 48a1ce434160c115dc5b0d7a1925a815ec238916..76b64d2d4af56e924f97d4e4c0062b2415a7973b 100644 --- a/src/Gargantext/Ends.purs +++ b/src/Gargantext/Ends.purs @@ -222,6 +222,7 @@ sessionPath (R.ChartHash { chartType, listId, tabType } i) = <> defaultListAddMaybe listId -- sessionPath (R.NodeAPI (NodeContact s a i) i) = sessionPath $ "annuaire/" <> show a <> "/contact/" <> show i + ------- misc routing stuff defaultList :: Int -> String diff --git a/src/Gargantext/Routes.purs b/src/Gargantext/Routes.purs index a87b59d165dffb2191112b8a6e55362e15ad3bd7..5099f83ee104a126716e0a3447afba5ccecae460 100644 --- a/src/Gargantext/Routes.purs +++ b/src/Gargantext/Routes.purs @@ -5,39 +5,36 @@ import Prelude import Data.Maybe (Maybe(..)) import Gargantext.Types (ChartOpts, ChartType, CorpusMetricOpts, CTabNgramType, Id, Limit, - ListId, NgramsGetOpts, NgramsGetTableAllOpts, NodeType, + ListId, DocId, ContactId, NgramsGetOpts, NgramsGetTableAllOpts, NodeType, Offset, OrderBy, SearchOpts, SessionId, TabSubType, TabType, TermList) import Gargantext.Types as GT data AppRoute - = Annuaire SessionId Int + = Annuaire SessionId Int | ContactPage SessionId Int Int - | Corpus SessionId Int + | Corpus SessionId Int | CorpusDocument SessionId Int Int Int | Dashboard SessionId Int | Document SessionId Int Int - | Folder SessionId Int - | FolderPrivate SessionId Int - | FolderPublic SessionId Int - | FolderShared SessionId Int + | Folder SessionId Int + | FolderPrivate SessionId Int + | FolderPublic SessionId Int + | FolderShared SessionId Int | Home | Lists SessionId Int | Login - | PGraphExplorer SessionId Int + | PGraphExplorer SessionId Int | RouteFile SessionId Int | RouteFrameCalc SessionId Int | RouteFrameCode SessionId Int | RouteFrameWrite SessionId Int - | Team SessionId Int - | Texts SessionId Int - | UserPage SessionId Int + | Team SessionId Int + | Texts SessionId Int + | UserPage SessionId Int derive instance eqAppRoute :: Eq AppRoute -type AnnuaireId = Int -type ContactId = Int - data SessionRoute = Tab TabType (Maybe Id) | Children NodeType Offset Limit (Maybe OrderBy) (Maybe Id) @@ -53,12 +50,13 @@ data SessionRoute | TreeFirstLevel (Maybe Id) String | GraphAPI Id String | ListsRoute ListId - | ListDocument (Maybe ListId) (Maybe Id) + | ListDocument (Maybe ListId) (Maybe DocId) | Search SearchOpts (Maybe Id) | CorpusMetrics CorpusMetricOpts (Maybe Id) | CorpusMetricsHash { listId :: ListId, tabType :: TabType } (Maybe Id) | Chart ChartOpts (Maybe Id) | ChartHash { chartType :: ChartType, listId :: Maybe ListId, tabType :: TabType } (Maybe Id) + -- | AnnuaireContact AnnuaireId DocId instance showAppRoute :: Show AppRoute where show Home = "Home" diff --git a/src/Gargantext/Types.purs b/src/Gargantext/Types.purs index d5aa8428abded261c007e82c84621a856d6027da..515270c9a165da4672faf7a27ae9f2a5dbd1c88e 100644 --- a/src/Gargantext/Types.purs +++ b/src/Gargantext/Types.purs @@ -333,8 +333,11 @@ nodeTypePath (NodePublic nt) = nodeTypePath nt nodeTypePath NodeFile = "file" ------------------------------------------------------------ - -type ListId = Int +type CorpusId = Int +type DocId = Int +type ListId = Int +type AnnuaireId = Int +type ContactId = Int data ScoreType = Occurrences diff --git a/src/Gargantext/Utils/Reactix.purs b/src/Gargantext/Utils/Reactix.purs index dde7ac15a5e97121ebba09bc88d97bcfb0b527c1..708fe3791279425f4cf291555d68ebaf582c652e 100644 --- a/src/Gargantext/Utils/Reactix.purs +++ b/src/Gargantext/Utils/Reactix.purs @@ -45,6 +45,35 @@ import Web.Storage.Storage (Storage, getItem, setItem) type Component p = Record p -> Array R.Element -> R.Element +-- newtypes +type NTHooksComponent props = props -> Array R.Element -> R.Hooks R.Element +newtype NTComponent p = NTComponent (EffectFn1 p R.Element) + +class NTIsComponent component (props :: Type) children + | component -> props, component -> children where + ntCreateElement :: component -> props -> children -> R.Element + +instance componentIsNTComponent :: NTIsComponent (NTComponent props) props (Array R.Element) where + ntCreateElement = R.rawCreateElement + +-- | Turns a `HooksComponent` function into a Component +ntHooksComponent :: forall props. String -> NTHooksComponent props -> NTComponent props +ntHooksComponent name c = NTComponent $ named name $ mkEffectFn1 c' + where + c' :: props -> Effect R.Element + c' props = R.runHooks $ c props (children props) + +ntHooksComponentWithModule :: forall props. Module -> String -> NTHooksComponent props -> NTComponent props +ntHooksComponentWithModule module' name c = ntHooksComponent (module' <> "." <> name) c + +--------------------------- +-- TODO Copied from reactix, export these: +children :: forall a. a -> Array R.Element +children a = react .. "Children" ... "toArray" $ [ (a .. "children") ] + +type Module = String +--------------------------- + newtype Point = Point { x :: Number, y :: Number } -- a reducer function living in effector, for useReductor diff --git a/src/Gargantext/Utils/Reload.purs b/src/Gargantext/Utils/Reload.purs index bec2bd4ff439e48116082ac945a1b462ee60b26b..461d0490a7bdf7a058b67a4f2234e6d9a3e01c88 100644 --- a/src/Gargantext/Utils/Reload.purs +++ b/src/Gargantext/Utils/Reload.purs @@ -1,7 +1,7 @@ module Gargantext.Utils.Reload where import Data.Maybe (Maybe(..), fromMaybe) -import Data.Tuple.Nested((/\)) +import Data.Tuple.Nested ((/\)) import Effect (Effect) import Reactix as R diff --git a/src/sass/_annotation.sass b/src/sass/_annotation.sass index c95373b827beda5dc2811f3a0fdf736b0e705909..491cf067b8f18227274891ac9c87ad8bb2d6fbb1 100644 --- a/src/sass/_annotation.sass +++ b/src/sass/_annotation.sass @@ -3,56 +3,52 @@ // $annotation-stop-color: #f00 // Copied from bootstrap's bg-warning, bg-success, bg-danger: -$annotation-candidate-color: #FF9800 -$annotation-graph-color: #43A047 -$annotation-stop-color: #E53935 +$annotation-graph-color: #95D29593 +$annotation-candidate-color: #B8B8B876 +$annotation-stop-color: #F5949931 + +@mixin lg1($color) + color: #000 + background-color: $color @mixin lg2($color1, $color2) + color: #000 background-image: linear-gradient(rgba($color1, 0.5), rgba($color1, 0.5)), linear-gradient(rgba($color2, 0.5), rgba($color2, 0.5)) @mixin lg3($color1, $color2, $color3) + color: #000 background-image: linear-gradient(rgba($color1, 0.34), rgba($color1, 0.34)), linear-gradient(rgba($color2, 0.33), rgba($color2, 0.33)), linear-gradient(rgba($color3, 0.33), rgba($color3, 0.33)) .annotation-run cursor: pointer &.candidate-term.graph-term.stop-term - color: #000 @include lg3($annotation-candidate-color, $annotation-graph-color, $annotation-stop-color) &.candidate-term.graph-term - color: #000 @include lg2($annotation-candidate-color, $annotation-graph-color) &.candidate-term.stop-term - color: #000 @include lg2($annotation-candidate-color, $annotation-stop-color) &.graph-term.stop-term - color: #000 @include lg2($annotation-graph-color, $annotation-stop-color) &.candidate-term - color: #000 - background-color: $annotation-candidate-color + @include lg1($annotation-candidate-color) &.graph-term - color: #000 - background-color: $annotation-graph-color + @include lg1($annotation-graph-color) &.stop-term - color: #000 - background-color: $annotation-stop-color + @include lg1($annotation-stop-color) .context-menu .candidate-term - color: #000 - background-color: $annotation-candidate-color + @include lg1($annotation-candidate-color) .graph-term - color: #000 - background-color: $annotation-graph-color + @include lg1($annotation-graph-color) .stop-term - color: #000 - background-color: $annotation-stop-color + @include lg1($annotation-stop-color) diff --git a/src/sass/_code_editor.sass b/src/sass/_code_editor.sass index 47d400a1f99771ae70d65acdfdf8b1242a24cf99..cc62ee9cae882a4b123cd2142558c0432c18a31a 100644 --- a/src/sass/_code_editor.sass +++ b/src/sass/_code_editor.sass @@ -20,24 +20,16 @@ word-break: keep-all .code-editor-heading - display: flex - //justify-content: space-between .renameable flex-grow: 2 .text padding-right: 10px - .buttons-right - display: flex - justify-content: flex-end + /* .buttons-right + /* display: flex + /* justify-content: flex-end .code-editor - .toolbar - display: flex - justify-content: flex-start - width: 100% .editor - display: flex - width: 100% .code-area flex-grow: 1 max-height: 200px diff --git a/src/sass/sass.sass b/src/sass/sass.sass index 2370eff76f0472c7ed65e9f0307e0311451b2177..37c94f17002d9cc1698d3c9a195b6b96349eea01 100644 --- a/src/sass/sass.sass +++ b/src/sass/sass.sass @@ -6,3 +6,4 @@ @use "_code_editor.sass" @use "_styles.sass" @use "_range_slider.sass" +@use "_annotation.sass"