Verified Commit f34c8927 authored by Przemyslaw Kaminski's avatar Przemyslaw Kaminski

Merge branch 'dev' into 330-dev-minify

parents 1d4b4d2d e4531010
Pipeline #1806 canceled with stage
use nix
...@@ -226,46 +226,6 @@ li#rename #rename-a { ...@@ -226,46 +226,6 @@ li#rename #rename-a {
left: 125px; left: 125px;
} }
#node-popup-tooltip {
background-color: white;
border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px;
border-top-left-radius: 6px;
border-top-right-radius: 6px;
}
#node-popup-tooltip:hover {
border: none;
text-decoration: none;
}
#node-popup-tooltip .popup-container {
display: flex;
flex-direction: colum;
}
#node-popup-tooltip .popup-container > .card {
border: 1px solid rgba(0, 0, 0, 0.2);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
margin-bottom: 0px;
width: 34rem;
}
#node-popup-tooltip .popup-container > .card .fa-pencil {
color: black;
}
#node-popup-tooltip .popup-container > .card .card-body {
display: flex;
justify-content: center;
background-color: white;
border: none;
}
#node-popup-tooltip .popup-container > .card .card-body .spacer {
margin: 10px;
}
#node-popup-tooltip .popup-container .frame-search.card {
border: 1px solid rgba(0, 0, 0, 0.2);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
height: 600px;
width: 1000px;
}
#create-node-tooltip { #create-node-tooltip {
position: absolute; position: absolute;
left: 96px; left: 96px;
...@@ -481,6 +441,63 @@ li .leaf:hover a.settings { ...@@ -481,6 +441,63 @@ li .leaf:hover a.settings {
text-decoration: underline; text-decoration: underline;
} }
.subtree__node {
margin-top: 2px;
}
.subtree__node__text {
display: flex;
align-items: center;
cursor: pointer;
font-size: 15px;
}
.subtree__node__icons {
display: flex;
}
.subtree__node__icons .fa {
margin-left: 2px;
margin-right: 2px;
}
.subtree__node--can-be-selected {
text-decoration: underline;
text-underline-offset: 2px;
}
.right-handed .subtree__node__text {
flex-direction: row;
text-align: left;
}
.right-handed .subtree__node__icons {
flex-direction: row;
}
.right-handed .subtree__node__children > .subtree__node {
padding-left: 16px;
}
.left-handed .subtree__node__text {
flex-direction: row-reverse;
text-align: right;
}
.left-handed .subtree__node__icons {
flex-direction: row-reverse;
}
.left-handed .subtree__node__children > .subtree__node {
padding-right: 20px;
}
.node-text {
display: inline-flex;
}
.node-text--selected {
font-weight: bold;
text-decoration: underline;
}
.right-handed .node-text {
flex-direction: row;
}
.left-handed .node-text {
flex-direction: row-reverse;
}
.progress-pie { .progress-pie {
background: rgba(51, 122, 183, 0.1); background: rgba(51, 122, 183, 0.1);
border-radius: 100%; border-radius: 100%;
...@@ -520,14 +537,13 @@ li .leaf:hover a.settings { ...@@ -520,14 +537,13 @@ li .leaf:hover a.settings {
#node-popup-tooltip { #node-popup-tooltip {
position: fixed; position: fixed;
background-color: white;
border-radius: 6px;
} }
#node-popup-tooltip .tree .node { #node-popup-tooltip:hover {
margin-top: 5px; border: none;
} text-decoration: none;
#node-popup-tooltip .tree .children .node {
padding-left: 15px;
} }
.right-handed #node-popup-tooltip { .right-handed #node-popup-tooltip {
top: 50%; top: 50%;
left: 16.6666666667%; left: 16.6666666667%;
...@@ -540,21 +556,51 @@ li .leaf:hover a.settings { ...@@ -540,21 +556,51 @@ li .leaf:hover a.settings {
transform: translateY(-50%); transform: translateY(-50%);
} }
.panel-actions .almost-useable { #node-popup-tooltip .tree .node {
margin-top: 5px;
}
#node-popup-tooltip .tree .children .node {
padding-left: 15px;
}
#node-popup-tooltip .panel-actions .almost-useable {
color: orange; color: orange;
} }
.panel-actions .development-in-progress { #node-popup-tooltip .panel-actions .development-in-progress {
color: red; color: red;
} }
.panel-actions .ok-to-use { #node-popup-tooltip .panel-actions .ok-to-use {
color: black; color: black;
} }
#node-popup-tooltip .popup-container {
.popup-container > .card { display: flex;
flex-direction: colum;
}
#node-popup-tooltip .popup-container > .card {
width: auto !important; width: auto !important;
min-width: 544px;
border: 1px solid rgba(0, 0, 0, 0.2);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
margin-bottom: initial;
} }
#node-popup-tooltip .popup-container > .card .fa-pencil {
.popup-container-body { color: black;
}
#node-popup-tooltip .popup-container > .card .card-body {
display: flex;
justify-content: center;
background-color: white;
border: none;
}
#node-popup-tooltip .popup-container > .card .card-body .spacer {
margin: 8px;
}
#node-popup-tooltip .popup-container .frame-search.card {
border: 1px solid rgba(0, 0, 0, 0.2);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
height: 600px;
width: 1000px;
}
#node-popup-tooltip .popup-container-body {
max-height: 70vh; max-height: 70vh;
overflow-y: auto; overflow-y: auto;
} }
...@@ -656,6 +702,13 @@ li .leaf:hover a.settings { ...@@ -656,6 +702,13 @@ li .leaf:hover a.settings {
margin-bottom: 24px; margin-bottom: 24px;
} }
.ids-selector .tree .children {
padding-left: 0.5em;
}
.ids-selector .tree .children .leaf input {
margin: 0.1em;
}
.code-editor .editor .code-area { .code-editor .editor .code-area {
flex-grow: 1; flex-grow: 1;
max-height: 200px; max-height: 200px;
......
{"version":3,"sourceRoot":"","sources":["../../src/sass/_menu.sass","../../src/sass/_context_menu.sass","../../src/sass/_graph.sass","../../src/sass/_login.sass","../../src/sass/_tree.sass","../../src/sass/abstract/_members.scss","../../src/sass/_code_editor.sass","../../src/sass/_styles.sass","../../src/sass/_range_slider.sass","../../src/sass/_annotation.sass","../../src/sass/_folder_view.sass"],"names":[],"mappings":"AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;EACE;EACA;EACA;EACA;EAEA;;;AAEF;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;;;AAME;EACE;;;AC9DN;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;EAEE;EAEA;EACA;EACA;EAEA;EACA;EACA;;AAEA;EACE;;AAEJ;EACE;;AAEA;EACE;;AAEJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;ACjFJ;EACE;;AACA;EACE;EACA;;;AAEJ;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;;;AC/IF;EACE;;;AAGA;EACE;EACA;EACA;;AAEA;EACE;EACA;;AAGA;EACE;;AACF;EACE;;AAEJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAKJ;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;;;AAEN;EAWE;;AAGE;EACE;;AAEA;EACE;;;AAUR;EAEE;EACA,MAFW;EAGX;;;AAEF;EAEE;EACA,OAFW;EAGX;;;AAGA;EACE;;AACF;EACE;;AACF;EACE;;;AAMF;EACE;;;AAEJ;EAEE;EACA;;;AAEF;EAEE;EACA;;;AAEF;EAGE;EAKA;EACA;EACA;EACA;EAGA;EACA;EACA;EAKA;;AAHA;EACE;;;AAKJ;EAGE;;AC9NS;ED/BP;EACA;;;ACqBO;EDlBP;EACA;;;AC0BO;EDiOP;;AAEA;EACE;;;AC7OK;EDgPP;;AAEA;EACE;;;AAON;EAIE;EAEA;EACA;EACA;EACA,QA9RmC;EA+RnC;;AC3PS;ED+PP;;;ACxQO;ED2QP;;;AAEJ;EAGE;EAEA;EACA;EACA;EACA,QAjTgC;EAkThC;;AC7QS;EDiRP;;;AC1RO;ED6RP;;;AAKF;EAIE;EACA;;AC9RO;ED/BP;EACA;;;ACqBO;EDlBP;EACA;;;AA0TA;EACE,eArU+B;;;AEsBjC;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;EApCR;EACA;EACA;EACA;EACA;EACA;EACA;EAlBA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AA0CM;EACE;EACA;EACA;EACA;EACA;EA5CR;EACA;EACA;EACA;EACA;EACA;EACA;EAlBA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAkDE;EACE;EACA;EACA;EACA;EACA;EACA;;AACF;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;;AACF;EACE;EACA;;AACF;EACE;EACA;;AAGE;EACE;;AAEF;EACE;;AAEV;EACE;;AAEA;EACE;;;AC9FN;EACE;;;AAEA;EAEE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;;AAGE;EACE;EACA;;AAEF;EACE;EACA;;;AAER;EAEE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;;AAGE;EACE;EACA;;AAEF;EACE;EACA;;;AAEV;EACE;;AACA;EACE;;AACF;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;;;AAEJ;EACE;;AACA;EACE;;;AAEJ;EACE;EACA;;;AAGF;EACE;;;AAEF;EACE;;AAEA;EACE;;AAEF;EACE;;;AAGJ;EAKE;;AAEA;EACE;;AAIE;EACE;;AACF;EACE;;AAEJ;EAGE;;AAGJ;EACE,SAtBa;EAuBb;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAKE;EACE;;AADF;EACE;;AADF;EACE;;AADF;EACE;;AADF;EACE;;AADF;EACE;;AADF;EACE;;AADF;EACE;;AADF;EACE;;AADF;EACE;;;AAKN;EACE;;AFhIO;EEmIL;;;AF5IK;EE+IL;;;AAEJ;EACE,SAZa;;;ACpKjB;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;;;ACxBJ;EACE;;AAEA;EANE;EACA;;AAQF;EAbE;EACA;;AAeF;EAhBE;EACA;;AAkBF;EAnBE;EACA;;AAqBF;EA1BE;EACA,kBANyB;;AAkC3B;EA7BE;EACA,kBAPqB;;AAsCvB;EAhCE;EACA,kBAJoB;;;AAuCtB;EApCE;EACA,kBANyB;;AA4C3B;EAvCE;EACA,kBAPqB;;AAgDvB;EA1CE;EACA,kBAJoB;;;ACNxB;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA","file":"sass.css"} {"version":3,"sourceRoot":"","sources":["../../src/sass/_menu.sass","../../src/sass/_context_menu.sass","../../src/sass/_graph.sass","../../src/sass/_login.sass","../../src/sass/_tree.sass","../../src/sass/abstract/_members.scss","../../src/sass/_code_editor.sass","../../src/sass/_styles.sass","../../src/sass/_range_slider.sass","../../src/sass/_annotation.sass","../../src/sass/_folder_view.sass"],"names":[],"mappings":"AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;EACE;EACA;EACA;EACA;EAEA;;;AAEF;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;;;AAME;EACE;;;AC9DN;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;EAEE;EAEA;EACA;EACA;EAEA;EACA;EACA;;AAEA;EACE;;AAEJ;EACE;;AAEA;EACE;;AAEJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;ACjFJ;EACE;;AACA;EACE;EACA;;;AAEJ;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAGF;EACE;;AAEE;EACE;EACA;;AACA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;;;AAKJ;EACE;EACA;EACA;;;AAEJ;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;;;AC1GF;EACE;;;AAGA;EACE;EACA;EACA;;AAEA;EACE;EACA;;AAGA;EACE;;AACF;EACE;;AAEJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAKJ;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;;;AAMN;EACE;;AAEA;EACE;EACA;EACA;EACA;;AAEF;EACE;;AAEA;EACE;EACA;;AAEJ;EACE;EACA;;AAIA;EACE;EACA;;AAEF;EACE;;AAEF;EACE;;;AAIF;EACE;EACA;;AAEF;EACE;;AAEF;EACE;;;AAGR;EACE;;AAEA;EACE;EACA;;ACrJO;EDwJP;;;ACjKO;EDoKP;;;AAKJ;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;;;AAEN;EAWE;EAGA;EACA,eAvPkB;;AAyPlB;EACE;EACA;;ACxNO;EDqOP;EACA,MAFW;EAGX;;;AChPO;EDoPP;EACA,OAFW;EAGX;;;AAGA;EACE;;AAEA;EACE;;AAGJ;EACE;;AACF;EACE;;AACF;EACE;;AAGJ;EACE;EACA;;AAEA;EAGE;EACA,WAzSa;EA4Sb;EACA;EACA;;AAEA;EACE;;AAEF;EACE;EACA;EACA;EACA;;AACA;EACE;;AAEN;EACE;EACA;EACA;EACA;;AAEJ;EAEE;EACA;;;AAEJ;EAEE;EACA;;;AAEF;EAGE;EAKA;EACA;EACA;EACA;EAGA;EACA;EACA;EAKA;;AAHA;EACE;;;AAKJ;EAGE;;ACpUS;ED5BP;EACA;;;ACkBO;EDfP;EACA;;;ACuBO;EDuUP;;AAEA;EACE;;;ACnVK;EDsVP;;AAEA;EACE;;;AAON;EAIE;EAEA;EACA;EACA;EACA,QApYmC;EAqYnC;;ACjWS;EDqWP;;;AC9WO;EDiXP;;;AAEJ;EAGE;EAEA;EACA;EACA;EACA,QAvZgC;EAwZhC;;ACnXS;EDuXP;;;AChYO;EDmYP;;;AAKF;EAIE;EACA;;ACpYO;ED5BP;EACA;;;ACkBO;EDfP;EACA;;;AA6ZA;EACE,eA3a+B;;;AAibjC;EACE;;AAEE;EACE;;;AE/ZN;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;EApCR;EACA;EACA;EACA;EACA;EACA;EACA;EAlBA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AA0CM;EACE;EACA;EACA;EACA;EACA;EA5CR;EACA;EACA;EACA;EACA;EACA;EACA;EAlBA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAkDE;EACE;EACA;EACA;EACA;EACA;EACA;;AACF;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;;AACF;EACE;EACA;;AACF;EACE;EACA;;AAGE;EACE;;AAEF;EACE;;AAEV;EACE;;AAEA;EACE;;;AC9FN;EACE;;;AAEA;EAEE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;;AAGE;EACE;EACA;;AAEF;EACE;EACA;;;AAER;EAEE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;;AAGE;EACE;EACA;;AAEF;EACE;EACA;;;AAEV;EACE;;AACA;EACE;;AACF;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;;;AAEJ;EACE;;AACA;EACE;;;AAEJ;EACE;EACA;;;AAGF;EACE;;;AAEF;EACE;;AAEA;EACE;;AAEF;EACE;;;AAGJ;EAKE;;AAEA;EACE;;AAIE;EACE;;AACF;EACE;;AAEJ;EAGE;;AAGJ;EACE,SAtBa;EAuBb;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAKE;EACE;;AADF;EACE;;AADF;EACE;;AADF;EACE;;AADF;EACE;;AADF;EACE;;AADF;EACE;;AADF;EACE;;AADF;EACE;;AADF;EACE;;;AAKN;EACE;;AFhIO;EEmIL;;;AF5IK;EE+IL;;;AAEJ;EACE,SAZa;;;ACpKjB;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;;;ACxBJ;EACE;;AAEA;EANE;EACA;;AAQF;EAbE;EACA;;AAeF;EAhBE;EACA;;AAkBF;EAnBE;EACA;;AAqBF;EA1BE;EACA,kBANyB;;AAkC3B;EA7BE;EACA,kBAPqB;;AAsCvB;EAhCE;EACA,kBAJoB;;;AAuCtB;EApCE;EACA,kBANyB;;AA4C3B;EAvCE;EACA,kBAPqB;;AAgDvB;EA1CE;EACA,kBAJoB;;;ACNxB;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA","file":"sass.css"}
\ No newline at end of file \ No newline at end of file
{ {
"name": "Gargantext", "name": "Gargantext",
"version": "0.0.3.1", "version": "0.0.3.3",
"scripts": { "scripts": {
"generate-purs-packages-nix": "./nix/generate-purs-packages.nix", "generate-purs-packages-nix": "./nix/generate-purs-packages.nix",
"generate-psc-packages-nix": "./nix/generate-packages-json.bash", "generate-psc-packages-nix": "./nix/generate-packages-json.bash",
...@@ -24,13 +24,13 @@ ...@@ -24,13 +24,13 @@
"prod:bundle": "pulp browserify --skip-compile -o dce-output -t app.js", "prod:bundle": "pulp browserify --skip-compile -o dce-output -t app.js",
"prod:pack": "parcel build index.html -d prod --public-url . --no-source-maps", "prod:pack": "parcel build index.html -d prod --public-url . --no-source-maps",
"test-pulp": "pulp test", "test-pulp": "pulp test",
"test": "gauge run specs/" "test": "gauge run specs/"
}, },
"dependencies": { "dependencies": {
"@popperjs/core": "^2.9.2", "@popperjs/core": "^2.9.2",
"aes-js": "^3.1.1", "aes-js": "^3.1.1",
"base-x": "^3.0.2", "base-x": "^3.0.2",
"bootstrap": "^4.6.0", "bootstrap": "^5.1.0",
"bootstrap-dark": "^1.0.3", "bootstrap-dark": "^1.0.3",
"create-react-class": "^15.6.3", "create-react-class": "^15.6.3",
"echarts": "^5.1.2", "echarts": "^5.1.2",
...@@ -50,12 +50,12 @@ ...@@ -50,12 +50,12 @@
"devDependencies": { "devDependencies": {
"@babel/core": "^7.15.0", "@babel/core": "^7.15.0",
"@babel/preset-react": "^7.12.7", "@babel/preset-react": "^7.12.7",
"@getgauge/cli": "^1.4.0", "@getgauge/cli": "^1.4.0",
"parcel": "^2.0.0-beta.2", "parcel": "^2.0.0-beta.2",
"react-testing-library": "^8.0.1", "react-testing-library": "^8.0.1",
"sass": "^1.35.2", "sass": "^1.35.2",
"serve": "^12.0.0", "serve": "^12.0.0",
"taiko": "latest", "taiko": "latest",
"vscode-languageserver": "^7.0.0", "vscode-languageserver": "^7.0.0",
"xhr2": "^0.2.1" "xhr2": "^0.2.1"
}, },
......
...@@ -26,6 +26,17 @@ let ...@@ -26,6 +26,17 @@ let
browserify browserify
''; '';
build-css = pkgs.writeShellScriptBin "build-css" ''
#!/usr/bin/env bash
set -e
yarn css
'';
build-watch = pkgs.writeShellScriptBin "build-watch" '' build-watch = pkgs.writeShellScriptBin "build-watch" ''
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
...@@ -72,11 +83,13 @@ pkgs.mkShell { ...@@ -72,11 +83,13 @@ pkgs.mkShell {
easy-ps.psc-package easy-ps.psc-package
easy-ps.dhall-json-simple easy-ps.dhall-json-simple
browserify browserify
build-css
build-purs build-purs
build-watch build-watch
build build
minify-bundle minify-bundle
pkgs.minify pkgs.minify
pkgs.nodejs
repl repl
pkgs.pulp pkgs.pulp
pkgs.spago pkgs.spago
......
...@@ -3,7 +3,6 @@ module Gargantext.Components.DocsTable where ...@@ -3,7 +3,6 @@ module Gargantext.Components.DocsTable where
import Gargantext.Prelude import Gargantext.Prelude
import DOM.Simple.Console (log2)
import DOM.Simple.Event as DE import DOM.Simple.Event as DE
import Data.Array as A import Data.Array as A
import Data.Either (Either) import Data.Either (Either)
...@@ -496,9 +495,9 @@ docChooserCpt = here.component "docChooser" cpt ...@@ -496,9 +495,9 @@ docChooserCpt = here.component "docChooser" cpt
] ]
where where
onClick selected _ = do onClick selected _ = do
-- log2 "[docChooser] onClick, listId" listId -- here.log2 "[docChooser] onClick, listId" listId
-- log2 "[docChooser] onClick, corpusId" corpusId -- here.log2 "[docChooser] onClick, corpusId" corpusId
-- log2 "[docChooser] onClick, nodeId" nodeId -- here.log2 "[docChooser] onClick, nodeId" nodeId
-- R2.callTrigger triggerAnnotatedDocIdChange { corpusId, listId, nodeId } -- R2.callTrigger triggerAnnotatedDocIdChange { corpusId, listId, nodeId }
-- T2.reload tableReload -- T2.reload tableReload
if selected then do if selected then do
...@@ -510,7 +509,7 @@ docChooserCpt = here.component "docChooser" cpt ...@@ -510,7 +509,7 @@ docChooserCpt = here.component "docChooser" cpt
, mCurrentDocId: Just nodeId , mCurrentDocId: Just nodeId
, nodeId: nodeId }) sidePanel , nodeId: nodeId }) sidePanel
T.write_ Opened sidePanelState T.write_ Opened sidePanelState
log2 "[docChooser] sidePanel opened" sidePanelState here.log2 "[docChooser] sidePanel opened" sidePanelState
newtype SearchQuery = SearchQuery { newtype SearchQuery = SearchQuery {
......
...@@ -5,7 +5,6 @@ module Gargantext.Components.FacetsTable where ...@@ -5,7 +5,6 @@ module Gargantext.Components.FacetsTable where
import Gargantext.Prelude import Gargantext.Prelude
import DOM.Simple.Console (log2)
import Data.Either (Either(..)) import Data.Either (Either(..))
import Data.Eq.Generic (genericEq) import Data.Eq.Generic (genericEq)
import Data.Generic.Rep (class Generic) import Data.Generic.Rep (class Generic)
...@@ -223,7 +222,7 @@ loadPage { session, nodeId, listId, query, params: {limit, offset, orderBy } } = ...@@ -223,7 +222,7 @@ loadPage { session, nodeId, listId, query, params: {limit, offset, orderBy } } =
case eSearchResult of case eSearchResult of
Left err -> pure $ Left err Left err -> pure $ Left err
Right (SearchResult {result}) -> do Right (SearchResult {result}) -> do
liftEffect $ log2 "[loadPage] result" result liftEffect $ here.log2 "[loadPage] result" result
-- $ SearchQuery {query: concat query, expected: SearchDoc} -- $ SearchQuery {query: concat query, expected: SearchDoc}
pure $ Right $ case result of pure $ Right $ case result of
SearchResultDoc {docs} -> Docs {docs: doc2view <$> Seq.fromFoldable docs} SearchResultDoc {docs} -> Docs {docs: doc2view <$> Seq.fromFoldable docs}
......
...@@ -10,7 +10,6 @@ import Effect.Aff (Aff) ...@@ -10,7 +10,6 @@ import Effect.Aff (Aff)
import Effect.Class (liftEffect) import Effect.Class (liftEffect)
import Gargantext.AsyncTasks as GAT import Gargantext.AsyncTasks as GAT
import Gargantext.Components.App.Data (Boxes) import Gargantext.Components.App.Data (Boxes)
import Gargantext.Components.Forest.Tree.Node.Action (Action(..))
import Gargantext.Components.Forest.Tree.Node.Action.Add (AddNodeValue(..), addNode) import Gargantext.Components.Forest.Tree.Node.Action.Add (AddNodeValue(..), addNode)
import Gargantext.Components.Forest.Tree.Node.Action.Contact as Contact import Gargantext.Components.Forest.Tree.Node.Action.Contact as Contact
import Gargantext.Components.Forest.Tree.Node.Action.Delete (deleteNode, unpublishNode) import Gargantext.Components.Forest.Tree.Node.Action.Delete (deleteNode, unpublishNode)
...@@ -19,10 +18,11 @@ import Gargantext.Components.Forest.Tree.Node.Action.Merge (mergeNodeReq) ...@@ -19,10 +18,11 @@ import Gargantext.Components.Forest.Tree.Node.Action.Merge (mergeNodeReq)
import Gargantext.Components.Forest.Tree.Node.Action.Move (moveNodeReq) import Gargantext.Components.Forest.Tree.Node.Action.Move (moveNodeReq)
import Gargantext.Components.Forest.Tree.Node.Action.Rename (RenameValue(..), rename) import Gargantext.Components.Forest.Tree.Node.Action.Rename (RenameValue(..), rename)
import Gargantext.Components.Forest.Tree.Node.Action.Share as Share import Gargantext.Components.Forest.Tree.Node.Action.Share as Share
import Gargantext.Components.Forest.Tree.Node.Action.Types (Action(..))
import Gargantext.Components.Forest.Tree.Node.Action.Update (updateRequest) import Gargantext.Components.Forest.Tree.Node.Action.Update (updateRequest)
import Gargantext.Components.Forest.Tree.Node.Action.Upload (uploadArbitraryFile, uploadFile) import Gargantext.Components.Forest.Tree.Node.Action.Upload (uploadArbitraryFile, uploadFile)
import Gargantext.Components.Forest.Tree.Node.Box (nodePopupView) import Gargantext.Components.Forest.Tree.Node.Box (nodePopupView)
import Gargantext.Components.Forest.Tree.Node.Tools.FTree (FTree, LNode(..), NTree(..), fTreeID) import Gargantext.Components.Forest.Tree.Node.Tools.FTree (FTree, LNode(..), NTree(..), ID, fTreeID)
import Gargantext.Components.Forest.Tree.Node.Tools.SubTree.Types (SubTreeOut(..)) import Gargantext.Components.Forest.Tree.Node.Tools.SubTree.Types (SubTreeOut(..))
import Gargantext.Config.REST (RESTError) import Gargantext.Config.REST (RESTError)
import Gargantext.Config.Utils (handleRESTError) import Gargantext.Config.Utils (handleRESTError)
...@@ -70,9 +70,9 @@ folderViewCpt = here.component "folderViewCpt" cpt where ...@@ -70,9 +70,9 @@ folderViewCpt = here.component "folderViewCpt" cpt where
, boxes , boxes
, folders , folders
, nodeId , nodeId
, session
, reload , reload
, setPopoverRef } } , session
, setPopoverRef } [] }
where where
errorHandler err = here.log2 "[folderView] RESTError" err errorHandler err = here.log2 "[folderView] RESTError" err
...@@ -86,8 +86,8 @@ type FolderViewProps = ...@@ -86,8 +86,8 @@ type FolderViewProps =
, setPopoverRef :: R.Ref (Maybe (Boolean -> Effect Unit)) , setPopoverRef :: R.Ref (Maybe (Boolean -> Effect Unit))
) )
folderViewMain :: Record FolderViewProps -> R.Element folderViewMain :: R2.Component FolderViewProps
folderViewMain props = R.createElement folderViewMainCpt props [] folderViewMain = R.createElement folderViewMainCpt
folderViewMainCpt :: R.Component FolderViewProps folderViewMainCpt :: R.Component FolderViewProps
folderViewMainCpt = here.component "folderViewMainCpt" cpt where folderViewMainCpt = here.component "folderViewMainCpt" cpt where
cpt { backFolder cpt { backFolder
...@@ -277,8 +277,10 @@ performAction = performAction' where ...@@ -277,8 +277,10 @@ performAction = performAction' where
performAction' (SharePublic { params }) p = sharePublic params p performAction' (SharePublic { params }) p = sharePublic params p
performAction' (AddContact params) p = addContact params p performAction' (AddContact params) p = addContact params p
performAction' (AddNode name nodeType) p = addNode' name nodeType p performAction' (AddNode name nodeType) p = addNode' name nodeType p
performAction' (UploadFile nodeType fileType mName contents) p = uploadFile' nodeType fileType mName contents p performAction' (UploadFile nodeType fileType mName contents selection) p =
performAction' (UploadArbitraryFile mName blob) p = uploadArbitraryFile' mName blob p uploadFile' nodeType fileType mName contents p selection
performAction' (UploadArbitraryFile mName blob selection) p =
uploadArbitraryFile' mName blob p selection
performAction' DownloadNode _ = liftEffect $ here.log "[performAction] DownloadNode" performAction' DownloadNode _ = liftEffect $ here.log "[performAction] DownloadNode"
performAction' (MoveNode {params}) p = moveNode params p performAction' (MoveNode {params}) p = moveNode params p
performAction' (MergeNode {params}) p = mergeNode params p performAction' (MergeNode {params}) p = mergeNode params p
...@@ -325,14 +327,14 @@ performAction = performAction' where ...@@ -325,14 +327,14 @@ performAction = performAction' where
addContact params { nodeId: id, session } = addContact params { nodeId: id, session } =
void $ Contact.contactReq session id params void $ Contact.contactReq session id params
uploadFile' nodeType fileType mName contents { boxes: { errors, tasks }, nodeId: id, session } = do uploadFile' nodeType fileType mName contents { boxes: { errors, tasks }, nodeId: id, session } selection = do
eTask <- uploadFile { contents, fileType, id, nodeType, mName, session } eTask <- uploadFile { contents, fileType, id, nodeType, mName, selection, session }
handleRESTError errors eTask $ \task -> liftEffect $ do handleRESTError errors eTask $ \task -> liftEffect $ do
GAT.insert id task tasks GAT.insert id task tasks
here.log2 "[performAction] UploadFile, uploaded, task:" task here.log2 "[performAction] UploadFile, uploaded, task:" task
uploadArbitraryFile' mName blob { boxes: { errors, tasks }, nodeId: id, session } = do uploadArbitraryFile' mName blob { boxes: { errors, tasks }, nodeId: id, session } selection = do
eTask <- uploadArbitraryFile session id { blob, mName } eTask <- uploadArbitraryFile session id { blob, mName } selection
handleRESTError errors eTask $ \task -> liftEffect $ do handleRESTError errors eTask $ \task -> liftEffect $ do
GAT.insert id task tasks GAT.insert id task tasks
here.log2 "[performAction] UploadArbitraryFile, uploaded, task:" task here.log2 "[performAction] UploadArbitraryFile, uploaded, task:" task
......
...@@ -3,9 +3,7 @@ module Gargantext.Components.FolderView.Box where ...@@ -3,9 +3,7 @@ module Gargantext.Components.FolderView.Box where
import Gargantext.Prelude import Gargantext.Prelude
import DOM.Simple as DOM import DOM.Simple as DOM
import Data.Maybe (Maybe(..))
import Effect (Effect) import Effect (Effect)
import Gargantext.Components.Forest.Tree.Node.Settings (SettingsBox(..), settingsBox)
import Gargantext.Components.Forest.Tree.Node.Tools (prettyNodeType) import Gargantext.Components.Forest.Tree.Node.Tools (prettyNodeType)
import Gargantext.Types (ID, Name) import Gargantext.Types (ID, Name)
import Gargantext.Types as GT import Gargantext.Types as GT
...@@ -13,7 +11,6 @@ import Gargantext.Utils.Glyphicon (glyphicon) ...@@ -13,7 +11,6 @@ import Gargantext.Utils.Glyphicon (glyphicon)
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
import Reactix as R import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
import Toestand as T
here :: R2.Here here :: R2.Here
here = R2.here "Gargantext.Components.FolderView.Box" here = R2.here "Gargantext.Components.FolderView.Box"
...@@ -25,12 +22,11 @@ type NodePopupProps = ...@@ -25,12 +22,11 @@ type NodePopupProps =
, onPopoverClose :: DOM.Element -> Effect Unit , onPopoverClose :: DOM.Element -> Effect Unit
) )
nodePopupView :: Record NodePopupProps -> R.Element nodePopupView :: R2.Leaf NodePopupProps
nodePopupView props = R.createElement nodePopupCpt props [] nodePopupView props = R.createElement nodePopupViewCpt props []
nodePopupViewCpt :: R.Component NodePopupProps
nodePopupCpt :: R.Component NodePopupProps nodePopupViewCpt = here.component "nodePopupView" cpt where
nodePopupCpt = here.component "nodePopupView" cpt where cpt props _ = do
cpt props@{ id, name, nodeType } _ = do
pure $ H.div tooltipProps pure $ H.div tooltipProps
[ H.div { className: "popup-container" } [ H.div { className: "popup-container" }
...@@ -43,7 +39,7 @@ nodePopupCpt = here.component "nodePopupView" cpt where ...@@ -43,7 +39,7 @@ nodePopupCpt = here.component "nodePopupView" cpt where
tooltipProps = { id: "node-popup-tooltip", title: "Node settings" tooltipProps = { id: "node-popup-tooltip", title: "Node settings"
, data: { toggle: "tooltip", placement: "right" } } , data: { toggle: "tooltip", placement: "right" } }
panelHeading props@{id, name, nodeType } = panelHeading props@{ nodeType } =
H.div { className: "card-header" } H.div { className: "card-header" }
[ R2.row [ R2.row
[ H.div { className: "col-4" } [ H.div { className: "col-4" }
...@@ -53,5 +49,4 @@ nodePopupCpt = here.component "nodePopupView" cpt where ...@@ -53,5 +49,4 @@ nodePopupCpt = here.component "nodePopupView" cpt where
[ H.span { className: "text-primary center" } [ H.text props.name ] ] [ H.span { className: "text-primary center" } [ H.text props.name ] ]
, H.div { className: "col-1" } , H.div { className: "col-1" }
[ H.a { type: "button", on: { click: closePopover props }, title: "Close" [ H.a { type: "button", on: { click: closePopover props }, title: "Close"
, className: glyphicon "window-close" } [] ]]] where , className: glyphicon "window-close" } [] ]]]
SettingsBox { edit, doc, buttons } = settingsBox nodeType
...@@ -12,7 +12,6 @@ import Effect.Class (liftEffect) ...@@ -12,7 +12,6 @@ import Effect.Class (liftEffect)
import Gargantext.AsyncTasks as GAT import Gargantext.AsyncTasks as GAT
import Gargantext.Components.App.Data (Boxes) import Gargantext.Components.App.Data (Boxes)
import Gargantext.Components.Forest.Tree.Node (nodeSpan) import Gargantext.Components.Forest.Tree.Node (nodeSpan)
import Gargantext.Components.Forest.Tree.Node.Action (Action(..))
import Gargantext.Components.Forest.Tree.Node.Action.Add (AddNodeValue(..), addNode) import Gargantext.Components.Forest.Tree.Node.Action.Add (AddNodeValue(..), addNode)
import Gargantext.Components.Forest.Tree.Node.Action.Contact as Contact import Gargantext.Components.Forest.Tree.Node.Action.Contact as Contact
import Gargantext.Components.Forest.Tree.Node.Action.Delete (deleteNode, unpublishNode) import Gargantext.Components.Forest.Tree.Node.Action.Delete (deleteNode, unpublishNode)
...@@ -21,6 +20,7 @@ import Gargantext.Components.Forest.Tree.Node.Action.Merge (mergeNodeReq) ...@@ -21,6 +20,7 @@ import Gargantext.Components.Forest.Tree.Node.Action.Merge (mergeNodeReq)
import Gargantext.Components.Forest.Tree.Node.Action.Move (moveNodeReq) import Gargantext.Components.Forest.Tree.Node.Action.Move (moveNodeReq)
import Gargantext.Components.Forest.Tree.Node.Action.Rename (RenameValue(..), rename) import Gargantext.Components.Forest.Tree.Node.Action.Rename (RenameValue(..), rename)
import Gargantext.Components.Forest.Tree.Node.Action.Share as Share import Gargantext.Components.Forest.Tree.Node.Action.Share as Share
import Gargantext.Components.Forest.Tree.Node.Action.Types (Action(..))
import Gargantext.Components.Forest.Tree.Node.Action.Update (updateRequest) import Gargantext.Components.Forest.Tree.Node.Action.Update (updateRequest)
import Gargantext.Components.Forest.Tree.Node.Action.Upload (uploadFile, uploadArbitraryFile) import Gargantext.Components.Forest.Tree.Node.Action.Upload (uploadFile, uploadArbitraryFile)
import Gargantext.Components.Forest.Tree.Node.Tools.FTree (FTree, LNode(..), NTree(..), fTreeID) import Gargantext.Components.Forest.Tree.Node.Tools.FTree (FTree, LNode(..), NTree(..), fTreeID)
...@@ -64,7 +64,8 @@ type NodeProps = ...@@ -64,7 +64,8 @@ type NodeProps =
| Common ) | Common )
type TreeProps = type TreeProps =
( tree :: FTree ( root :: ID
, tree :: FTree
| NodeProps ) | NodeProps )
type ChildrenTreeProps = type ChildrenTreeProps =
...@@ -91,8 +92,9 @@ type NSCommon = ...@@ -91,8 +92,9 @@ type NSCommon =
-- way. This function is only called by functions in this module, so -- way. This function is only called by functions in this module, so
-- we just have to careful in what we pass. -- we just have to careful in what we pass.
type ChildLoaderProps = type ChildLoaderProps =
( id :: ID ( id :: ID
, render :: R2.Leaf TreeProps , render :: R2.Leaf TreeProps
, root :: ID
| NodeProps ) | NodeProps )
type PerformActionProps = type PerformActionProps =
...@@ -118,7 +120,7 @@ treeLoaderCpt = here.component "treeLoader" cpt where ...@@ -118,7 +120,7 @@ treeLoaderCpt = here.component "treeLoader" cpt where
loaded tree' = tree props where loaded tree' = tree props where
props = Record.merge common extra where props = Record.merge common extra where
common = RecordE.pick p :: Record Common common = RecordE.pick p :: Record Common
extra = { tree: tree', reloadTree: p.reload, session } extra = { reloadTree: p.reload, root, session, tree: tree' }
errorHandler err = here.log2 "[treeLoader] RESTError" err errorHandler err = here.log2 "[treeLoader] RESTError" err
getNodeTree :: Session -> ID -> Aff (Either RESTError FTree) getNodeTree :: Session -> ID -> Aff (Either RESTError FTree)
...@@ -135,6 +137,7 @@ treeCpt = here.component "tree" cpt where ...@@ -135,6 +137,7 @@ treeCpt = here.component "tree" cpt where
, frontends , frontends
, handed , handed
, reload , reload
, root
, session , session
, tree: NTree (LNode { id, name, nodeType }) children } _ = do , tree: NTree (LNode { id, name, nodeType }) children } _ = do
setPopoverRef <- R.useRef Nothing setPopoverRef <- R.useRef Nothing
...@@ -150,6 +153,7 @@ treeCpt = here.component "tree" cpt where ...@@ -150,6 +153,7 @@ treeCpt = here.component "tree" cpt where
, name , name
, nodeType , nodeType
, reload , reload
, root
, session , session
, setPopoverRef } , setPopoverRef }
[ renderChildren (Record.merge p { childProps: { children', folderOpen, render: tree } } ) [] ] [ renderChildren (Record.merge p { childProps: { children', folderOpen, render: tree } } ) [] ]
...@@ -186,13 +190,14 @@ renderTreeChildren = R.createElement renderTreeChildrenCpt ...@@ -186,13 +190,14 @@ renderTreeChildren = R.createElement renderTreeChildrenCpt
renderTreeChildrenCpt :: R.Component ChildrenTreeProps renderTreeChildrenCpt :: R.Component ChildrenTreeProps
renderTreeChildrenCpt = here.component "renderTreeChildren" cpt where renderTreeChildrenCpt = here.component "renderTreeChildren" cpt where
cpt p@{ childProps: { children' cpt p@{ childProps: { children'
, render } } _ = do , render }
, root } _ = do
pure $ R.fragment (map renderChild children') pure $ R.fragment (map renderChild children')
where where
nodeProps = RecordE.pick p :: Record NodeProps nodeProps = RecordE.pick p :: Record NodeProps
renderChild (NTree (LNode {id: cId}) _) = childLoader props [] where renderChild (NTree (LNode {id: cId}) _) = childLoader props [] where
props = Record.merge nodeProps { id: cId, render } props = Record.merge nodeProps { id: cId, render, root }
childLoader :: R2.Component ChildLoaderProps childLoader :: R2.Component ChildLoaderProps
childLoader = R.createElement childLoaderCpt childLoader = R.createElement childLoaderCpt
...@@ -200,7 +205,8 @@ childLoaderCpt :: R.Component ChildLoaderProps ...@@ -200,7 +205,8 @@ childLoaderCpt :: R.Component ChildLoaderProps
childLoaderCpt = here.component "childLoader" cpt where childLoaderCpt = here.component "childLoader" cpt where
cpt p@{ boxes: { reloadRoot } cpt p@{ boxes: { reloadRoot }
, reloadTree , reloadTree
, render } _ = do , render
, root } _ = do
reload <- T.useBox T2.newReload reload <- T.useBox T2.newReload
let reloads = [ reload, reloadRoot, reloadTree ] let reloads = [ reload, reloadRoot, reloadTree ]
cache <- (A.cons p.id) <$> traverse (T.useLive T.unequal) reloads cache <- (A.cons p.id) <$> traverse (T.useLive T.unequal) reloads
...@@ -213,7 +219,7 @@ childLoaderCpt = here.component "childLoader" cpt where ...@@ -213,7 +219,7 @@ childLoaderCpt = here.component "childLoader" cpt where
fetch _ = getNodeTreeFirstLevel p.session p.id fetch _ = getNodeTreeFirstLevel p.session p.id
paint reload tree' = render (Record.merge base extra) where paint reload tree' = render (Record.merge base extra) where
base = nodeProps { reload = reload } base = nodeProps { reload = reload }
extra = { tree: tree' } extra = { root, tree: tree' }
nodeProps = RecordE.pick p :: Record NodeProps nodeProps = RecordE.pick p :: Record NodeProps
closePopover { setPopoverRef } = closePopover { setPopoverRef } =
...@@ -265,14 +271,14 @@ addNode' name nodeType p@{ boxes: { errors, forestOpen }, session, tree: (NTree ...@@ -265,14 +271,14 @@ addNode' name nodeType p@{ boxes: { errors, forestOpen }, session, tree: (NTree
liftEffect $ T.modify_ (openNodesInsert (mkNodeId session id)) forestOpen liftEffect $ T.modify_ (openNodesInsert (mkNodeId session id)) forestOpen
refreshTree p refreshTree p
uploadFile' nodeType fileType mName contents p@{ boxes: { errors, tasks }, session, tree: (NTree (LNode { id }) _) } = do uploadFile' nodeType fileType mName contents p@{ boxes: { errors, tasks }, session, tree: (NTree (LNode { id }) _) } selection = do
eTask <- uploadFile { contents, fileType, id, mName, nodeType, session } eTask <- uploadFile { contents, fileType, id, mName, nodeType, selection, session }
handleRESTError errors eTask $ \task -> liftEffect $ do handleRESTError errors eTask $ \task -> liftEffect $ do
GAT.insert id task tasks GAT.insert id task tasks
here.log2 "[uploadFile'] UploadFile, uploaded, task:" task here.log2 "[uploadFile'] UploadFile, uploaded, task:" task
uploadArbitraryFile' mName blob p@{ boxes: { errors, tasks }, session, tree: (NTree (LNode { id }) _) } = do uploadArbitraryFile' mName blob p@{ boxes: { errors, tasks }, session, tree: (NTree (LNode { id }) _) } selection = do
eTask <- uploadArbitraryFile session id { blob, mName } eTask <- uploadArbitraryFile session id { blob, mName } selection
handleRESTError errors eTask $ \task -> liftEffect $ do handleRESTError errors eTask $ \task -> liftEffect $ do
GAT.insert id task tasks GAT.insert id task tasks
here.log2 "[uploadArbitraryFile'] UploadArbitraryFile, uploaded, task:" task here.log2 "[uploadArbitraryFile'] UploadArbitraryFile, uploaded, task:" task
...@@ -307,8 +313,10 @@ performAction (ShareTeam username) p = shareTeam userna ...@@ -307,8 +313,10 @@ performAction (ShareTeam username) p = shareTeam userna
performAction (SharePublic { params }) p = sharePublic params p performAction (SharePublic { params }) p = sharePublic params p
performAction (AddContact params) p = addContact params p performAction (AddContact params) p = addContact params p
performAction (AddNode name nodeType) p = addNode' name nodeType p performAction (AddNode name nodeType) p = addNode' name nodeType p
performAction (UploadFile nodeType fileType mName contents) p = uploadFile' nodeType fileType mName contents p performAction (UploadFile nodeType fileType mName contents selection) p =
performAction (UploadArbitraryFile mName blob) p = uploadArbitraryFile' mName blob p uploadFile' nodeType fileType mName contents p selection
performAction (UploadArbitraryFile mName blob selection) p =
uploadArbitraryFile' mName blob p selection
performAction DownloadNode _ = liftEffect $ here.log "[performAction] DownloadNode" performAction DownloadNode _ = liftEffect $ here.log "[performAction] DownloadNode"
performAction (MoveNode {params}) p = moveNode params p performAction (MoveNode {params}) p = moveNode params p
performAction (MergeNode {params}) p = mergeNode params p performAction (MergeNode {params}) p = mergeNode params p
......
...@@ -10,7 +10,7 @@ import Effect.Aff (Aff, launchAff) ...@@ -10,7 +10,7 @@ import Effect.Aff (Aff, launchAff)
import Effect.Class (liftEffect) import Effect.Class (liftEffect)
import Gargantext.AsyncTasks as GAT import Gargantext.AsyncTasks as GAT
import Gargantext.Components.App.Data (Boxes) import Gargantext.Components.App.Data (Boxes)
import Gargantext.Components.Forest.Tree.Node.Action (Action(..)) import Gargantext.Components.Forest.Tree.Node.Action.Types (Action(..))
import Gargantext.Components.Forest.Tree.Node.Action.Upload (DroppedFile(..), fileTypeView) import Gargantext.Components.Forest.Tree.Node.Action.Upload (DroppedFile(..), fileTypeView)
import Gargantext.Components.Forest.Tree.Node.Action.Upload.Types (FileType(..), UploadFileBlob(..)) import Gargantext.Components.Forest.Tree.Node.Action.Upload.Types (FileType(..), UploadFileBlob(..))
import Gargantext.Components.Forest.Tree.Node.Box (nodePopupView) import Gargantext.Components.Forest.Tree.Node.Box (nodePopupView)
...@@ -51,6 +51,7 @@ type NodeMainSpanProps = ...@@ -51,6 +51,7 @@ type NodeMainSpanProps =
, name :: Name , name :: Name
, nodeType :: GT.NodeType , nodeType :: GT.NodeType
, reload :: T2.ReloadS , reload :: T2.ReloadS
, root :: ID
, session :: Session , session :: Session
, setPopoverRef :: R.Ref (Maybe (Boolean -> Effect Unit)) , setPopoverRef :: R.Ref (Maybe (Boolean -> Effect Unit))
) )
......
module Gargantext.Components.Forest.Tree.Node.Action where module Gargantext.Components.Forest.Tree.Node.Action where
import Data.Generic.Rep (class Generic)
import Data.Maybe (Maybe(..))
import Effect.Aff (Aff)
import Gargantext.Prelude import Gargantext.Prelude
import Gargantext.Components.Forest.Tree.Node.Tools.SubTree.Types (SubTreeOut, SubTreeParams(..)) import Data.Maybe (Maybe(..))
import Effect.Aff (Aff)
import Gargantext.Components.Forest.Tree.Node.Action.Types (Action(..))
import Gargantext.Components.Forest.Tree.Node.Settings (NodeAction(..), glyphiconNodeAction) import Gargantext.Components.Forest.Tree.Node.Settings (NodeAction(..), glyphiconNodeAction)
import Gargantext.Components.Forest.Tree.Node.Action.Upload.Types (FileType, UploadFileBlob) import Gargantext.Components.Forest.Tree.Node.Tools.FTree (ID)
import Gargantext.Components.Forest.Tree.Node.Action.Update.Types (UpdateNodeParams) import Gargantext.Components.Forest.Tree.Node.Tools.SubTree.Types (SubTreeOut, SubTreeParams(..))
import Gargantext.Components.Forest.Tree.Node.Action.Contact.Types (AddContactParams)
import Gargantext.Sessions (Session) import Gargantext.Sessions (Session)
import Gargantext.Types as GT import Gargantext.Types as GT
type Props = type Props =
( dispatch :: Action -> Aff Unit ( dispatch :: Action -> Aff Unit
, id :: Int , id :: ID
, nodeType :: GT.NodeType , nodeType :: GT.NodeType
, session :: Session , session :: Session
) )
data Action = AddNode String GT.NodeType
| DeleteNode GT.NodeType
| RenameNode String
| UpdateNode UpdateNodeParams
| DoSearch GT.AsyncTaskWithType
| UploadFile GT.NodeType FileType (Maybe String) String
| UploadArbitraryFile (Maybe String) UploadFileBlob
| DownloadNode
| RefreshTree
| ClosePopover
| ShareTeam String
| AddContact AddContactParams
| SharePublic {params :: Maybe SubTreeOut}
| MoveNode {params :: Maybe SubTreeOut}
| MergeNode {params :: Maybe SubTreeOut}
| LinkNode {nodeType :: Maybe GT.NodeType, params :: Maybe SubTreeOut}
| NoAction
subTreeOut :: Action -> Maybe SubTreeOut subTreeOut :: Action -> Maybe SubTreeOut
subTreeOut (MoveNode {params}) = params subTreeOut (MoveNode {params}) = params
subTreeOut (MergeNode {params}) = params subTreeOut (MergeNode {params}) = params
...@@ -57,47 +33,6 @@ setTreeOut (LinkNode {nodeType, params:_}) p = LinkNode {nodeType, params: p} ...@@ -57,47 +33,6 @@ setTreeOut (LinkNode {nodeType, params:_}) p = LinkNode {nodeType, params: p}
setTreeOut (SharePublic {params:_}) p = SharePublic {params: p} setTreeOut (SharePublic {params:_}) p = SharePublic {params: p}
setTreeOut a _ = a setTreeOut a _ = a
derive instance Generic Action _
instance Eq Action where
eq (AddNode s1 nt1) (AddNode s2 nt2) = (eq s1 s2) && (eq nt1 nt2)
eq (DeleteNode nt1) (DeleteNode nt2) = eq nt1 nt2
eq (RenameNode s1) (RenameNode s2) = eq s1 s2
eq (UpdateNode un1) (UpdateNode un2) = eq un1 un2
eq (DoSearch at1) (DoSearch at2) = eq at1 at2
eq (UploadFile nt1 ft1 s1 _) (UploadFile nt2 ft2 s2 _) = (eq nt1 nt2) && (eq ft1 ft2) && (eq s1 s2)
eq (UploadArbitraryFile s1 _) (UploadArbitraryFile s2 _) = eq s1 s2
eq DownloadNode DownloadNode = true
eq RefreshTree RefreshTree = true
eq ClosePopover ClosePopover = true
eq (ShareTeam s1) (ShareTeam s2) = eq s1 s2
eq (AddContact ac1) (AddContact ac2) = eq ac1 ac2
eq (SharePublic p1) (SharePublic p2) = eq p1 p2
eq (MoveNode p1) (MoveNode p2) = eq p1 p2
eq (MergeNode p1) (MergeNode p2) = eq p1 p2
eq (LinkNode l1) (LinkNode l2) = eq l1 l2
eq NoAction NoAction = true
eq _ _ = false
instance Show Action where
show (AddNode _ _ ) = "AddNode"
show (DeleteNode _ ) = "DeleteNode"
show (RenameNode _ ) = "RenameNode"
show (UpdateNode _ ) = "UpdateNode"
show (ShareTeam _ ) = "ShareTeam"
show (AddContact _ ) = "AddContact"
show (SharePublic _ ) = "SharePublic"
show (DoSearch _ ) = "SearchQuery"
show (UploadFile _ _ _ _) = "UploadFile"
show (UploadArbitraryFile _ _) = "UploadArbitraryFile"
show RefreshTree = "RefreshTree"
show ClosePopover = "ClosePopover"
show DownloadNode = "Download"
show (MoveNode _ ) = "MoveNode"
show (MergeNode _ ) = "MergeNode"
show (LinkNode _ ) = "LinkNode"
show NoAction = "NoAction"
----------------------------------------------------------------------- -----------------------------------------------------------------------
icon :: Action -> String icon :: Action -> String
icon (AddNode _ _) = glyphiconNodeAction (Add []) icon (AddNode _ _) = glyphiconNodeAction (Add [])
...@@ -108,8 +43,8 @@ icon (ShareTeam _) = glyphiconNodeAction Share ...@@ -108,8 +43,8 @@ icon (ShareTeam _) = glyphiconNodeAction Share
icon (AddContact _) = glyphiconNodeAction Share icon (AddContact _) = glyphiconNodeAction Share
icon (SharePublic _ ) = glyphiconNodeAction (Publish { subTreeParams : SubTreeParams {showtypes:[], valitypes:[] }}) icon (SharePublic _ ) = glyphiconNodeAction (Publish { subTreeParams : SubTreeParams {showtypes:[], valitypes:[] }})
icon (DoSearch _) = glyphiconNodeAction SearchBox icon (DoSearch _) = glyphiconNodeAction SearchBox
icon (UploadFile _ _ _ _) = glyphiconNodeAction Upload icon (UploadFile _ _ _ _ _) = glyphiconNodeAction Upload
icon (UploadArbitraryFile _ _ ) = glyphiconNodeAction Upload icon (UploadArbitraryFile _ _ _ ) = glyphiconNodeAction Upload
icon RefreshTree = glyphiconNodeAction Refresh icon RefreshTree = glyphiconNodeAction Refresh
icon ClosePopover = glyphiconNodeAction CloseNodePopover icon ClosePopover = glyphiconNodeAction CloseNodePopover
icon DownloadNode = glyphiconNodeAction Download icon DownloadNode = glyphiconNodeAction Download
...@@ -122,21 +57,22 @@ icon NoAction = "hand-o-right" ...@@ -122,21 +57,22 @@ icon NoAction = "hand-o-right"
-- icon _ = "hand-o-right" -- icon _ = "hand-o-right"
text :: Action -> String text :: Action -> String
text (AddNode _ _ ) = "Add !" text (AddNode _ _ ) = "Add !"
text (DeleteNode _ ) = "Delete !" text (DeleteNode _ ) = "Delete !"
text (RenameNode _ ) = "Rename !" text (RenameNode _ ) = "Rename !"
text (UpdateNode _ ) = "Update !" text (UpdateNode _ ) = "Update !"
text (ShareTeam _ ) = "Share with team !" text (ShareTeam _ ) = "Share with team !"
text (AddContact _ ) = "Add contact !" text (AddContact _ ) = "Add contact !"
text (SharePublic _ ) = "Publish !" text (SharePublic _ ) = "Publish !"
text (DoSearch _ ) = "Launch search !" text (DoSearch _ ) = "Launch search !"
text (UploadFile _ _ _ _) = "Upload File !" text (UploadFile _ _ _ _ _) = "Upload File !"
text (UploadArbitraryFile _ _) = "Upload arbitrary file !" text (UploadArbitraryFile _ _ _) = "Upload arbitrary file !"
text RefreshTree = "Refresh Tree !" text RefreshTree = "Refresh Tree !"
text ClosePopover = "Close Popover !" text ClosePopover = "Close Popover !"
text DownloadNode = "Download !" text DownloadNode = "Download !"
text (MoveNode _ ) = "Move !" text (MoveNode _ ) = "Move !"
text (MergeNode _ ) = "Merge !" text (MergeNode _ ) = "Merge !"
text (LinkNode _ ) = "Link !" text (LinkNode _ ) = "Link !"
text NoAction = "No Action" text NoAction = "No Action"
----------------------------------------------------------------------- -----------------------------------------------------------------------
...@@ -11,7 +11,7 @@ import Data.String (Pattern(..), indexOf) ...@@ -11,7 +11,7 @@ import Data.String (Pattern(..), indexOf)
import Data.Tuple.Nested ((/\)) import Data.Tuple.Nested ((/\))
import Effect (Effect) import Effect (Effect)
import Effect.Aff (Aff, launchAff_) import Effect.Aff (Aff, launchAff_)
import Gargantext.Components.Forest.Tree.Node.Action (Action(..)) import Gargantext.Components.Forest.Tree.Node.Action.Types (Action(..))
import Gargantext.Components.Forest.Tree.Node.Settings (SettingsBox(..), settingsBox) import Gargantext.Components.Forest.Tree.Node.Settings (SettingsBox(..), settingsBox)
import Gargantext.Components.Forest.Tree.Node.Tools (formChoiceSafe, panel, submitButton) import Gargantext.Components.Forest.Tree.Node.Tools (formChoiceSafe, panel, submitButton)
import Gargantext.Components.InputWithEnter (inputWithEnter) import Gargantext.Components.InputWithEnter (inputWithEnter)
......
...@@ -10,7 +10,7 @@ import Reactix as R ...@@ -10,7 +10,7 @@ import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
import Toestand as T import Toestand as T
import Gargantext.Components.Forest.Tree.Node.Action (Action(..)) import Gargantext.Components.Forest.Tree.Node.Action.Types (Action(..))
import Gargantext.Components.Forest.Tree.Node.Action.Contact.Types (AddContactParams(..)) import Gargantext.Components.Forest.Tree.Node.Action.Contact.Types (AddContactParams(..))
import Gargantext.Config.REST (RESTError) import Gargantext.Config.REST (RESTError)
import Gargantext.Routes as GR import Gargantext.Routes as GR
......
...@@ -9,7 +9,7 @@ import Effect.Aff (Aff) ...@@ -9,7 +9,7 @@ import Effect.Aff (Aff)
import Reactix as R import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
import Gargantext.Components.Forest.Tree.Node.Action (Action(..)) import Gargantext.Components.Forest.Tree.Node.Action.Types (Action(..))
import Gargantext.Components.Forest.Tree.Node.Tools (submitButton, panel) import Gargantext.Components.Forest.Tree.Node.Tools (submitButton, panel)
import Gargantext.Config.REST (RESTError) import Gargantext.Config.REST (RESTError)
import Gargantext.Routes (SessionRoute(..)) import Gargantext.Routes (SessionRoute(..))
......
...@@ -4,7 +4,7 @@ import Data.Maybe (Maybe(..)) ...@@ -4,7 +4,7 @@ import Data.Maybe (Maybe(..))
import Reactix as R import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
import Gargantext.Components.Forest.Tree.Node.Action (Action(DownloadNode)) import Gargantext.Components.Forest.Tree.Node.Action.Types (Action(DownloadNode))
import Gargantext.Components.Forest.Tree.Node.Tools (fragmentPT, panel, submitButtonHref) import Gargantext.Components.Forest.Tree.Node.Tools (fragmentPT, panel, submitButtonHref)
import Gargantext.Ends (url) import Gargantext.Ends (url)
import Gargantext.Prelude (pure, ($)) import Gargantext.Prelude (pure, ($))
......
...@@ -7,7 +7,7 @@ import Data.Generic.Rep (class Generic) ...@@ -7,7 +7,7 @@ import Data.Generic.Rep (class Generic)
import Data.Maybe (Maybe(..)) import Data.Maybe (Maybe(..))
import Data.Show.Generic (genericShow) import Data.Show.Generic (genericShow)
import Effect.Aff (Aff) import Effect.Aff (Aff)
import Gargantext.Components.Forest.Tree.Node.Action (Action(..)) import Gargantext.Components.Forest.Tree.Node.Action.Types (Action(..))
import Gargantext.Components.Forest.Tree.Node.Tools (submitButton, panel) import Gargantext.Components.Forest.Tree.Node.Tools (submitButton, panel)
import Gargantext.Components.Forest.Tree.Node.Tools.SubTree (subTreeView, SubTreeParamsIn) import Gargantext.Components.Forest.Tree.Node.Tools.SubTree (subTreeView, SubTreeParamsIn)
import Gargantext.Config.REST (RESTError) import Gargantext.Config.REST (RESTError)
......
...@@ -10,7 +10,7 @@ import Reactix as R ...@@ -10,7 +10,7 @@ import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
import Toestand as T import Toestand as T
import Gargantext.Components.Forest.Tree.Node.Action (Action(..)) import Gargantext.Components.Forest.Tree.Node.Action.Types (Action(..))
import Gargantext.Components.Forest.Tree.Node.Tools (submitButton, panel, checkbox, checkboxesListGroup) import Gargantext.Components.Forest.Tree.Node.Tools (submitButton, panel, checkbox, checkboxesListGroup)
import Gargantext.Components.Forest.Tree.Node.Tools.SubTree (subTreeView, SubTreeParamsIn) import Gargantext.Components.Forest.Tree.Node.Tools.SubTree (subTreeView, SubTreeParamsIn)
import Gargantext.Config.REST (RESTError) import Gargantext.Config.REST (RESTError)
......
module Gargantext.Components.Forest.Tree.Node.Action.Move where module Gargantext.Components.Forest.Tree.Node.Action.Move where
import Gargantext.Prelude
import Data.Either (Either) import Data.Either (Either)
import Data.Maybe (Maybe(..)) import Data.Maybe (Maybe(..))
import Effect.Aff (Aff) import Effect.Aff (Aff)
import Reactix as R import Gargantext.Components.Forest.Tree.Node.Action.Types (Action(..))
import Reactix.DOM.HTML as H
import Toestand as T
import Gargantext.Components.Forest.Tree.Node.Action (Action(..))
import Gargantext.Components.Forest.Tree.Node.Tools (submitButton, panel) import Gargantext.Components.Forest.Tree.Node.Tools (submitButton, panel)
import Gargantext.Components.Forest.Tree.Node.Tools.SubTree (subTreeView, SubTreeParamsIn) import Gargantext.Components.Forest.Tree.Node.Tools.SubTree (subTreeView, SubTreeParamsIn)
import Gargantext.Config.REST (RESTError) import Gargantext.Config.REST (RESTError)
import Gargantext.Prelude
import Gargantext.Routes (SessionRoute(..)) import Gargantext.Routes (SessionRoute(..))
import Gargantext.Sessions (Session, put_) import Gargantext.Sessions (Session, put_)
import Gargantext.Types as GT import Gargantext.Types as GT
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
import Toestand as T
here :: R2.Here here :: R2.Here
here = R2.here "Gargantext.Components.Forest.Tree.Node.Action.Move" here = R2.here "Gargantext.Components.Forest.Tree.Node.Action.Move"
......
...@@ -10,7 +10,7 @@ import Simple.JSON as JSON ...@@ -10,7 +10,7 @@ import Simple.JSON as JSON
import Gargantext.Prelude import Gargantext.Prelude
import Gargantext.Components.Forest.Tree.Node.Action (Action(..)) import Gargantext.Components.Forest.Tree.Node.Action.Types (Action(..))
import Gargantext.Config.REST (RESTError) import Gargantext.Config.REST (RESTError)
import Gargantext.Routes as GR import Gargantext.Routes as GR
import Gargantext.Sessions (Session, put) import Gargantext.Sessions (Session, put)
......
...@@ -6,7 +6,7 @@ import Data.Maybe (Maybe) ...@@ -6,7 +6,7 @@ import Data.Maybe (Maybe)
import Effect (Effect) import Effect (Effect)
import Effect.Aff (Aff, launchAff) import Effect.Aff (Aff, launchAff)
import Gargantext.Components.App.Data (Boxes) import Gargantext.Components.App.Data (Boxes)
import Gargantext.Components.Forest.Tree.Node.Action (Action(..)) import Gargantext.Components.Forest.Tree.Node.Action.Types (Action(..))
import Gargantext.Components.Forest.Tree.Node.Action.Add (NodePopup) import Gargantext.Components.Forest.Tree.Node.Action.Add (NodePopup)
import Gargantext.Components.Forest.Tree.Node.Action.Search.SearchBar (searchBar) import Gargantext.Components.Forest.Tree.Node.Action.Search.SearchBar (searchBar)
import Gargantext.Components.Forest.Tree.Node.Action.Search.SearchField (defaultSearch) import Gargantext.Components.Forest.Tree.Node.Action.Search.SearchField (defaultSearch)
...@@ -38,16 +38,17 @@ actionSearchCpt = here.component "actionSearch" cpt ...@@ -38,16 +38,17 @@ actionSearchCpt = here.component "actionSearch" cpt
where where
cpt { boxes: { errors }, dispatch, id, nodePopup, session } _ = do cpt { boxes: { errors }, dispatch, id, nodePopup, session } _ = do
search <- T.useBox $ defaultSearch { node_id = id } search <- T.useBox $ defaultSearch { node_id = id }
pure $ R.fragment [ H.p { className: "action-search" } pure $ R.fragment
[ H.text $ "Search and create a private " [ H.p { className: "action-search" }
<> "corpus with the search query as corpus name." ] [ H.text $ "Search and create a private "
, searchBar { errors <> "corpus with the search query as corpus name." ]
, langs: allLangs , searchBar { errors
, onSearch: searchOn dispatch nodePopup , langs: allLangs
, search , onSearch: searchOn dispatch nodePopup
, session , search
} [] , session
] } []
]
where where
searchOn :: (Action -> Aff Unit) searchOn :: (Action -> Aff Unit)
-> Maybe NodePopup -> Maybe NodePopup
......
...@@ -34,11 +34,11 @@ searchBarCpt = here.component "searchBar" cpt ...@@ -34,11 +34,11 @@ searchBarCpt = here.component "searchBar" cpt
cpt { errors, langs, onSearch, search, session } _ = do cpt { errors, langs, onSearch, search, session } _ = do
--onSearchChange session s --onSearchChange session s
pure $ H.div { className: "search-bar" } pure $ H.div { className: "search-bar" }
[ searchField { databases: allDatabases [ searchField { databases: allDatabases
, errors , errors
, langs , langs
, onSearch , onSearch
, search , search
, session , session
} [] } []
] ]
...@@ -19,6 +19,7 @@ import URI.Query as Q ...@@ -19,6 +19,7 @@ import URI.Query as Q
import Gargantext.Prelude import Gargantext.Prelude
import Gargantext.Components.Lang (Lang) import Gargantext.Components.Lang (Lang)
import Gargantext.Components.ListSelection.Types as ListSelection
import Gargantext.Config.REST (RESTError) import Gargantext.Config.REST (RESTError)
import Gargantext.Ends (class ToUrl, backendUrl) import Gargantext.Ends (class ToUrl, backendUrl)
import Gargantext.Routes as GR import Gargantext.Routes as GR
...@@ -330,27 +331,13 @@ newtype SearchQuery = SearchQuery ...@@ -330,27 +331,13 @@ newtype SearchQuery = SearchQuery
, node_id :: Maybe Int , node_id :: Maybe Int
, offset :: Maybe Int , offset :: Maybe Int
, order :: Maybe SearchOrder , order :: Maybe SearchOrder
, selection :: ListSelection.Selection
} }
derive instance Generic SearchQuery _ derive instance Generic SearchQuery _
derive instance Newtype SearchQuery _ derive instance Newtype SearchQuery _
defaultSearchQuery :: SearchQuery
defaultSearchQuery = SearchQuery
{ query: ""
, databases: Empty
, datafield: Nothing
, files_id : []
, lang : Nothing
, limit : Nothing
, node_id : Nothing
, offset : Nothing
, order : Nothing
}
instance ToUrl Session SearchQuery where instance ToUrl Session SearchQuery where
toUrl (Session {backend}) q = backendUrl backend q2 toUrl (Session {backend}) q = backendUrl backend q2
where q2 = "new" <> Q.print (GT.toQuery q) where q2 = "new" <> Q.print (GT.toQuery q)
instance GT.ToQuery SearchQuery where instance GT.ToQuery SearchQuery where
toQuery (SearchQuery {offset, limit, order}) = toQuery (SearchQuery {offset, limit, order}) =
QP.print id id $ QP.QueryPairs QP.print id id $ QP.QueryPairs
...@@ -361,13 +348,28 @@ instance GT.ToQuery SearchQuery where ...@@ -361,13 +348,28 @@ instance GT.ToQuery SearchQuery where
pair k = maybe [] $ \v -> pair k = maybe [] $ \v ->
[ QP.keyFromString k /\ Just (QP.valueFromString $ show v) ] [ QP.keyFromString k /\ Just (QP.valueFromString $ show v) ]
instance JSON.WriteForeign SearchQuery where instance JSON.WriteForeign SearchQuery where
writeImpl (SearchQuery { databases, lang, node_id, query }) = writeImpl (SearchQuery { databases, lang, node_id, query, selection }) =
JSON.writeImpl { query: String.replace (String.Pattern "\"") (String.Replacement "\\\"") query JSON.writeImpl { query: String.replace (String.Pattern "\"") (String.Replacement "\\\"") query
, databases: databases , databases: databases
, lang: maybe "EN" show lang , lang: maybe "EN" show lang
, node_id: fromMaybe 0 node_id , node_id: fromMaybe 0 node_id
, flowListWith: selection
} }
defaultSearchQuery :: SearchQuery
defaultSearchQuery = SearchQuery
{ query : ""
, databases : Empty
, datafield : Nothing
, files_id : []
, lang : Nothing
, limit : Nothing
, node_id : Nothing
, offset : Nothing
, order : Nothing
, selection : ListSelection.MyListsFirst
}
performSearch :: Session -> Int -> SearchQuery -> Aff (Either RESTError GT.AsyncTaskWithType) performSearch :: Session -> Int -> SearchQuery -> Aff (Either RESTError GT.AsyncTaskWithType)
performSearch session nodeId q = do performSearch session nodeId q = do
eTask :: Either RESTError GT.AsyncTask <- post session p q eTask :: Either RESTError GT.AsyncTask <- post session p q
......
...@@ -13,8 +13,8 @@ import Toestand as T ...@@ -13,8 +13,8 @@ import Toestand as T
import Gargantext.Prelude import Gargantext.Prelude
import Gargantext.Components.Forest.Tree.Node.Action (Action) import Gargantext.Components.Forest.Tree.Node.Action.Types (Action)
import Gargantext.Components.Forest.Tree.Node.Action as Action import Gargantext.Components.Forest.Tree.Node.Action.Types as Action
import Gargantext.Components.Forest.Tree.Node.Tools as Tools import Gargantext.Components.Forest.Tree.Node.Tools as Tools
import Gargantext.Components.Forest.Tree.Node.Tools.SubTree (subTreeView, SubTreeParamsIn) import Gargantext.Components.Forest.Tree.Node.Tools.SubTree (subTreeView, SubTreeParamsIn)
import Gargantext.Config.REST (RESTError) import Gargantext.Config.REST (RESTError)
...@@ -22,6 +22,7 @@ import Gargantext.Routes as GR ...@@ -22,6 +22,7 @@ import Gargantext.Routes as GR
import Gargantext.Sessions (Session, post) import Gargantext.Sessions (Session, post)
import Gargantext.Types (ID) import Gargantext.Types (ID)
import Gargantext.Types as GT import Gargantext.Types as GT
import Gargantext.Utils.SimpleJSON as GUSJ
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
here :: R2.Here here :: R2.Here
...@@ -41,8 +42,12 @@ data ShareNodeParams = ShareTeamParams { username :: String } ...@@ -41,8 +42,12 @@ data ShareNodeParams = ShareTeamParams { username :: String }
| SharePublicParams { node_id :: Int } | SharePublicParams { node_id :: Int }
derive instance Eq ShareNodeParams derive instance Eq ShareNodeParams
derive instance Generic ShareNodeParams _ derive instance Generic ShareNodeParams _
instance JSON.ReadForeign ShareNodeParams where readImpl = JSONG.untaggedSumRep instance JSON.ReadForeign ShareNodeParams where readImpl = GUSJ.taggedSumRep
instance JSON.WriteForeign ShareNodeParams where writeImpl = JSON.writeImpl <<< show instance JSON.WriteForeign ShareNodeParams where
writeImpl (ShareTeamParams { username }) = JSON.writeImpl { "type": "ShareTeamParams"
, username }
writeImpl (SharePublicParams { node_id }) = JSON.writeImpl { "type": "SharePublicParams"
, node_id }
instance Show ShareNodeParams where show = genericShow instance Show ShareNodeParams where show = genericShow
------------------------------------------------------------------------ ------------------------------------------------------------------------
......
module Gargantext.Components.Forest.Tree.Node.Action.Types where
import Gargantext.Prelude
import Data.Generic.Rep (class Generic)
import Data.Maybe (Maybe)
import Gargantext.Components.Forest.Tree.Node.Action.Contact.Types (AddContactParams)
import Gargantext.Components.Forest.Tree.Node.Action.Update.Types (UpdateNodeParams)
import Gargantext.Components.Forest.Tree.Node.Action.Upload.Types (FileType, UploadFileBlob)
import Gargantext.Components.Forest.Tree.Node.Tools.SubTree.Types (SubTreeOut)
import Gargantext.Components.ListSelection.Types (Selection)
import Gargantext.Types as GT
data Action = AddNode String GT.NodeType
| DeleteNode GT.NodeType
| RenameNode String
| UpdateNode UpdateNodeParams
| DoSearch GT.AsyncTaskWithType
| UploadFile GT.NodeType FileType (Maybe String) String Selection
| UploadArbitraryFile (Maybe String) UploadFileBlob Selection
| DownloadNode
| RefreshTree
| ClosePopover
| ShareTeam String
| AddContact AddContactParams
| SharePublic {params :: Maybe SubTreeOut}
| MoveNode {params :: Maybe SubTreeOut}
| MergeNode {params :: Maybe SubTreeOut}
| LinkNode {nodeType :: Maybe GT.NodeType, params :: Maybe SubTreeOut}
| NoAction
derive instance Generic Action _
instance Eq Action where
eq (AddNode s1 nt1) (AddNode s2 nt2) = (eq s1 s2) && (eq nt1 nt2)
eq (DeleteNode nt1) (DeleteNode nt2) = eq nt1 nt2
eq (RenameNode s1) (RenameNode s2) = eq s1 s2
eq (UpdateNode un1) (UpdateNode un2) = eq un1 un2
eq (DoSearch at1) (DoSearch at2) = eq at1 at2
eq (UploadFile nt1 ft1 s1 _ _) (UploadFile nt2 ft2 s2 _ _) =
(eq nt1 nt2) && (eq ft1 ft2) && (eq s1 s2)
eq (UploadArbitraryFile s1 _ _) (UploadArbitraryFile s2 _ _) = eq s1 s2
eq DownloadNode DownloadNode = true
eq RefreshTree RefreshTree = true
eq ClosePopover ClosePopover = true
eq (ShareTeam s1) (ShareTeam s2) = eq s1 s2
eq (AddContact ac1) (AddContact ac2) = eq ac1 ac2
eq (SharePublic p1) (SharePublic p2) = eq p1 p2
eq (MoveNode p1) (MoveNode p2) = eq p1 p2
eq (MergeNode p1) (MergeNode p2) = eq p1 p2
eq (LinkNode l1) (LinkNode l2) = eq l1 l2
eq NoAction NoAction = true
eq _ _ = false
instance Show Action where
show (AddNode _ _ ) = "AddNode"
show (DeleteNode _ ) = "DeleteNode"
show (RenameNode _ ) = "RenameNode"
show (UpdateNode _ ) = "UpdateNode"
show (ShareTeam _ ) = "ShareTeam"
show (AddContact _ ) = "AddContact"
show (SharePublic _ ) = "SharePublic"
show (DoSearch _ ) = "SearchQuery"
show (UploadFile _ _ _ _ _) = "UploadFile"
show (UploadArbitraryFile _ _ _) = "UploadArbitraryFile"
show RefreshTree = "RefreshTree"
show ClosePopover = "ClosePopover"
show DownloadNode = "Download"
show (MoveNode _ ) = "MoveNode"
show (MergeNode _ ) = "MergeNode"
show (LinkNode _ ) = "LinkNode"
show NoAction = "NoAction"
...@@ -9,7 +9,7 @@ import Toestand as T ...@@ -9,7 +9,7 @@ import Toestand as T
import Gargantext.Prelude import Gargantext.Prelude
import Gargantext.Components.Forest.Tree.Node.Action (Action(..)) import Gargantext.Components.Forest.Tree.Node.Action.Types (Action(..))
import Gargantext.Components.Forest.Tree.Node.Action.Update.Types import Gargantext.Components.Forest.Tree.Node.Action.Update.Types
import Gargantext.Components.Forest.Tree.Node.Tools (formChoiceSafe, submitButton, panel) import Gargantext.Components.Forest.Tree.Node.Tools (formChoiceSafe, submitButton, panel)
import Gargantext.Config.REST (RESTError) import Gargantext.Config.REST (RESTError)
......
...@@ -14,13 +14,17 @@ import Data.Tuple.Nested ((/\)) ...@@ -14,13 +14,17 @@ import Data.Tuple.Nested ((/\))
import Effect (Effect) import Effect (Effect)
import Effect.Aff (Aff, launchAff) import Effect.Aff (Aff, launchAff)
import Effect.Class (liftEffect) import Effect.Class (liftEffect)
import Gargantext.Components.Forest.Tree.Node.Action (Action(..), Props) import Gargantext.Components.Forest.Tree.Node.Action (Props)
import Gargantext.Components.Forest.Tree.Node.Action.Types (Action(..))
import Gargantext.Components.Forest.Tree.Node.Action.Upload.Types (FileType(..), UploadFileBlob(..), readUFBAsText) import Gargantext.Components.Forest.Tree.Node.Action.Upload.Types (FileType(..), UploadFileBlob(..), readUFBAsText)
import Gargantext.Components.Forest.Tree.Node.Tools (fragmentPT, formChoiceSafe, panel) import Gargantext.Components.Forest.Tree.Node.Tools (fragmentPT, formChoiceSafe, panel)
import Gargantext.Components.Lang (Lang(..)) import Gargantext.Components.Lang (Lang(..))
import Gargantext.Components.ListSelection as ListSelection
import Gargantext.Components.ListSelection.Types (Selection(..))
import Gargantext.Components.ListSelection.Types as ListSelection
import Gargantext.Config.REST (RESTError) import Gargantext.Config.REST (RESTError)
import Gargantext.Routes as GR import Gargantext.Routes as GR
import Gargantext.Sessions (Session, postWwwUrlencoded) import Gargantext.Sessions (Session(..), postWwwUrlencoded)
import Gargantext.Types (NodeType(..), ID) import Gargantext.Types (NodeType(..), ID)
import Gargantext.Types as GT import Gargantext.Types as GT
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
...@@ -48,8 +52,10 @@ actionUpload :: R2.Component ActionUpload ...@@ -48,8 +52,10 @@ actionUpload :: R2.Component ActionUpload
actionUpload = R.createElement actionUploadCpt actionUpload = R.createElement actionUploadCpt
actionUploadCpt :: R.Component ActionUpload actionUploadCpt :: R.Component ActionUpload
actionUploadCpt = here.component "actionUpload" cpt where actionUploadCpt = here.component "actionUpload" cpt where
cpt { nodeType: Corpus, dispatch, id, session } _ = pure $ uploadFileView {dispatch, id, nodeType: GT.Corpus, session} cpt { nodeType: Corpus, dispatch, id, session } _ =
cpt { nodeType: NodeList, dispatch, id, session } _ = pure $ uploadTermListView {dispatch, id, nodeType: GT.NodeList, session} pure $ uploadFileView { dispatch, id, nodeType: GT.Corpus, session }
cpt { nodeType: NodeList, dispatch, id, session } _ =
pure $ uploadTermListView { dispatch, id, nodeType: GT.NodeList, session }
cpt props@{ nodeType: _ } _ = pure $ actionUploadOther props [] cpt props@{ nodeType: _ } _ = pure $ actionUploadOther props []
{- {-
...@@ -72,8 +78,7 @@ data DroppedFile = ...@@ -72,8 +78,7 @@ data DroppedFile =
, lang :: Lang , lang :: Lang
} }
derive instance Generic DroppedFile _ derive instance Generic DroppedFile _
instance Eq DroppedFile where instance Eq DroppedFile where eq = genericEq
eq = genericEq
type FileHash = String type FileHash = String
...@@ -88,11 +93,12 @@ uploadFileView props = R.createElement uploadFileViewCpt props [] ...@@ -88,11 +93,12 @@ uploadFileView props = R.createElement uploadFileViewCpt props []
uploadFileViewCpt :: R.Component Props uploadFileViewCpt :: R.Component Props
uploadFileViewCpt = here.component "uploadFileView" cpt uploadFileViewCpt = here.component "uploadFileView" cpt
where where
cpt {dispatch, id, nodeType} _ = do cpt { dispatch, id, nodeType, session } _ = do
-- mFile :: R.State (Maybe UploadFile) <- R.useState' Nothing -- mFile :: R.State (Maybe UploadFile) <- R.useState' Nothing
mFile <- T.useBox (Nothing :: Maybe UploadFile) mFile <- T.useBox (Nothing :: Maybe UploadFile)
fileType <- T.useBox CSV fileType <- T.useBox CSV
lang <- T.useBox EN lang <- T.useBox EN
selection <- T.useBox ListSelection.MyListsFirst
let setFileType' val = T.write_ val fileType let setFileType' val = T.write_ val fileType
let setLang' val = T.write_ val lang let setLang' val = T.write_ val lang
...@@ -125,14 +131,18 @@ uploadFileViewCpt = here.component "uploadFileView" cpt ...@@ -125,14 +131,18 @@ uploadFileViewCpt = here.component "uploadFileView" cpt
show show
] ]
] ]
, R2.row
[ H.div { className: "col-6 flex-space-around" }
[ ListSelection.selection { selection, session } [] ]
]
] ]
let footer = H.div {} [ uploadButton { dispatch let footer = H.div {} [ uploadButton { dispatch
, fileType , fileType
, lang , lang
, id
, mFile , mFile
, nodeType , nodeType
, selection
} }
] ]
pure $ panel bodies footer pure $ panel bodies footer
...@@ -152,12 +162,12 @@ uploadFileViewCpt = here.component "uploadFileView" cpt ...@@ -152,12 +162,12 @@ uploadFileViewCpt = here.component "uploadFileView" cpt
type UploadButtonProps = type UploadButtonProps =
( dispatch :: Action -> Aff Unit ( dispatch :: Action -> Aff Unit
, fileType :: T.Box FileType , fileType :: T.Box FileType
, id :: GT.ID , lang :: T.Box Lang
, lang :: T.Box Lang , mFile :: T.Box (Maybe UploadFile)
, mFile :: T.Box (Maybe UploadFile) , nodeType :: GT.NodeType
, nodeType :: GT.NodeType , selection :: T.Box ListSelection.Selection
) )
uploadButton :: Record UploadButtonProps -> R.Element uploadButton :: Record UploadButtonProps -> R.Element
...@@ -167,13 +177,14 @@ uploadButtonCpt = here.component "uploadButton" cpt ...@@ -167,13 +177,14 @@ uploadButtonCpt = here.component "uploadButton" cpt
where where
cpt { dispatch cpt { dispatch
, fileType , fileType
, id
, lang , lang
, mFile , mFile
, nodeType , nodeType
, selection
} _ = do } _ = do
fileType' <- T.useLive T.unequal fileType fileType' <- T.useLive T.unequal fileType
mFile' <- T.useLive T.unequal mFile mFile' <- T.useLive T.unequal mFile
selection' <- T.useLive T.unequal selection
let disabled = case mFile' of let disabled = case mFile' of
Nothing -> "1" Nothing -> "1"
...@@ -183,19 +194,19 @@ uploadButtonCpt = here.component "uploadButton" cpt ...@@ -183,19 +194,19 @@ uploadButtonCpt = here.component "uploadButton" cpt
, "type" : "button" , "type" : "button"
, disabled , disabled
, style : { width: "100%" } , style : { width: "100%" }
, on: {click: onClick fileType' mFile'} , on: { click: onClick fileType' mFile' selection' }
} [ H.text "Upload" ] } [ H.text "Upload" ]
where where
onClick fileType' mFile' e = do onClick fileType' mFile' selection' e = do
let { blob, name } = unsafePartial $ fromJust mFile' let { blob, name } = unsafePartial $ fromJust mFile'
here.log2 "[uploadButton] fileType" fileType' here.log2 "[uploadButton] fileType" fileType'
void $ launchAff do void $ launchAff do
case fileType' of case fileType' of
Arbitrary -> Arbitrary ->
dispatch $ UploadArbitraryFile (Just name) blob dispatch $ UploadArbitraryFile (Just name) blob selection'
_ -> do _ -> do
contents <- readUFBAsText blob contents <- readUFBAsText blob
dispatch $ UploadFile nodeType fileType' (Just name) contents dispatch $ UploadFile nodeType fileType' (Just name) contents selection'
liftEffect $ do liftEffect $ do
T.write_ Nothing mFile T.write_ Nothing mFile
T.write_ CSV fileType T.write_ CSV fileType
...@@ -282,7 +293,7 @@ fileTypeViewCpt = here.component "fileTypeView" cpt ...@@ -282,7 +293,7 @@ fileTypeViewCpt = here.component "fileTypeView" cpt
T.write_ Nothing droppedFile T.write_ Nothing droppedFile
launchAff $ do launchAff $ do
contents <- readUFBAsText blob contents <- readUFBAsText blob
dispatch $ UploadFile nodeType ft Nothing contents dispatch $ UploadFile nodeType ft Nothing contents (SelectedLists [])
} }
} [H.text "Upload"] } [H.text "Upload"]
Nothing -> Nothing ->
...@@ -303,12 +314,13 @@ instance GT.ToQuery FileUploadQuery where ...@@ -303,12 +314,13 @@ instance GT.ToQuery FileUploadQuery where
where pair :: forall a. Show a => String -> a -> Array (Tuple QP.Key (Maybe QP.Value)) where pair :: forall a. Show a => String -> a -> Array (Tuple QP.Key (Maybe QP.Value))
pair k v = [ QP.keyFromString k /\ (Just $ QP.valueFromString $ show v) ] pair k v = [ QP.keyFromString k /\ (Just $ QP.valueFromString $ show v) ]
uploadFile :: { contents :: String uploadFile :: { contents :: String
, fileType :: FileType , fileType :: FileType
, id :: ID , id :: ID
, nodeType :: GT.NodeType , nodeType :: GT.NodeType
, mName :: Maybe String , mName :: Maybe String
, session :: Session } , selection :: ListSelection.Selection
, session :: Session }
-> Aff (Either RESTError GT.AsyncTaskWithType) -> Aff (Either RESTError GT.AsyncTaskWithType)
{- {-
uploadFile session NodeList id JSON { mName, contents } = do uploadFile session NodeList id JSON { mName, contents } = do
...@@ -350,8 +362,9 @@ uploadFile { contents, fileType, id, nodeType, mName, session } = do ...@@ -350,8 +362,9 @@ uploadFile { contents, fileType, id, nodeType, mName, session } = do
uploadArbitraryFile :: Session uploadArbitraryFile :: Session
-> ID -> ID
-> {blob :: UploadFileBlob, mName :: Maybe String} -> {blob :: UploadFileBlob, mName :: Maybe String}
-> ListSelection.Selection
-> Aff (Either RESTError GT.AsyncTaskWithType) -> Aff (Either RESTError GT.AsyncTaskWithType)
uploadArbitraryFile session id {mName, blob: UploadFileBlob blob} = do uploadArbitraryFile session id {mName, blob: UploadFileBlob blob} selection = do
contents <- readAsDataURL blob contents <- readAsDataURL blob
uploadArbitraryDataURL session id mName contents uploadArbitraryDataURL session id mName contents
...@@ -468,6 +481,6 @@ uploadTermButtonCpt = here.component "uploadTermButton" cpt ...@@ -468,6 +481,6 @@ uploadTermButtonCpt = here.component "uploadTermButton" cpt
let {name, blob} = unsafePartial $ fromJust mFile' let {name, blob} = unsafePartial $ fromJust mFile'
void $ launchAff do void $ launchAff do
contents <- readUFBAsText blob contents <- readUFBAsText blob
_ <- dispatch $ UploadFile nodeType uploadType' (Just name) contents _ <- dispatch $ UploadFile nodeType uploadType' (Just name) contents (SelectedLists [])
liftEffect $ do liftEffect $ do
T.write_ Nothing mFile T.write_ Nothing mFile
...@@ -6,7 +6,6 @@ import Data.Array as A ...@@ -6,7 +6,6 @@ import Data.Array as A
import Data.Maybe (Maybe(..)) import Data.Maybe (Maybe(..))
import Effect.Aff (Aff) import Effect.Aff (Aff)
import Gargantext.Components.App.Data (Boxes) import Gargantext.Components.App.Data (Boxes)
import Gargantext.Components.Forest.Tree.Node.Action (Action)
import Gargantext.Components.Forest.Tree.Node.Action.Add (NodePopup(..), addNodeView) import Gargantext.Components.Forest.Tree.Node.Action.Add (NodePopup(..), addNodeView)
import Gargantext.Components.Forest.Tree.Node.Action.Contact as Contact import Gargantext.Components.Forest.Tree.Node.Action.Contact as Contact
import Gargantext.Components.Forest.Tree.Node.Action.Delete (actionDelete) import Gargantext.Components.Forest.Tree.Node.Action.Delete (actionDelete)
...@@ -18,6 +17,7 @@ import Gargantext.Components.Forest.Tree.Node.Action.Move (moveNode) ...@@ -18,6 +17,7 @@ import Gargantext.Components.Forest.Tree.Node.Action.Move (moveNode)
import Gargantext.Components.Forest.Tree.Node.Action.Rename (renameAction) import Gargantext.Components.Forest.Tree.Node.Action.Rename (renameAction)
import Gargantext.Components.Forest.Tree.Node.Action.Search (actionSearch) import Gargantext.Components.Forest.Tree.Node.Action.Search (actionSearch)
import Gargantext.Components.Forest.Tree.Node.Action.Share as Share import Gargantext.Components.Forest.Tree.Node.Action.Share as Share
import Gargantext.Components.Forest.Tree.Node.Action.Types (Action)
import Gargantext.Components.Forest.Tree.Node.Action.Update (update) import Gargantext.Components.Forest.Tree.Node.Action.Update (update)
import Gargantext.Components.Forest.Tree.Node.Action.Upload (actionUpload) import Gargantext.Components.Forest.Tree.Node.Action.Upload (actionUpload)
import Gargantext.Components.Forest.Tree.Node.Box.Types (NodePopupProps, NodePopupS) import Gargantext.Components.Forest.Tree.Node.Box.Types (NodePopupProps, NodePopupS)
...@@ -25,7 +25,7 @@ import Gargantext.Components.Forest.Tree.Node.Settings (NodeAction(..), Settings ...@@ -25,7 +25,7 @@ import Gargantext.Components.Forest.Tree.Node.Settings (NodeAction(..), Settings
import Gargantext.Components.Forest.Tree.Node.Status (Status(..), hasStatus) import Gargantext.Components.Forest.Tree.Node.Status (Status(..), hasStatus)
import Gargantext.Components.Forest.Tree.Node.Tools (textInputBox, fragmentPT) import Gargantext.Components.Forest.Tree.Node.Tools (textInputBox, fragmentPT)
import Gargantext.Sessions (Session) import Gargantext.Sessions (Session)
import Gargantext.Types (FrontendError, ID, Name, prettyNodeType) import Gargantext.Types (ID, Name, prettyNodeType)
import Gargantext.Types as GT import Gargantext.Types as GT
import Gargantext.Utils.Glyphicon (glyphicon, glyphiconActive) import Gargantext.Utils.Glyphicon (glyphicon, glyphiconActive)
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
...@@ -40,7 +40,7 @@ type CommonProps = ...@@ -40,7 +40,7 @@ type CommonProps =
( dispatch :: Action -> Aff Unit ( dispatch :: Action -> Aff Unit
, session :: Session ) , session :: Session )
nodePopupView :: Record NodePopupProps -> R.Element nodePopupView :: R2.Leaf NodePopupProps
nodePopupView p = R.createElement nodePopupCpt p [] nodePopupView p = R.createElement nodePopupCpt p []
nodePopupCpt :: R.Component NodePopupProps nodePopupCpt :: R.Component NodePopupProps
nodePopupCpt = here.component "nodePopupView" cpt where nodePopupCpt = here.component "nodePopupView" cpt where
......
...@@ -5,7 +5,7 @@ import Data.Maybe (Maybe) ...@@ -5,7 +5,7 @@ import Data.Maybe (Maybe)
import Effect (Effect) import Effect (Effect)
import Effect.Aff (Aff) import Effect.Aff (Aff)
import Gargantext.Components.App.Data (Boxes) import Gargantext.Components.App.Data (Boxes)
import Gargantext.Components.Forest.Tree.Node.Action (Action) import Gargantext.Components.Forest.Tree.Node.Action.Types (Action)
import Gargantext.Components.Forest.Tree.Node.Settings (NodeAction) import Gargantext.Components.Forest.Tree.Node.Settings (NodeAction)
import Gargantext.Prelude (Unit) import Gargantext.Prelude (Unit)
import Gargantext.Sessions (Session) import Gargantext.Sessions (Session)
......
module Gargantext.Components.Forest.Tree.Node.Tools where module Gargantext.Components.Forest.Tree.Node.Tools where
import Data.Foldable (intercalate)
import Data.Maybe (fromMaybe, Maybe(..)) import Data.Maybe (fromMaybe, Maybe(..))
import Data.Nullable (null)
import Data.Set (Set) import Data.Set (Set)
import Data.Set as Set import Data.Set as Set
import Data.String as S import Data.String as S
...@@ -9,13 +9,14 @@ import Data.String.CodeUnits as DSCU ...@@ -9,13 +9,14 @@ import Data.String.CodeUnits as DSCU
import Effect (Effect) import Effect (Effect)
import Effect.Aff (Aff, launchAff, launchAff_) import Effect.Aff (Aff, launchAff, launchAff_)
import Gargantext.Components.App.Data (Boxes) import Gargantext.Components.App.Data (Boxes)
import Gargantext.Components.Forest.Tree.Node.Action (Action, icon, text) import Gargantext.Components.Forest.Tree.Node.Action (icon, text)
import Gargantext.Components.Forest.Tree.Node.Action.Types (Action)
import Gargantext.Components.InputWithEnter (inputWithEnter) import Gargantext.Components.InputWithEnter (inputWithEnter)
import Gargantext.Ends (Frontends, url) import Gargantext.Ends (Frontends, url)
import Gargantext.Prelude (class Ord, class Read, class Show, Unit, bind, const, discard, map, not, pure, read, show, when, mempty, ($), (<), (<<<), (<>), (<$>), (<*>)) import Gargantext.Prelude (class Ord, class Read, class Show, Unit, bind, const, discard, map, not, pure, read, show, when, mempty, ($), (<), (<<<), (<>), (<$>), (<*>))
import Gargantext.Sessions (Session, sessionId) import Gargantext.Sessions (Session, sessionId)
import Gargantext.Types as GT import Gargantext.Types as GT
import Gargantext.Utils (toggleSet) import Gargantext.Utils (toggleSet, (?))
import Gargantext.Utils.Glyphicon (glyphicon) import Gargantext.Utils.Glyphicon (glyphicon)
import Gargantext.Utils.ReactTooltip as ReactTooltip import Gargantext.Utils.ReactTooltip as ReactTooltip
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
...@@ -201,7 +202,6 @@ type CheckboxProps = ...@@ -201,7 +202,6 @@ type CheckboxProps =
checkbox :: R2.Leaf CheckboxProps checkbox :: R2.Leaf CheckboxProps
checkbox props = R.createElement checkboxCpt props [] checkbox props = R.createElement checkboxCpt props []
checkboxCpt :: R.Component CheckboxProps checkboxCpt :: R.Component CheckboxProps
checkboxCpt = here.component "checkbox" cpt checkboxCpt = here.component "checkbox" cpt
where where
...@@ -269,7 +269,7 @@ nodeLink = R.createElement nodeLinkCpt ...@@ -269,7 +269,7 @@ nodeLink = R.createElement nodeLinkCpt
nodeLinkCpt :: R.Component NodeLinkProps nodeLinkCpt :: R.Component NodeLinkProps
nodeLinkCpt = here.component "nodeLink" cpt nodeLinkCpt = here.component "nodeLink" cpt
where where
cpt { boxes: { handed } cpt { boxes
, folderOpen , folderOpen
, frontends , frontends
, id , id
...@@ -278,13 +278,12 @@ nodeLinkCpt = here.component "nodeLink" cpt ...@@ -278,13 +278,12 @@ nodeLinkCpt = here.component "nodeLink" cpt
, nodeType , nodeType
, session , session
} _ = do } _ = do
popoverRef <- R.useRef null
pure $ pure $
H.div { className: "node-link" H.div { className: "node-link"
, on: { click } } , on: { click } }
[ H.a { href, data: { for: tooltipId id, tip: true } } [ H.a { href, data: { for: tooltipId id, tip: true } }
[ nodeText { handed, isSelected, name } [] [ nodeText { isSelected, name }
, ReactTooltip.reactTooltip { effect: "float", id: tooltipId id, type: "dark" } , ReactTooltip.reactTooltip { effect: "float", id: tooltipId id, type: "dark" }
[ R2.row [ R2.row
[ H.h4 {className: GT.fldr nodeType true} [ H.h4 {className: GT.fldr nodeType true}
...@@ -305,29 +304,45 @@ nodeLinkCpt = here.component "nodeLink" cpt ...@@ -305,29 +304,45 @@ nodeLinkCpt = here.component "nodeLink" cpt
type NodeTextProps = type NodeTextProps =
( isSelected :: Boolean ( isSelected :: Boolean
, handed :: T.Box GT.Handed
, name :: GT.Name , name :: GT.Name
) )
nodeText :: R2.Component NodeTextProps nodeText :: R2.Leaf NodeTextProps
nodeText = R.createElement nodeTextCpt nodeText p = R.createElement nodeTextCpt p []
nodeTextCpt :: R.Component NodeTextProps nodeTextCpt :: R.Memo NodeTextProps
nodeTextCpt = here.component "nodeText" cpt where nodeTextCpt = R.memo' $ here.component "nodeText" cpt where
cpt { isSelected, handed, name } _ = do cpt props@{ isSelected } _ = do
handed' <- T.useLive T.unequal handed -- Computed
pure $ if isSelected then let
H.u { className }
[ H.b {} className = intercalate " "
[ H.text ("| " <> name15 name <> " | ") ] [ "node-text"
] , isSelected ? "node-text--selected" $ ""
else ]
GT.flipHanded l r handed' where
l = H.text "..." prefix = isSelected ?
r = H.text (name15 name) "" $
name_ len n = "..."
if S.length n < len then n
else case (DSCU.slice 0 len n) of name = isSelected ?
Nothing -> "???" "| " <> (textEllipsisBreak 15 props.name) <> " | " $
Just s -> s <> "..." textEllipsisBreak 15 props.name
name15 = name_ 15
className = "node-text" -- Render
pure $
H.span { className }
[
H.span {}
[ H.text prefix ]
,
H.span {}
[ H.text name ]
]
textEllipsisBreak :: Int -> String -> String
textEllipsisBreak len n =
if S.length n < len then n
else case (DSCU.slice 0 len n) of
Nothing -> "???"
Just s -> s <> "..."
...@@ -2,12 +2,16 @@ module Gargantext.Components.Forest.Tree.Node.Tools.SubTree where ...@@ -2,12 +2,16 @@ module Gargantext.Components.Forest.Tree.Node.Tools.SubTree where
import Gargantext.Prelude import Gargantext.Prelude
import Data.Array (length)
import Data.Array as A import Data.Array as A
import Data.Either (Either) import Data.Either (Either)
import Data.Foldable (intercalate)
import Data.Maybe (Maybe(..)) import Data.Maybe (Maybe(..))
import Data.Tuple.Nested ((/\))
import Effect.Aff (Aff) import Effect.Aff (Aff)
import Gargantext.Components.App.Data (Boxes) import Gargantext.Components.App.Data (Boxes)
import Gargantext.Components.Forest.Tree.Node.Action (Props, Action, subTreeOut, setTreeOut) import Gargantext.Components.Forest.Tree.Node.Action (Props, subTreeOut, setTreeOut)
import Gargantext.Components.Forest.Tree.Node.Action.Types (Action)
import Gargantext.Components.Forest.Tree.Node.Tools (nodeText) import Gargantext.Components.Forest.Tree.Node.Tools (nodeText)
import Gargantext.Components.Forest.Tree.Node.Tools.FTree (FTree, LNode(..), NTree(..)) import Gargantext.Components.Forest.Tree.Node.Tools.FTree (FTree, LNode(..), NTree(..))
import Gargantext.Components.Forest.Tree.Node.Tools.SubTree.Types (SubTreeParams(..), SubTreeOut(..)) import Gargantext.Components.Forest.Tree.Node.Tools.SubTree.Types (SubTreeParams(..), SubTreeOut(..))
...@@ -16,8 +20,9 @@ import Gargantext.Hooks.Loader (useLoader) ...@@ -16,8 +20,9 @@ import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Routes as GR import Gargantext.Routes as GR
import Gargantext.Sessions (Session(..), get) import Gargantext.Sessions (Session(..), get)
import Gargantext.Types as GT import Gargantext.Types as GT
import Gargantext.Utils ((?))
import Gargantext.Utils.Reactix (if', useBox', useLive')
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
import React.SyntheticEvent as E
import Reactix as R import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
import Record as Record import Record as Record
...@@ -91,63 +96,94 @@ type CorpusTreeProps = ...@@ -91,63 +96,94 @@ type CorpusTreeProps =
subTreeViewLoaded :: R2.Component CorpusTreeProps subTreeViewLoaded :: R2.Component CorpusTreeProps
subTreeViewLoaded = R.createElement subTreeViewLoadedCpt subTreeViewLoaded = R.createElement subTreeViewLoadedCpt
subTreeViewLoadedCpt :: R.Component CorpusTreeProps subTreeViewLoadedCpt :: R.Component CorpusTreeProps
subTreeViewLoadedCpt = here.component "subTreeViewLoaded" cpt subTreeViewLoadedCpt = here.component "subTreeViewLoaded" cpt where
where cpt props _ = do
cpt p@{ boxes: { handed } } _ = do
handed' <- T.useLive T.unequal handed let pRender = Record.merge { render: subTreeTreeView } props
let pRender = Record.merge { render: subTreeTreeView } p
pure $
pure $ H.div {className:"tree"}
[ H.div { className: if handed' == GT.RightHanded H.div { className: "subtree" }
then "righthanded" [ subTreeTreeView (CorpusTreeRenderProps pRender) [] ]
else "lefthanded"
}
[ subTreeTreeView (CorpusTreeRenderProps pRender) [] ]
]
newtype CorpusTreeRenderProps = CorpusTreeRenderProps newtype CorpusTreeRenderProps = CorpusTreeRenderProps
{ render :: CorpusTreeRenderProps -> Array R.Element -> R.Element { render :: CorpusTreeRenderProps -> Array R.Element -> R.Element
| CorpusTreeProps } | CorpusTreeProps
}
subTreeTreeView :: CorpusTreeRenderProps -> Array R.Element -> R.Element subTreeTreeView :: CorpusTreeRenderProps -> Array R.Element -> R.Element
subTreeTreeView = R2.ntCreateElement subTreeTreeViewCpt subTreeTreeView = R2.ntCreateElement subTreeTreeViewCpt
subTreeTreeViewCpt :: R2.NTComponent CorpusTreeRenderProps subTreeTreeViewCpt :: R2.NTComponent CorpusTreeRenderProps
subTreeTreeViewCpt = here.ntComponent "subTreeTreeView" cpt where subTreeTreeViewCpt = here.ntComponent "subTreeTreeView" cpt where
cpt (CorpusTreeRenderProps p@{ action cpt (CorpusTreeRenderProps p@{ id
, boxes: { handed }
, id
, render , render
, subTreeParams , subTreeParams
, tree: NTree (LNode { id: targetId, name, nodeType }) ary }) _ = do , tree: NTree (LNode { id: targetId, name, nodeType }) ary }) _ = do
action' <- T.useLive T.unequal action -- Hooks
handed' <- T.useLive T.unequal handed action <- useLive' p.action
isExpanded /\ isExpandedBox <- useBox' false
let click e = do -- Computed
let action'' = if not validNodeType then Nothing else Just $ SubTreeOut { in: id, out: targetId } let
E.preventDefault e expandCbk _ = T.modify_ not isExpandedBox
E.stopPropagation e
T.modify_ (\a -> setTreeOut a action'') action selectCbk _ = do
params <- pure $
if validNodeType
then Just $ SubTreeOut { in: id, out: targetId }
else Nothing
T.modify_ (\a -> setTreeOut a params) p.action
children = (map (\ctree -> render (CorpusTreeRenderProps (p { tree = ctree })) []) sortedAry) :: Array R.Element children = (map (\ctree -> render (CorpusTreeRenderProps (p { tree = ctree })) []) sortedAry) :: Array R.Element
pure $ H.div {} $ GT.reverseHanded handed' hasChild = length children > 0
[ H.div { className: nodeClass validNodeType }
[ H.span { className: "text" -- Render
, on: { click } } pure $
[ nodeText { handed
, isSelected: isSelected targetId action' H.div
, name: " " <> name } [] { className: intercalate " "
, H.span { className: "children" } children [ "subtree__node"
, validNodeType ? "subtree__node--can-be-selected" $ ""
]
}
[
H.div
{ className: "subtree__node__text" }
[
H.div
{ className: "subtree__node__icons"
, on: { click: expandCbk }
}
[
H.span { className: GT.fldr nodeType true } []
,
if' hasChild $
if isExpanded then
H.span { className: "fa fa-chevron-down" } []
else
H.span { className: "fa fa-chevron-right" } []
]
,
H.div
{ on: { click: selectCbk } }
[
nodeText
{ isSelected: isSelected targetId action
, name
}
]
] ]
] ,
if' (hasChild && isExpanded) $
H.div { className: "subtree__node__children" }
children
] ]
where where
nodeClass vnt = "node " <> GT.fldr nodeType true <> " " <> validNodeTypeClass where
validNodeTypeClass = if vnt then "node-type-valid" else ""
SubTreeParams { valitypes } = subTreeParams SubTreeParams { valitypes } = subTreeParams
sortedAry = A.sortWith (\(NTree (LNode {id:id'}) _) -> id') sortedAry = A.sortWith (\(NTree (LNode {id:id'}) _) -> id')
$ A.filter (\(NTree (LNode {id:id'}) _) -> id'/= id) ary $ A.filter (\(NTree (LNode {id:id'}) _) -> id'/= id) ary
validNodeType = (A.elem nodeType valitypes) && (id /= targetId) validNodeType = (A.elem nodeType valitypes) && (id /= targetId)
isSelected n action' = case (subTreeOut action') of isSelected n action = case (subTreeOut action) of
Nothing -> false Nothing -> false
(Just (SubTreeOut {out})) -> n == out (Just (SubTreeOut {out})) -> n == out
module Gargantext.Components.Forest.Tree.Node.Tools.Sync where module Gargantext.Components.Forest.Tree.Node.Tools.Sync where
import Gargantext.Prelude import Gargantext.Prelude
( Unit, bind, const, discard, pure, unit, ($), (<>), (==) ) ( Unit, bind, discard, pure, unit, ($), (<>), (==) )
import Effect.Aff (Aff, launchAff_) import Effect.Aff (Aff, launchAff_)
import Data.Tuple.Nested ((/\))
import Data.Maybe (Maybe(..)) import Data.Maybe (Maybe(..))
import Data.Tuple (fst)
import Effect.Class (liftEffect) import Effect.Class (liftEffect)
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
import Reactix as R import Reactix as R
...@@ -69,7 +67,7 @@ graphUpdateButtonCpt = here.component "graphUpdateButton" cpt ...@@ -69,7 +67,7 @@ graphUpdateButtonCpt = here.component "graphUpdateButton" cpt
onClick true enabled = do onClick true enabled = do
launchAff_ $ do launchAff_ $ do
liftEffect $ T.write_ false enabled liftEffect $ T.write_ false enabled
g <- GraphAPI.updateGraphVersions { graphId: id, session } _g <- GraphAPI.updateGraphVersions { graphId: id, session }
liftEffect $ T.write_ true enabled liftEffect $ T.write_ true enabled
refresh unit refresh unit
pure unit pure unit
...@@ -105,7 +103,6 @@ type NodeListUpdateButtonProps = ...@@ -105,7 +103,6 @@ type NodeListUpdateButtonProps =
nodeListUpdateButton :: Record NodeListUpdateButtonProps -> R.Element nodeListUpdateButton :: Record NodeListUpdateButtonProps -> R.Element
nodeListUpdateButton p = R.createElement nodeListUpdateButtonCpt p [] nodeListUpdateButton p = R.createElement nodeListUpdateButtonCpt p []
nodeListUpdateButtonCpt :: R.Component NodeListUpdateButtonProps nodeListUpdateButtonCpt :: R.Component NodeListUpdateButtonProps
nodeListUpdateButtonCpt = here.component "nodeListUpdateButton" cpt nodeListUpdateButtonCpt = here.component "nodeListUpdateButton" cpt
where where
......
...@@ -2,7 +2,7 @@ module Gargantext.Components.GraphExplorer.API where ...@@ -2,7 +2,7 @@ module Gargantext.Components.GraphExplorer.API where
import Gargantext.Prelude import Gargantext.Prelude
import Data.Either (Either(..)) import Data.Either (Either)
import Data.Maybe (Maybe) import Data.Maybe (Maybe)
import Effect.Aff (Aff) import Effect.Aff (Aff)
import Gargantext.Components.GraphExplorer.Types as GET import Gargantext.Components.GraphExplorer.Types as GET
......
...@@ -21,7 +21,6 @@ import Gargantext.Components.Forest.Tree.Node.Action.Upload (uploadArbitraryData ...@@ -21,7 +21,6 @@ import Gargantext.Components.Forest.Tree.Node.Action.Upload (uploadArbitraryData
import Gargantext.Components.GraphExplorer.API (cloneGraph) import Gargantext.Components.GraphExplorer.API (cloneGraph)
import Gargantext.Components.GraphExplorer.Types as GET import Gargantext.Components.GraphExplorer.Types as GET
import Gargantext.Components.GraphExplorer.Utils as GEU import Gargantext.Components.GraphExplorer.Utils as GEU
import Gargantext.Config.REST (RESTError)
import Gargantext.Hooks.Sigmax as Sigmax import Gargantext.Hooks.Sigmax as Sigmax
import Gargantext.Hooks.Sigmax.Sigma as Sigma import Gargantext.Hooks.Sigmax.Sigma as Sigma
import Gargantext.Sessions (Session) import Gargantext.Sessions (Session)
......
module Gargantext.Components.ListSelection where
import Gargantext.Prelude
import Data.Array as A
import Data.Either (Either)
import Data.Maybe (Maybe(..))
import Gargantext.Components.Forest.Tree.Node.Tools (formChoiceSafe)
import Gargantext.Components.ListSelection.Types (NodeSimple(..), Selection(..), selectedListIds)
import Gargantext.Config.REST (RESTError(..), AffRESTError)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Routes (SessionRoute(..))
import Gargantext.Sessions (Session(..), get)
import Gargantext.Types (ID, NodeType(..), fldr)
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
import Toestand as T
here :: R2.Here
here = R2.here "Gargantext.Components.ListSelection"
type Props =
( selection :: T.Box Selection
, session :: Session
)
selection :: R2.Component Props
selection = R.createElement selectionCpt
selectionCpt :: R.Component Props
selectionCpt = here.component "selection" cpt where
cpt { selection, session } _ = do
pure $ H.div { className: "list-selection" }
[ formChoiceSafe [ MyListsFirst
, OtherListsFirst
, SelectedLists [] ] MyListsFirst setSelection show
, selectedIds { selection, session } []
]
where
setSelection val = T.write_ val selection
selectedIds :: R2.Component Props
selectedIds = R.createElement selectedIdsCpt
selectedIdsCpt :: R.Component Props
selectedIdsCpt = here.component "selectedIds" cpt where
cpt { selection, session } _ = do
selection' <- T.useLive T.unequal selection
pure $ case selection' of
SelectedLists ids -> H.div {} [ idsSelector { selection, session } [] ]
_ -> H.div {} []
type IdsSelectorProps =
( selection :: T.Box Selection
, session :: Session )
idsSelector :: R2.Component IdsSelectorProps
idsSelector = R.createElement idsSelectorCpt
idsSelectorCpt :: R.Component IdsSelectorProps
idsSelectorCpt = here.component "idsSelector" cpt where
cpt { selection, session } _ = do
pure $ H.div { className: "ids-selector" }
[ listTree { name: "", nodeType: NodeUser, root, selection, session } ] -- $ map checkbox [1, 2, 3, 4]
where
Session { treeId: root } = session
listIdsRoute :: ID -> SessionRoute
listIdsRoute = Children NodeList 0 1 Nothing <<< Just
treeFirstLevelRoute :: ID -> SessionRoute
treeFirstLevelRoute id = TreeFirstLevel (Just id) ""
loadTreeChildren :: { root :: ID, session :: Session } -> AffRESTError (Array NodeSimple)
loadTreeChildren { root, session } = do
eResult :: (Either RESTError { children :: Array NodeSimple }) <- get session $ treeFirstLevelRoute root
pure $ (\{ children } -> children) <$> eResult
type ListTreeProps =
( name :: String
, nodeType :: NodeType
, root :: ID
, selection :: T.Box Selection
, session :: Session )
listTree :: R2.Leaf ListTreeProps
listTree props = R.createElement listTreeCpt props []
listTreeCpt :: R.Component ListTreeProps
listTreeCpt = here.component "listTree" cpt where
cpt { name, nodeType, root, selection, session } _ = do
pure $ H.div { className: "tree" }
[ H.div { className: "root" }
[ H.i { className: fldr nodeType true } []
, H.text $ "[" <> show root <> "] " <> name ]
, listTreeChildren { render: listTree
, root
, selection
, session } []
]
type Render = Record ListTreeProps -> R.Element
type ListTreeChildrenProps =
( render :: Render
, root :: ID
, selection :: T.Box Selection
, session :: Session )
listTreeChildren :: R2.Component ListTreeChildrenProps
listTreeChildren = R.createElement listTreeChildrenCpt
listTreeChildrenCpt :: R.Component ListTreeChildrenProps
listTreeChildrenCpt = here.component "listTreeChildren" cpt where
cpt { render, root, selection, session } _ = do
useLoader { errorHandler
, loader: loadTreeChildren
, path: { root, session }
, render: \loaded ->
listTreeChildrenLoaded { loaded
, render
, root
, selection
, session } [] }
where
errorHandler err = case err of
ReadJSONError err' -> here.log2 "[listTreeChildren] ReadJSONError" $ show err'
_ -> here.log2 "[listTreeChildren] RESTError" err
type ListTreeChildrenLoadedProps =
( loaded :: Array NodeSimple
, render :: Render
, root :: ID
, selection :: T.Box Selection
, session :: Session )
listTreeChildrenLoaded :: R2.Component ListTreeChildrenLoadedProps
listTreeChildrenLoaded = R.createElement listTreeChildrenLoadedCpt
listTreeChildrenLoadedCpt :: R.Component ListTreeChildrenLoadedProps
listTreeChildrenLoadedCpt = here.component "listTreeChildrenLoaded" cpt where
cpt { loaded, render, root, selection, session } _ = do
pure $ H.div { className: "children" } (element <$> loaded)
where
element (NodeSimple { id, name, nodeType: nodeType@Folder }) =
render { root: id, name, nodeType, selection, session }
element (NodeSimple { id, name, nodeType: nodeType@FolderPrivate }) =
render { root: id, name, nodeType, selection, session }
element (NodeSimple { id, name, nodeType: nodeType@FolderPublic }) =
render { root: id, name, nodeType, selection, session }
element (NodeSimple { id, name, nodeType: nodeType@FolderShared }) =
render { root: id, name, nodeType, selection, session }
element (NodeSimple { id, name, nodeType: nodeType@Corpus }) =
render { root: id, name, nodeType, selection, session }
element (NodeSimple { id, name, nodeType: NodeList}) =
renderListElement { id, name, selection }
element _ = H.div {} []
type RenderListElementProps =
( id :: ID
, name :: String
, selection :: T.Box Selection )
renderListElement :: R2.Leaf RenderListElementProps
renderListElement props = R.createElement renderListElementCpt props []
renderListElementCpt :: R.Component RenderListElementProps
renderListElementCpt = here.component "renderListElement" cpt where
cpt { id, name, selection } _ = do
selection' <- T.useLive T.unequal selection
let ids = selectedListIds selection'
pure $ H.div { className: "leaf" }
[ H.input { defaultChecked: A.elem id ids
, on: { click: click ids }
, type: "checkbox" }
, H.i { className: fldr NodeList true } []
, H.text $ "[" <> show id <> "] " <> name
]
where
click ids _ = do
let f (SelectedLists lst) =
if A.elem id ids
then SelectedLists (A.delete id lst)
else SelectedLists (A.cons id lst)
f x = x
T.modify_ f selection
module Gargantext.Components.ListSelection.Types where
import Gargantext.Prelude
import Data.Eq.Generic (genericEq)
import Data.Generic.Rep (class Generic)
import Data.Maybe (Maybe(..))
import Data.Newtype (class Newtype)
import Gargantext.Types (ID, ListId, NodeType)
import Simple.JSON as JSON
data Selection = MyListsFirst | OtherListsFirst | SelectedLists (Array ListId)
derive instance Generic Selection _
instance Show Selection where
show MyListsFirst = "My lists first"
show OtherListsFirst = "Other lists first"
show (SelectedLists _) = "Selected lists"
instance Eq Selection where eq = genericEq
instance Read Selection where
read "My lists first" = Just MyListsFirst
read "Other lists first" = Just OtherListsFirst
read "Selected lists" = Just $ SelectedLists []
read _ = Nothing
instance JSON.WriteForeign Selection where
writeImpl MyListsFirst = JSON.writeImpl { "type": "MyListsFirst" }
writeImpl OtherListsFirst = JSON.writeImpl { "type": "OtherListsFirst" }
writeImpl (SelectedLists ids) = JSON.writeImpl { "type": "SelectedLists", value: ids }
selectedListIds :: Selection -> Array ListId
selectedListIds (SelectedLists ids) = ids
selectedListIds _ = []
----------------------
-- TODO Make a separate endpoint on the backend for fetching the whole
-- tree with NodeSimple results?
-- A simplified data structure (we don't want the full-blown (NodePoly
-- a), we care only about Corpus and NodeList node types, with id,
-- name and that's all).
newtype NodeSimple =
NodeSimple { id :: ID
, name :: String
, nodeType :: NodeType }
derive instance Generic NodeSimple _
derive instance Newtype NodeSimple _
derive instance Eq NodeSimple
instance JSON.ReadForeign NodeSimple where
readImpl f = do
{ node } :: { node :: { id :: ID
, name :: String
, type :: NodeType } } <- JSON.read' f
pure $ NodeSimple { id: node.id
, name: node.name
, nodeType: node.type }
...@@ -35,7 +35,7 @@ import Gargantext.Components.Nodes.Lists.Types as NT ...@@ -35,7 +35,7 @@ import Gargantext.Components.Nodes.Lists.Types as NT
import Gargantext.Components.Table as TT import Gargantext.Components.Table as TT
import Gargantext.Components.Table.Types as TT import Gargantext.Components.Table.Types as TT
import Gargantext.Config.REST (RESTError) import Gargantext.Config.REST (RESTError)
import Gargantext.Hooks.Loader (useLoader, useLoaderBox) import Gargantext.Hooks.Loader (useLoaderBox)
import Gargantext.Routes (SessionRoute(..)) as R import Gargantext.Routes (SessionRoute(..)) as R
import Gargantext.Sessions (Session, get) import Gargantext.Sessions (Session, get)
import Gargantext.Types (CTabNgramType, OrderBy(..), SearchQuery, TabType, TermList(..), TermSize, termLists, termSizes) import Gargantext.Types (CTabNgramType, OrderBy(..), SearchQuery, TabType, TermList(..), TermSize, termLists, termSizes)
...@@ -379,14 +379,14 @@ loadedNgramsTableBodyCpt = here.component "loadedNgramsTableBody" cpt where ...@@ -379,14 +379,14 @@ loadedNgramsTableBodyCpt = here.component "loadedNgramsTableBody" cpt where
, performAction: performAction <<< CoreAction } , performAction: performAction <<< CoreAction }
-- autoUpdate :: Array R.Element -- autoUpdate :: Array R.Element
autoUpdate path' = if withAutoUpdate then -- autoUpdate path' = if withAutoUpdate then
[ R2.buff -- [ R2.buff
$ autoUpdateElt -- $ autoUpdateElt
{ duration: 5000 -- { duration: 5000
, effect: performAction $ CoreAction $ Synchronize { afterSync: afterSync' } -- , effect: performAction $ CoreAction $ Synchronize { afterSync: afterSync' }
} -- }
] -- ]
else [] -- else []
ngramsParentRoot :: Maybe NgramsTerm ngramsParentRoot :: Maybe NgramsTerm
ngramsParentRoot = ngramsParentRoot =
...@@ -595,7 +595,7 @@ mainNgramsTableCacheOnCpt = here.component "mainNgramsTableCacheOn" cpt where ...@@ -595,7 +595,7 @@ mainNgramsTableCacheOnCpt = here.component "mainNgramsTableCacheOn" cpt where
handleResponse v = v handleResponse v = v
mainNgramsTableCacheOff :: R2.Component MainNgramsTableProps mainNgramsTableCacheOff :: R2.Component MainNgramsTableProps
mainNgramsTableCacheOff = R.createElement mainNgramsTableCacheOnCpt mainNgramsTableCacheOff = R.createElement mainNgramsTableCacheOffCpt
mainNgramsTableCacheOffCpt :: R.Component MainNgramsTableProps mainNgramsTableCacheOffCpt :: R.Component MainNgramsTableProps
mainNgramsTableCacheOffCpt = here.component "mainNgramsTableCacheOff" cpt where mainNgramsTableCacheOffCpt = here.component "mainNgramsTableCacheOff" cpt where
cpt { afterSync cpt { afterSync
......
...@@ -11,11 +11,10 @@ import Data.Set (Set) ...@@ -11,11 +11,10 @@ import Data.Set (Set)
import Data.Set as Set import Data.Set as Set
import Effect (Effect) import Effect (Effect)
import FFI.Simple (delay) import FFI.Simple (delay)
import Gargantext.Components.Forest.Tree.Node.Action.Search.SearchField (searchQuery)
import Gargantext.Components.NgramsTable.Core (Action(..), Dispatch, NgramsElement, NgramsTable, NgramsTablePatch, NgramsTerm, _NgramsElement, _NgramsRepoElement, _PatchMap, _children, _list, _ngrams, _occurrences, ngramsTermText, replace, setTermListA) import Gargantext.Components.NgramsTable.Core (Action(..), Dispatch, NgramsElement, NgramsTable, NgramsTablePatch, NgramsTerm, _NgramsElement, _NgramsRepoElement, _PatchMap, _children, _list, _ngrams, _occurrences, ngramsTermText, replace, setTermListA)
import Gargantext.Components.Table as Tbl import Gargantext.Components.Table as Tbl
import Gargantext.Prelude (Unit, bind, const, discard, map, not, otherwise, pure, show, unit, ($), (+), (/=), (<<<), (<>), (==), (>), (||)) import Gargantext.Prelude (Unit, bind, const, discard, map, not, otherwise, pure, show, unit, ($), (+), (/=), (<<<), (<>), (==), (>), (||))
import Gargantext.Types as T import Gargantext.Types as GT
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
import React.DOM (a, span, text) import React.DOM (a, span, text)
import React.DOM.Props as DOM import React.DOM.Props as DOM
...@@ -241,8 +240,8 @@ renderNgramsItemCpt = here.component "renderNgramsItem" cpt ...@@ -241,8 +240,8 @@ renderNgramsItemCpt = here.component "renderNgramsItem" cpt
, on: { click: onClick } } [] , on: { click: onClick } } []
] ]
, selected , selected
, checkbox T.MapTerm , checkbox GT.MapTerm
, checkbox T.StopTerm , checkbox GT.StopTerm
, H.div {} ( if ngramsParent == Nothing , H.div {} ( if ngramsParent == Nothing
then [renderNgramsTree { ngramsTable, ngrams, ngramsStyle, ngramsClick, ngramsEdit }] then [renderNgramsTree { ngramsTable, ngrams, ngramsStyle, ngramsClick, ngramsEdit }]
else [H.a { on: { click: const $ dispatch $ ToggleChild true ngrams } } else [H.a { on: { click: const $ dispatch $ ToggleChild true ngrams } }
...@@ -283,7 +282,7 @@ renderNgramsItemCpt = here.component "renderNgramsItem" cpt ...@@ -283,7 +282,7 @@ renderNgramsItemCpt = here.component "renderNgramsItem" cpt
} }
checkbox termList' = checkbox termList' =
let chkd = termList == termList' let chkd = termList == termList'
termList'' = if chkd then T.CandidateTerm else termList' termList'' = if chkd then GT.CandidateTerm else termList'
in in
H.input { checked: chkd H.input { checked: chkd
, className: "checkbox" , className: "checkbox"
...@@ -300,18 +299,18 @@ renderNgramsItemCpt = here.component "renderNgramsItem" cpt ...@@ -300,18 +299,18 @@ renderNgramsItemCpt = here.component "renderNgramsItem" cpt
cycleTermListItem n = setTermListA n (replace termList (nextTermList termList)) cycleTermListItem n = setTermListA n (replace termList (nextTermList termList))
termStyle :: T.TermList -> Number -> DOM.Props termStyle :: GT.TermList -> Number -> DOM.Props
termStyle T.MapTerm opacity = DOM.style { color: "green", opacity } termStyle GT.MapTerm opacity = DOM.style { color: "green", opacity }
termStyle T.StopTerm opacity = DOM.style { color: "red", opacity termStyle GT.StopTerm opacity = DOM.style { color: "red", opacity
, textDecoration: "line-through" } , textDecoration: "line-through" }
termStyle T.CandidateTerm opacity = DOM.style { color: "#767676", opacity } termStyle GT.CandidateTerm opacity = DOM.style { color: "#767676", opacity }
tablePatchHasNgrams :: NgramsTablePatch -> NgramsTerm -> Boolean tablePatchHasNgrams :: NgramsTablePatch -> NgramsTerm -> Boolean
tablePatchHasNgrams ngramsTablePatch ngrams = tablePatchHasNgrams ngramsTablePatch ngrams =
isJust $ ngramsTablePatch.ngramsPatches ^. _PatchMap <<< at ngrams isJust $ ngramsTablePatch.ngramsPatches ^. _PatchMap <<< at ngrams
nextTermList :: T.TermList -> T.TermList nextTermList :: GT.TermList -> GT.TermList
nextTermList T.MapTerm = T.StopTerm nextTermList GT.MapTerm = GT.StopTerm
nextTermList T.StopTerm = T.CandidateTerm nextTermList GT.StopTerm = GT.CandidateTerm
nextTermList T.CandidateTerm = T.MapTerm nextTermList GT.CandidateTerm = GT.MapTerm
...@@ -121,7 +121,7 @@ import Data.TraversableWithIndex (traverseWithIndex) ...@@ -121,7 +121,7 @@ import Data.TraversableWithIndex (traverseWithIndex)
import Data.Tuple (Tuple(..)) import Data.Tuple (Tuple(..))
import Data.Tuple.Nested ((/\)) import Data.Tuple.Nested ((/\))
import Effect (Effect) import Effect (Effect)
import Effect.Aff (Aff, error, launchAff_) import Effect.Aff (Aff, launchAff_)
import Effect.Class (liftEffect) import Effect.Class (liftEffect)
import Effect.Exception.Unsafe (unsafeThrow) import Effect.Exception.Unsafe (unsafeThrow)
import FFI.Simple.Functions (delay) import FFI.Simple.Functions (delay)
......
...@@ -38,4 +38,5 @@ instance JSON.ReadForeign a => JSON.ReadForeign (NodePoly a) where ...@@ -38,4 +38,5 @@ instance JSON.ReadForeign a => JSON.ReadForeign (NodePoly a) where
newtype HyperdataList = HyperdataList { preferences :: Maybe String } newtype HyperdataList = HyperdataList { preferences :: Maybe String }
derive instance Generic HyperdataList _ derive instance Generic HyperdataList _
derive instance Newtype HyperdataList _ derive instance Newtype HyperdataList _
derive instance Eq HyperdataList
derive newtype instance JSON.ReadForeign HyperdataList derive newtype instance JSON.ReadForeign HyperdataList
...@@ -7,7 +7,6 @@ import Data.Generic.Rep (class Generic) ...@@ -7,7 +7,6 @@ import Data.Generic.Rep (class Generic)
import Data.Maybe (Maybe(..)) import Data.Maybe (Maybe(..))
import Data.Show.Generic (genericShow) import Data.Show.Generic (genericShow)
import Data.Tuple.Nested ((/\)) import Data.Tuple.Nested ((/\))
import Gargantext.AsyncTasks as GAT
import Gargantext.Components.App.Data (Boxes) import Gargantext.Components.App.Data (Boxes)
import Gargantext.Components.DocsTable as DT import Gargantext.Components.DocsTable as DT
import Gargantext.Components.DocsTable.Types (Year) import Gargantext.Components.DocsTable.Types (Year)
...@@ -19,9 +18,8 @@ import Gargantext.Components.Nodes.Texts.Types as TTypes ...@@ -19,9 +18,8 @@ import Gargantext.Components.Nodes.Texts.Types as TTypes
import Gargantext.Components.Tab as Tab import Gargantext.Components.Tab as Tab
import Gargantext.Ends (Frontends) import Gargantext.Ends (Frontends)
import Gargantext.Sessions (Session) import Gargantext.Sessions (Session)
import Gargantext.Types (CTabNgramType(..), FrontendError, PTabNgramType(..), SidePanelState, TabSubType(..), TabType(..)) import Gargantext.Types (CTabNgramType(..), PTabNgramType(..), TabSubType(..), TabType(..))
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Toestand as T2
import Reactix as R import Reactix as R
import Toestand as T import Toestand as T
......
...@@ -24,7 +24,7 @@ import Gargantext.Prelude (class Eq, class Show, Unit, bind, discard, pure, show ...@@ -24,7 +24,7 @@ import Gargantext.Prelude (class Eq, class Show, Unit, bind, discard, pure, show
import Gargantext.Routes (SessionRoute(Children, NodeAPI)) import Gargantext.Routes (SessionRoute(Children, NodeAPI))
import Gargantext.Routes as GR import Gargantext.Routes as GR
import Gargantext.Sessions (Session, get, put, sessionId) import Gargantext.Sessions (Session, get, put, sessionId)
import Gargantext.Types (AffETableResult, NodeType(..)) import Gargantext.Types (AffETableResult, NodeType(..), ID)
import Gargantext.Utils.Crypto as Crypto import Gargantext.Utils.Crypto as Crypto
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Toestand as T2 import Gargantext.Utils.Toestand as T2
...@@ -38,7 +38,7 @@ here = R2.here "Gargantext.Components.Nodes.Corpus" ...@@ -38,7 +38,7 @@ here = R2.here "Gargantext.Components.Nodes.Corpus"
type Props = type Props =
( boxes :: Boxes ( boxes :: Boxes
, nodeId :: Int , nodeId :: ID
, session :: Session ) , session :: Session )
corpusLayout :: R2.Leaf Props corpusLayout :: R2.Leaf Props
...@@ -53,7 +53,7 @@ corpusLayoutCpt = here.component "corpusLayout" cpt where ...@@ -53,7 +53,7 @@ corpusLayoutCpt = here.component "corpusLayout" cpt where
type KeyProps = type KeyProps =
( boxes :: Boxes ( boxes :: Boxes
, key :: String , key :: String
, nodeId :: Int , nodeId :: ID
, session :: Session , session :: Session
) )
...@@ -88,11 +88,11 @@ corpusLayoutMainCpt = here.component "corpusLayoutMain" cpt ...@@ -88,11 +88,11 @@ corpusLayoutMainCpt = here.component "corpusLayoutMain" cpt
H.hr {} H.hr {}
, ,
FV.folderView FV.folderView
{ nodeId { backFolder: true
, session , boxes
, backFolder: true , nodeId
, boxes , session
} }
] ]
----------------------------------- -----------------------------------
......
...@@ -15,7 +15,7 @@ import Gargantext.Components.Nodes.Types (FTFieldList(..), FTFieldsWithIndex(..) ...@@ -15,7 +15,7 @@ import Gargantext.Components.Nodes.Types (FTFieldList(..), FTFieldsWithIndex(..)
import Gargantext.Hooks.Loader (useLoader) import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Prelude (Unit, bind, discard, pure, read, show, unit, ($), (<$>), (<>), (==)) import Gargantext.Prelude (Unit, bind, discard, pure, read, show, unit, ($), (<$>), (<>), (==))
import Gargantext.Sessions (Session, sessionId) import Gargantext.Sessions (Session, sessionId)
import Gargantext.Types (FrontendError, NodeID) import Gargantext.Types (NodeID)
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Toestand as T2 import Gargantext.Utils.Toestand as T2
import Reactix as R import Reactix as R
......
module Gargantext.Components.Nodes.Corpus.Document where module Gargantext.Components.Nodes.Corpus.Document where
--import Data.Argonaut (encodeJson) -- DEBUG
--import Data.Argonaut.Core (stringifyWithIndent) -- DEBUG
import Data.Either (Either(..)) import Data.Either (Either(..))
import Data.Maybe (Maybe(..), fromMaybe) import Data.Maybe (Maybe(..), fromMaybe)
import Data.Tuple (fst)
import Data.Tuple.Nested ((/\))
import Effect.Aff (Aff) import Effect.Aff (Aff)
import Reactix as R import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
...@@ -34,10 +30,10 @@ here :: R2.Here ...@@ -34,10 +30,10 @@ here :: R2.Here
here = R2.here "Gargantext.Components.Nodes.Corpus.Document" here = R2.here "Gargantext.Components.Nodes.Corpus.Document"
publicationDate :: Document -> String publicationDate :: Document -> String
publicationDate (Document doc@{publication_year: Nothing}) = "" publicationDate (Document {publication_year: Nothing}) = ""
publicationDate (Document doc@{publication_year: Just py, publication_month: Nothing}) = U.zeroPad 2 py publicationDate (Document {publication_year: Just py, publication_month: Nothing}) = U.zeroPad 2 py
publicationDate (Document doc@{publication_year: Just py, publication_month: Just pm, publication_day: Nothing}) = (U.zeroPad 2 py) <> "-" <> (U.zeroPad 2 pm) publicationDate (Document {publication_year: Just py, publication_month: Just pm, publication_day: Nothing}) = (U.zeroPad 2 py) <> "-" <> (U.zeroPad 2 pm)
publicationDate (Document doc@{publication_year: Just py, publication_month: Just pm, publication_day: Just pd}) = (U.zeroPad 2 py) <> "-" <> (U.zeroPad 2 pm) <> "-" <> (U.zeroPad 2 pd) publicationDate (Document {publication_year: Just py, publication_month: Just pm, publication_day: Just pd}) = (U.zeroPad 2 py) <> "-" <> (U.zeroPad 2 pm) <> "-" <> (U.zeroPad 2 pd)
docViewWrapper :: R2.Component Props docViewWrapper :: R2.Component Props
docViewWrapper = R.createElement docViewWrapperCpt docViewWrapper = R.createElement docViewWrapperCpt
...@@ -60,10 +56,10 @@ docViewCpt :: R.Component DocViewProps ...@@ -60,10 +56,10 @@ docViewCpt :: R.Component DocViewProps
docViewCpt = here.component "docView" cpt docViewCpt = here.component "docView" cpt
where where
cpt { path cpt { path
, loaded: loaded@{ ngramsTable: Versioned { data: initTable }, document } , loaded: { ngramsTable: Versioned { data: initTable }, document }
, state , state
} _children = do } _children = do
state'@{ ngramsLocalPatch, ngramsVersion: version } <- T.useLive T.unequal state state'@{ ngramsLocalPatch } <- T.useLive T.unequal state
let let
afterSync = \_ -> pure unit afterSync = \_ -> pure unit
......
...@@ -183,7 +183,10 @@ tutorialCpt = here.component "tutorial" cpt where ...@@ -183,7 +183,10 @@ tutorialCpt = here.component "tutorial" cpt where
sessionToFolder session@(Session {treeId, username, backend: (Backend {name})}) = sessionToFolder session@(Session {treeId, username, backend: (Backend {name})}) =
H.span { className: "folder" } [ H.span { className: "folder" } [
H.div { className: "d-flex justify-content-center" } [ H.text (username <> "@" <> name) ] H.div { className: "d-flex justify-content-center" } [ H.text (username <> "@" <> name) ]
, H.div {} [ FV.folderView { backFolder: false, boxes, nodeId: treeId, session } ] ] , H.div {} [ FV.folderView { backFolder: false
, boxes
, nodeId: treeId
, session } ] ]
startTutos :: Array Tuto startTutos :: Array Tuto
startTutos = startTutos =
......
...@@ -6,7 +6,6 @@ import Data.Array as A ...@@ -6,7 +6,6 @@ import Data.Array as A
import Data.Maybe (Maybe(..), fromMaybe) import Data.Maybe (Maybe(..), fromMaybe)
import Data.Tuple.Nested ((/\)) import Data.Tuple.Nested ((/\))
import Effect.Class (liftEffect) import Effect.Class (liftEffect)
import Gargantext.AsyncTasks as GAT
import Gargantext.Components.App.Data (Boxes) import Gargantext.Components.App.Data (Boxes)
import Gargantext.Components.NgramsTable as NT import Gargantext.Components.NgramsTable as NT
import Gargantext.Components.NgramsTable.Core as NTC import Gargantext.Components.NgramsTable.Core as NTC
...@@ -18,7 +17,7 @@ import Gargantext.Components.Nodes.Corpus.Types (CorpusData) ...@@ -18,7 +17,7 @@ import Gargantext.Components.Nodes.Corpus.Types (CorpusData)
import Gargantext.Components.Tab as Tab import Gargantext.Components.Tab as Tab
import Gargantext.Prelude (bind, pure, unit, ($), (<>)) import Gargantext.Prelude (bind, pure, unit, ($), (<>))
import Gargantext.Sessions (Session) import Gargantext.Sessions (Session)
import Gargantext.Types (CTabNgramType(..), FrontendError, Mode(..), TabSubType(..), TabType(..), modeTabType) import Gargantext.Types (CTabNgramType(..), Mode(..), TabSubType(..), TabType(..), modeTabType)
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Toestand as T2 import Gargantext.Utils.Toestand as T2
import Reactix as R import Reactix as R
...@@ -121,6 +120,7 @@ ngramsViewCpt = here.component "ngramsView" cpt where ...@@ -121,6 +120,7 @@ ngramsViewCpt = here.component "ngramsView" cpt where
} }
charts params CTabTerms = [ charts params CTabTerms = [
{-
H.div {className: "row"} H.div {className: "row"}
[ H.div {className: "col-12 d-flex justify-content-center"} [ H.div {className: "col-12 d-flex justify-content-center"}
[ H.img { src: "images/Gargantextuel-212x300.jpg" [ H.img { src: "images/Gargantextuel-212x300.jpg"
...@@ -129,7 +129,6 @@ ngramsViewCpt = here.component "ngramsView" cpt where ...@@ -129,7 +129,6 @@ ngramsViewCpt = here.component "ngramsView" cpt where
] ]
] ]
{-
R2.select { className: "form-control" R2.select { className: "form-control"
, defaultValue: show chartType , defaultValue: show chartType
, on: { change: \e -> setChartType , on: { change: \e -> setChartType
......
...@@ -9,9 +9,13 @@ import Data.Maybe (Maybe(..)) ...@@ -9,9 +9,13 @@ import Data.Maybe (Maybe(..))
import Effect (Effect) import Effect (Effect)
import Gargantext.Components.App.Data (Boxes) import Gargantext.Components.App.Data (Boxes)
import Gargantext.Routes (Tile) import Gargantext.Routes (Tile)
import Gargantext.Utils.Reactix as R2
import Reactix as R import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
here :: R2.Here
here = R2.here "Gargantext.Components.Tile"
type Props = type Props =
( boxes :: Boxes ( boxes :: Boxes
, tile :: Record Tile , tile :: Record Tile
...@@ -19,11 +23,10 @@ type Props = ...@@ -19,11 +23,10 @@ type Props =
, closeCallback :: Unit -> Effect Unit , closeCallback :: Unit -> Effect Unit
) )
tileBlock :: Record Props -> Array R.Element -> R.Element tileBlock :: R2.Component Props
tileBlock = R.createElement tileBlockCpt tileBlock = R.createElement tileBlockCpt
tileBlockCpt :: R.Component Props tileBlockCpt :: R.Component Props
tileBlockCpt = R.hooksComponent "tileBlock" cpt where tileBlockCpt = here.component "tileBlock" cpt where
cpt props@{ closeCallback } children = do cpt props@{ closeCallback } children = do
-- Render -- Render
......
...@@ -13,10 +13,14 @@ import Gargantext.Components.App.Data (Boxes) ...@@ -13,10 +13,14 @@ import Gargantext.Components.App.Data (Boxes)
import Gargantext.Hooks.LinkHandler (useLinkHandler) import Gargantext.Hooks.LinkHandler (useLinkHandler)
import Gargantext.Routes (AppRoute, Tile) import Gargantext.Routes (AppRoute, Tile)
import Gargantext.Utils.Popover as Popover import Gargantext.Utils.Popover as Popover
import Gargantext.Utils.Reactix as R2
import Reactix as R import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
import Toestand as T import Toestand as T
here :: R2.Here
here = R2.here "Gargantext.Components.TileMenu"
type Props = type Props =
( boxes :: Boxes ( boxes :: Boxes
, currentTile :: Maybe (Unit -> Effect AppRoute) , currentTile :: Maybe (Unit -> Effect AppRoute)
...@@ -24,11 +28,10 @@ type Props = ...@@ -24,11 +28,10 @@ type Props =
, yTile :: Maybe (Unit -> Effect AppRoute) , yTile :: Maybe (Unit -> Effect AppRoute)
) )
tileMenu :: Record Props -> Array (R.Element) -> R.Element tileMenu :: R2.Component Props
tileMenu = R.createElement tileMenuCpt tileMenu = R.createElement tileMenuCpt
tileMenuCpt :: R.Component Props tileMenuCpt :: R.Component Props
tileMenuCpt = R.hooksComponent "tileMenu" cpt where tileMenuCpt = here.component "tileMenu" cpt where
cpt props@{ boxes } children = do cpt props@{ boxes } children = do
-- Hooks -- Hooks
{ goToRoute } <- useLinkHandler { goToRoute } <- useLinkHandler
......
...@@ -29,7 +29,6 @@ data RESTError = ...@@ -29,7 +29,6 @@ data RESTError =
SendResponseError Affjax.Error SendResponseError Affjax.Error
| ReadJSONError Foreign.MultipleErrors | ReadJSONError Foreign.MultipleErrors
| CustomError String | CustomError String
derive instance Generic RESTError _ derive instance Generic RESTError _
instance Show RESTError where instance Show RESTError where
show (SendResponseError e) = "SendResponseError " <> showError e show (SendResponseError e) = "SendResponseError " <> showError e
...@@ -45,6 +44,8 @@ instance Eq RESTError where ...@@ -45,6 +44,8 @@ instance Eq RESTError where
-- this is crude but we need it only because of useLoader -- this is crude but we need it only because of useLoader
eq _ _ = false eq _ _ = false
type AffRESTError a = Aff (Either RESTError a)
readJSON :: forall a b. JSON.ReadForeign a => readJSON :: forall a b. JSON.ReadForeign a =>
Either Affjax.Error Either Affjax.Error
......
...@@ -112,3 +112,8 @@ nbsp = nbsp' "" ...@@ -112,3 +112,8 @@ nbsp = nbsp' ""
nbsp' acc n nbsp' acc n
| n <= 0 = acc | n <= 0 = acc
| otherwise = nbsp' (acc <> char) (n - 1) | otherwise = nbsp' (acc <> char) (n - 1)
ifElse :: forall a. Boolean -> a -> a -> a
ifElse predicate a b = if predicate then a else b
infixl 1 ifElse as ?
...@@ -44,40 +44,6 @@ li#rename ...@@ -44,40 +44,6 @@ li#rename
position : absolute position : absolute
left : 125px left : 125px
#node-popup-tooltip
background-color: white
border-bottom-left-radius: 6px
border-bottom-right-radius: 6px
border-top-left-radius: 6px
border-top-right-radius: 6px
&:hover
border: none
text-decoration: none
.popup-container
display: flex
flex-direction: colum
& > .card
border: 1px solid rgba(0,0,0,0.2)
box-shadow: 0 2px 5px rgba(0,0,0,0.2)
margin-bottom: 0px
width: 34rem
.fa-pencil
color: black
.card-body
display: flex
justify-content: center
background-color: white
border: none
.spacer
margin: 10px
.frame-search.card
border: 1px solid rgba(0,0,0,0.2)
box-shadow: 0 2px 5px rgba(0,0,0,0.2)
height: 600px
width: 1000px
#create-node-tooltip #create-node-tooltip
position : absolute position : absolute
left : 96px left : 96px
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
$forest-layout-top-teaser-height: 24px $forest-layout-top-teaser-height: 24px
$forest-layout-bottom-teaser-height: 24px // ~line-height to 1.5 (covering tree) $forest-layout-bottom-teaser-height: 24px // ~line-height to 1.5 (covering tree)
$node-popop-radius: 6px
$node-popup-width: 544px
@mixin forest-layout-gutter @mixin forest-layout-gutter
...@@ -129,6 +132,70 @@ li ...@@ -129,6 +132,70 @@ li
.text .text
text-decoration: underline text-decoration: underline
.subtree
$self: &
&__node
margin-top: space-x(0.25)
&__text
display: flex
align-items: center // align icon with text
cursor: pointer
font-size: 15px
&__icons
display: flex
.fa
margin-left: space-x(0.25)
margin-right: space-x(0.25)
&--can-be-selected
text-decoration: underline
text-underline-offset: 2px // easing node reading (empirical)
@include right-handed
&__text
flex-direction: row
text-align: left
&__icons
flex-direction: row
&__children > #{ $self }__node
padding-left: space-x(2)
@include left-handed
&__text
flex-direction: row-reverse
text-align: right
&__icons
flex-direction: row-reverse
&__children > #{ $self }__node
padding-right: space-x(2.5)
.node-text
display: inline-flex
&--selected
font-weight: bold
text-decoration: underline
@include right-handed
flex-direction: row
@include left-handed
flex-direction: row-reverse
// based on https://codeburst.io/how-to-pure-css-pie-charts-w-css-variables-38287aea161e // based on https://codeburst.io/how-to-pure-css-pie-charts-w-css-variables-38287aea161e
.progress-pie .progress-pie
background: rgba(51, 122, 183, 0.1) background: rgba(51, 122, 183, 0.1)
...@@ -180,6 +247,35 @@ li ...@@ -180,6 +247,35 @@ li
// @link https://gitlab.iscpif.fr/gargantext/purescript-gargantext/issues/302 // @link https://gitlab.iscpif.fr/gargantext/purescript-gargantext/issues/302
position: fixed position: fixed
background-color: white
border-radius: $node-popop-radius
&:hover
border: none
text-decoration: none
// @XXX "react-awesome-popover" lack of parent host parameter
//
// as the container where the popover will be appended is actually a
// a heighthy sidebar (which a large is hidden with a scrollbar),
// the library tends to add the tooltip position in the middle of the
// sidebar height: which can be off screen
//
// this workaround appends the tooltip in a static position
@include right-handed
$offset-x: 16.6666666667% // simulate "col-2" sidebar attributes
top: 50%
left: $offset-x
transform: translateY(-50%)
@include left-handed
$offset-x: 16.6666666667% // simulate "col-2" sidebar attributes
top: 50%
right: $offset-x
transform: translateY(-50%)
.tree .tree
.node .node
margin-top: 5px margin-top: 5px
...@@ -187,45 +283,51 @@ li ...@@ -187,45 +283,51 @@ li
.node .node
padding-left: 15px padding-left: 15px
// @XXX "react-awesome-popover" lack of parent host parameter .panel-actions
// .almost-useable
// as the container where the popover will be appended is actually a color: orange
// a heighthy sidebar (which a large is hidden with a scrollbar), .development-in-progress
// the library tends to add the tooltip position in the middle of the color: red
// sidebar height: which can be off screen .ok-to-use
// color: black
// this workaround appends the tooltip in a static position
.right-handed #node-popup-tooltip
$offset-x: 16.6666666667% // simulate "col-2" sidebar attributes .popup-container
top: 50% display: flex
left: $offset-x flex-direction: colum
transform: translateY(-50%)
& > .card
.left-handed #node-popup-tooltip // will enlarge popup when inner content is larger (see issue #315),
$offset-x: 16.6666666667% // simulate "col-2" sidebar attributes // with a minimal width to avoid row item collapsing (see issue #324)
top: 50% width: auto !important
right: $offset-x min-width: $node-popup-width
transform: translateY(-50%)
.panel-actions border: 1px solid rgba(0,0,0,0.2)
.almost-useable box-shadow: 0 2px 5px rgba(0,0,0,0.2)
color: orange margin-bottom: initial
.development-in-progress
color: red .fa-pencil
.ok-to-use color: black
color: black
.card-body
display: flex
.popup-container justify-content: center
background-color: white
// will enlarge popup when inner content is larger (see issue #315) border: none
& > .card .spacer
width: auto !important margin: space-x(1)
.popup-container-body .frame-search.card
// empirical value (see issue #308, #315) border: 1px solid rgba(0,0,0,0.2)
max-height: 70vh box-shadow: 0 2px 5px rgba(0,0,0,0.2)
overflow-y: auto height: 600px
width: 1000px
.popup-container-body
// empirical value (see issue #308, #315)
max-height: 70vh
overflow-y: auto
.forest-layout-wrapper .forest-layout-wrapper
// removing Bootstrap "col" padding // removing Bootstrap "col" padding
...@@ -327,3 +429,13 @@ li ...@@ -327,3 +429,13 @@ li
&:last-child &:last-child
margin-bottom: $forest-layout-bottom-teaser-height margin-bottom: $forest-layout-bottom-teaser-height
/////////////////////////////////////////
.ids-selector
.tree
.children
padding-left: 0.5em
.leaf
input
margin: 0.1em
...@@ -1609,16 +1609,11 @@ bootstrap-dark@^1.0.3: ...@@ -1609,16 +1609,11 @@ bootstrap-dark@^1.0.3:
dependencies: dependencies:
bootstrap ">=4.3" bootstrap ">=4.3"
bootstrap@>=4.3: bootstrap@>=4.3, bootstrap@^5.1.0:
version "5.1.0" version "5.1.0"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.1.0.tgz#543ef8f44f4b9af67b0230f19508542fec38ef55" resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.1.0.tgz#543ef8f44f4b9af67b0230f19508542fec38ef55"
integrity sha512-bs74WNI9BgBo3cEovmdMHikSKoXnDgA6VQjJ7TyTotU6L7d41ZyCEEelPwkYEzsG/Zjv3ie9IE3EMAje0W9Xew== integrity sha512-bs74WNI9BgBo3cEovmdMHikSKoXnDgA6VQjJ7TyTotU6L7d41ZyCEEelPwkYEzsG/Zjv3ie9IE3EMAje0W9Xew==
bootstrap@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.6.0.tgz#97b9f29ac98f98dfa43bf7468262d84392552fd7"
integrity sha512-Io55IuQY3kydzHtbGvQya3H+KorS/M9rSNyfCGCg9WZ4pyT/lCxIlpJgG1GXW/PswzC84Tr2fBYi+7+jFVQQBw==
boxen@1.3.0: boxen@1.3.0:
version "1.3.0" version "1.3.0"
resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment