Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
nomad-lab
encyclopedia-gui
Commits
c98a54f4
Commit
c98a54f4
authored
Dec 30, 2020
by
Iker Hurtado
Browse files
Deep refactoring of the MaterialList component and integration with the new API (unfinished)
parent
f7ff10fe
Pipeline
#90267
skipped with stage
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
client/css/styles.css
View file @
c98a54f4
...
...
@@ -798,14 +798,14 @@ div#specialRows{margin: 30px 40px;}
#matlist
.not-found
{
font-size
:
1.6em
;
color
:
#E56400
;
text-align
:
center
;
padding
:
80px
0
;
}
#matlist
.results-total
{
text-align
:
center
;}
#matlist
.pag-header
{
font-size
:
1.0em
;
padding
:
10px
12px
24px
;
text-align
:
center
;}
span
.prevButton
{
display
:
inline-block
;
cursor
:
pointer
;}
span
.page
{
display
:
inline-block
;
}
span
.nextButton
{
display
:
inline-block
;
cursor
:
pointer
;}
.data-container
table
{
.mat-list-container
table
{
margin
:
auto
;
width
:
96%
;
}
...
...
client/src/search-mod/FilterPanel.view.js
View file @
c98a54f4
...
...
@@ -83,8 +83,8 @@ class FilterPanel {
const
boolValueFields
=
new
CheckboxesField
(
'
Results containing...
'
,
undefined
,
[
{
value
:
'
Band structure
'
,
text
:
'
Band structure
'
,
id
:
'
has_band_structure
'
},
{
value
:
'
DOS
'
,
text
:
'
DOS
'
,
id
:
'
has
-
dos
'
},
{
value
:
'
Thermal properties
'
,
text
:
'
Thermal properties
'
,
id
:
'
has
-
thermal
-
properties
'
},
{
value
:
'
DOS
'
,
text
:
'
DOS
'
,
id
:
'
has
_
dos
'
},
{
value
:
'
Thermal properties
'
,
text
:
'
Thermal properties
'
,
id
:
'
has
_
thermal
_
properties
'
},
]);
this
.
fields
.
push
(
boolValueFields
)
propertiesGroupBox
.
append
(
boolValueFields
.
element
);
...
...
client/src/search-mod/MaterialList.view.js
View file @
c98a54f4
...
...
@@ -27,7 +27,7 @@ let util = require('../common/util.js');
let
InfoSys
=
require
(
'
../common/InfoSys.js
'
);
let
LoadingPopup
=
require
(
'
../common/LoadingPopup.js
'
);
const
RESULTS_PER_PAGE
=
20
;
//
const RESULTS_PER_PAGE = 20;
class
MaterialList
{
...
...
@@ -35,312 +35,195 @@ class MaterialList {
constructor
(){
this
.
element
=
document
.
createElement
(
'
div
'
);
this
.
element
.
setAttribute
(
"
id
"
,
'
matlist
'
);
// map containing an entry per system type (if there are materials for it)
this
.
matMap
=
new
Map
();
this
.
currentSystemType
=
'
bulk
'
;
this
.
esQueryObject
=
null
;
this
.
element
.
innerHTML
=
`
<div id="system-type-tabs" style=" display: inline-block">
<button id="system-tab-bulk" class="selected">BULK</button>
<button id="system-tab-2D" >2D</button>
<button id="system-tab-1D" >1D</button>
<span class="results-total" >Results<span>
</div>
<div class="pag-header">
<span class="prevButton">
<img src="img/prev.svg" style="display: inline;" width="7px"/> prev
</span>
<span class="page"> X </span>
<span class="nextButton"> next
<img src="img/next.svg" width="7px" />
</span>
</div>
<div class="data-container"> </div>`
;
// results data container
this
.
titleBox
=
this
.
element
.
getElementsByClassName
(
"
results-total
"
)[
0
];
this
.
tabsBox
=
this
.
element
.
querySelector
(
"
#system-type-tabs
"
);
// Pagination components
this
.
resultsNrTag
=
this
.
element
.
getElementsByClassName
(
"
pag-header
"
)[
0
];
this
.
prevButton
=
this
.
element
.
getElementsByClassName
(
"
prevButton
"
)[
0
];
this
.
pageElement
=
this
.
element
.
getElementsByClassName
(
"
page
"
)[
0
];
this
.
nextButton
=
this
.
element
.
getElementsByClassName
(
"
nextButton
"
)[
0
];
this
.
resultsContainer
=
this
.
element
.
getElementsByClassName
(
"
data-container
"
)[
0
];
this
.
matMap
=
new
Map
();
//this.currentSystemType = 'bulk';
this
.
optimadeQuery
=
null
;
this
.
_hide
();
this
.
pagControl
=
new
PaginationControl
();
this
.
element
.
append
(
this
.
pagControl
.
element
);
this
.
pagControl
.
setPrevPageListener
(
page
=>
{
this
.
_search
(
page
);
});
this
.
pagControl
.
setNextPageListener
(
page
=>
{
this
.
_search
(
page
);
})
this
.
matListContainer
=
new
MatListContainer
();
this
.
element
.
append
(
this
.
matListContainer
.
element
);
}
attachAndSetEvents
(
element
){
element
.
appendChild
(
this
.
element
);
this
.
_events
();
}
_hide
()
{
this
.
element
.
style
.
display
=
'
none
'
;
}
_show
()
{
this
.
element
.
style
.
display
=
'
block
'
;
this
.
element
.
style
.
display
=
''
;
}
_events
()
{
this
.
tabsBox
.
addEventListener
(
"
click
"
,
(
e
)
=>
{
if
(
e
.
target
!==
e
.
currentTarget
)
{
// When the event source is a child
let
tabId
=
e
.
target
.
id
;
let
index
=
tabId
.
indexOf
(
'
system-tab
'
);
if
(
index
>=
0
){
let
selectingTab
=
tabId
.
substring
(
'
system-tab
'
.
length
+
1
);
this
.
_updateUI
(
selectingTab
);
// Change the styles of the tabs
this
.
element
.
querySelector
(
'
#system-tab-
'
+
this
.
currentSystemType
).
className
=
''
;
this
.
element
.
querySelector
(
'
#system-tab-
'
+
selectingTab
).
className
=
'
selected
'
;
this
.
currentSystemType
=
selectingTab
;
}
}
});
this
.
nextButton
.
addEventListener
(
'
click
'
,
e
=>
{
let
systemData
=
this
.
matMap
.
get
(
this
.
currentSystemType
);
if
(
systemData
.
page
===
systemData
.
totalPages
)
return
;
systemData
.
page
++
;
this
.
_paginationSearch
();
});
this
.
prevButton
.
addEventListener
(
'
click
'
,
e
=>
{
let
systemData
=
this
.
matMap
.
get
(
this
.
currentSystemType
);
if
(
systemData
.
page
===
1
)
return
;
systemData
.
page
--
;
this
.
_paginationSearch
();
});
this
.
resultsContainer
.
addEventListener
(
'
click
'
,
(
e
)
=>
{
if
(
e
.
target
!==
e
.
currentTarget
)
{
// When the event source is a child
let
element
;
if
(
e
.
target
.
className
===
'
mat-row
'
)
element
=
e
.
target
;
else
if
(
e
.
target
.
parentElement
.
className
===
'
mat-row
'
)
element
=
e
.
target
.
parentElement
;
else
if
(
e
.
target
.
parentElement
.
parentElement
.
className
===
'
mat-row
'
)
element
=
e
.
target
.
parentElement
.
parentElement
;
if
(
element
)
{
util
.
setBrowserHashPath
(
'
material
'
,
element
.
getAttribute
(
'
data-mat-id
'
));
}
e
.
stopPropagation
();
}
});
invalidateSearch
(){
this
.
_hide
();
}
_paginationSearch
(){
let
systemTypePosition
=
this
.
esQueryObject
.
bool
.
must
.
length
-
1
;
this
.
esQueryObject
.
bool
.
must
[
systemTypePosition
].
match
.
system_type
=
this
.
currentSystemType
;
let
page
=
this
.
matMap
.
get
(
this
.
currentSystemType
).
page
;
let
req
=
util
.
serverReqPOST
(
util
.
getSearchURL
()
+
'
?page=
'
+
page
+
'
&per_page=
'
+
RESULTS_PER_PAGE
,
JSON
.
stringify
(
this
.
esQueryObject
),
e
=>
{
let
data
=
JSON
.
parse
(
e
.
target
.
response
);
this
.
matMap
.
set
(
this
.
currentSystemType
,
this
.
_createSystemTypeData
(
data
,
page
,
true
));
//console.log('this.matMap: ', this.matMap);
this
.
_updateUI
(
this
.
currentSystemType
);
});
initSearch
(
optimadeQuery
){
this
.
optimadeQuery
=
optimadeQuery
;
this
.
_search
();
}
initSearchTest
(
rootQueryObj
){
_search
(
page
){
//this.resultsContainer.style.visibility = 'hidden';
this
.
matMap
.
clear
();
let
qqq
=
{
'
bool
'
:
{}
};
//qqq.bool.must = {"terms":{"crystal_system":{"operator":"or","query":"cubic"}}};
qqq
.
bool
.
must
=
{
"
terms
"
:{
"
crystal_system
"
:
[
"
hexagonal
"
,
"
cubic
"
]}};
console
.
log
(
'
SENDING:
'
,
JSON
.
stringify
(
qqq
));
console
.
log
(
'
:
'
,
qqq
.
bool
.
must
);
let
bulkReq
=
util
.
serverReqPOST
(
util
.
getSearchURL
()
+
'
?page=1
'
+
'
&per_page=
'
+
RESULTS_PER_PAGE
,
JSON
.
stringify
(
qqq
),
bulke
=>
{
let
bulkData
=
JSON
.
parse
(
bulke
.
target
.
response
);
console
.
log
(
'
GETTING:
'
,
bulkData
);
this
.
matMap
.
set
(
'
bulk
'
,
this
.
_createSystemTypeData
(
bulkData
,
1
,
bulke
.
target
.
status
===
200
));
LoadingPopup
.
hide
();
});
}
initSearch
(
rootQueryObj
){
//this.resultsContainer.style.visibility = 'hidden';
this
.
matMap
.
clear
();
LoadingPopup
.
show
();
// rootQueryObj.bool.must.push( { "match": {"system_type" : "bulk"} } );
//console.log('SENDING: ', JSON.stringify(rootQueryObj)); console.log(': ', rootQueryObj.bool.must);
//let systemTypePosition = rootQueryObj.bool.must.length-1;
//this.esQueryObject = rootQueryObj;
let
reqJson
=
{
query
:
this
.
optimadeQuery
};
if
(
page
)
reqJson
.
search_by
=
{
page
:
page
}
LoadingPopup
.
show
(
);
console
.
log
(
'
SEARCHING:
'
,
reqJson
);
//rootQueryObj = 'elements HAS ALL "Si", "Cl"';
console
.
log
(
'
SENDING:
'
,
rootQueryObj
);
let
bulkReq
=
util
.
serverReqPOST
(
util
.
getSearchURL
(),
JSON
.
stringify
({
query
:
rootQueryObj
})
,
bulke
=>
{
let
bulkData
=
JSON
.
parse
(
bulke
.
target
.
response
);
console
.
log
(
'
GETTING:
'
,
bulkData
);
fetch
(
util
.
getSearchURL
(),
{
method
:
'
POST
'
,
headers
:
{
'
Content-Type
'
:
'
application/json;charset=utf-8
'
},
body
:
JSON
.
stringify
(
reqJson
)
})
.
then
(
resp
=>
resp
.
json
()
)
.
then
(
result
=>
{
console
.
log
(
'
GETTING:
'
,
result
);
this
.
matMap
.
set
(
'
bulk
'
,
this
.
_createSystemTypeData
(
bulkData
,
1
,
bulke
.
target
.
status
===
200
));
// Update
this
.
_setMatList
(
result
.
results
);
this
.
pagControl
.
set
(
result
.
pages
);
this
.
_updateUI
(
this
.
currentSystemType
);
this
.
_show
();
LoadingPopup
.
hide
();
this
.
_launchMaterialViewerIfOnlyOne
();
});
if
(
result
.
results
.
length
===
0
){
this
.
_hide
();
}
else
{
if
(
result
.
results
.
length
===
1
){
const
onlyMat
=
this
.
matMap
.
values
().
next
().
value
[
0
];
util
.
setBrowserHashPath
(
'
material
'
,
onlyMat
.
material_id
);
}
//else{
this
.
matListContainer
.
updateList
(
this
.
matMap
);
this
.
_show
();
//}
}
LoadingPopup
.
hide
();
})
/*
//let oReq = util.serverReqPOST('http://enc-staging-nomad.esc.rzg.mpg.de/current/v1.0/esmaterials', postQuery, e => {
// Bulk materials request
let bulkReq = util.serverReqPOST(util.getSearchURL()+'?page=1'+
'&per_page='+RESULTS_PER_PAGE, JSON.stringify(rootQueryObj), bulke => {
let bulkData = JSON.parse(bulke.target.response); console.log('GETTING: ', bulkData);
this.matMap.set('bulk', this._createSystemTypeData(bulkData, 1, bulke.target.status === 200));
// 2D materials request
rootQueryObj.bool.must[systemTypePosition].match.system_type = '2D';
let twoDReq = util.serverReqPOST(util.getSearchURL()+'?page=1'+
'&per_page='+RESULTS_PER_PAGE, JSON.stringify(rootQueryObj), twoDe => {
oReq.addEventListener("error", e => { // Not valid query
console.log('Search ERROR - Not valid query ');
this.total_results= 0;
this.setData([]);
this._updateUI();
this.resultsContainer.style.visibility = 'visible';
LoadingPopup.hide();
});
*/
}
let twoDData = JSON.parse(twoDe.target.response);
this.matMap.set('2D', this._createSystemTypeData(twoDData, 1, twoDe.target.status === 200));
_setMatList
(
matList
){
if
(
matList
.
length
>
0
){
matList
.
forEach
(
mat
=>
{
// 1D materials request
rootQueryObj.bool.must[systemTypePosition].match.system_type = '1D';
let oneDReq = util.serverReqPOST(util.getSearchURL()+'?page=1'+
'&per_page='+RESULTS_PER_PAGE, JSON.stringify(rootQueryObj), oneDe => {
if
(
this
.
matMap
.
has
(
mat
.
formula_reduced
)){
let
matArray
=
this
.
matMap
.
get
(
mat
.
formula_reduced
);
matArray
.
push
(
mat
);
}
else
this
.
matMap
.
set
(
mat
.
formula_reduced
,
[
mat
]);
});
let oneDData = JSON.parse(oneDe.target.response);
}
else
this
.
matMap
.
clear
();
// Right query - results not found
}
this.matMap.set('1D', this._createSystemTypeData(oneDData, 1, oneDe.target.status === 200));
}
let selectedSystemType = null;
this.matMap.forEach( (materials, systemType) => {
this.element.querySelector('#system-tab-'+systemType).disabled =
(materials.total === 0);
if (selectedSystemType === null && materials.total > 0) {
selectedSystemType = systemType;
this.element.querySelector('#system-tab-'+this.currentSystemType).className = '';
this.element.querySelector('#system-tab-'+selectedSystemType).className = 'selected';
this.currentSystemType = selectedSystemType;
}
});
rootQueryObj.bool.must[systemTypePosition].match.system_type = this.currentSystemType;
this._updateUI(this.currentSystemType);
//this.resultsContainer.style.visibility = 'visible';
this._show();
LoadingPopup.hide();
this._launchMaterialViewerIfOnlyOne();
});
class
PaginationControl
{
});
constructor
(){
this
.
element
=
document
.
createElement
(
'
div
'
);
//this.element.className = 'pag-header';
this
.
element
.
innerHTML
=
`
<div class="results-total" >Results</div>
<div class="pag-header" >
<span class="prevButton">
<img src="img/prev.svg" style="display: inline;" width="7px"/> prev
</span>
<span class="page"> X </span>
<span class="nextButton"> next
<img src="img/next.svg" width="7px" />
</span>
</div>
`
;
this
.
titleBox
=
this
.
element
.
querySelector
(
'
.results-total
'
);
this
.
prevButton
=
this
.
element
.
querySelector
(
'
.prevButton
'
);
this
.
pageElement
=
this
.
element
.
querySelector
(
'
.page
'
);
this
.
nextButton
=
this
.
element
.
querySelector
(
'
.nextButton
'
);
this
.
prevButton
.
addEventListener
(
'
click
'
,
e
=>
{
if
(
this
.
pagesData
.
page
===
1
)
return
;
this
.
prevPageListener
(
this
.
pagesData
.
page
-
1
);
});
*/
/*
oReq.addEventListener("error", e => { // Not valid query
console.log('Search ERROR - Not valid query ');
this.total_results= 0;
this.setData([]);
this._updateUI();
this.resultsContainer.style.visibility = 'visible';
LoadingPopup.hide();
this
.
nextButton
.
addEventListener
(
'
click
'
,
e
=>
{
console
.
log
(
'
nextButton
'
)
if
(
this
.
pagesData
.
page
===
this
.
pagesData
.
pages
)
return
;
this
.
nextPageListener
(
this
.
pagesData
.
page
+
1
);
});
*/
this
.
pagesData
;
}
_launchMaterialViewerIfOnlyOne
(){
let
mat
;
let
sum
=
0
;
this
.
matMap
.
forEach
(
(
materials
,
systemType
)
=>
{
sum
+=
materials
.
total
;
if
(
materials
.
total
===
1
)
mat
=
materials
.
materials
.
values
().
next
().
value
[
0
];
});
if
(
sum
===
1
)
util
.
setBrowserHashPath
(
'
material
'
,
+
(
mat
.
id
));
set
(
pagesData
){
this
.
pagesData
=
pagesData
;
this
.
titleBox
.
innerHTML
=
'
Results (total:
'
+
pagesData
.
total
+
'
)
'
;
this
.
pageElement
.
innerHTML
=
'
page
'
+
pagesData
.
page
+
'
/
'
+
pagesData
.
pages
;
}
_createSystemTypeData
(
data
,
page
,
status
){
if
(
status
){
let
systemTypeMatMap
=
new
Map
();
data
.
results
.
forEach
(
mat
=>
{
if
(
systemTypeMatMap
.
has
(
mat
.
formula_reduced
)){
let
matArray
=
systemTypeMatMap
.
get
(
mat
.
formula_reduced
);
matArray
.
push
(
mat
);
}
else
{
let
newArray
=
[];
newArray
.
push
(
mat
);
systemTypeMatMap
.
set
(
mat
.
formula_reduced
,
newArray
);
}
});
return
{
'
materials
'
:
systemTypeMatMap
,
'
page
'
:
page
,
'
total
'
:
data
.
total_results
,
'
totalPages
'
:
Math
.
ceil
(
data
.
total_results
/
RESULTS_PER_PAGE
)
};
}
else
return
null
;
// Right query - results not found
//this.total_results = 0;
setPrevPageListener
(
listener
){
this
.
prevPageListener
=
listener
;
}
_updateUI
(
systemType
){
let
systemData
=
this
.
matMap
.
get
(
systemType
);
//console.log('_updateUI',systemType, systemData);
this
.
titleBox
.
innerHTML
=
'
Results (total:
'
+
systemData
.
total
+
'
)
'
;
this
.
pageElement
.
innerHTML
=
'
page
'
+
systemData
.
page
+
'
/
'
+
systemData
.
totalPages
;
let
html
=
''
;
setNextPageListener
(
listener
){
this
.
nextPageListener
=
listener
;
}
}
if
(
systemData
===
null
)
{
this
.
resultsNrTag
.
style
.
display
=
'
none
'
;
this
.
titleBox
.
style
.
display
=
'
none
'
;
//if (this.page === 1)
//html+= `<div class="not-found"> No results found </div>`;
// If there is search without results IF PAGE == 0 THERE ISN'T SEARCH
}
else
{
this
.
resultsNrTag
.
style
.
display
=
'
block
'
;
this
.
titleBox
.
style
.
display
=
'
inline
'
;
class
MatListContainer
{
html
+=
`
<table>
constructor
(){
this
.
element
=
document
.
createElement
(
'
div
'
);
this
.
element
.
className
=
'
mat-list-container
'
;
this
.
element
.
innerHTML
=
`
<table>
<thead> <tr>
<th style="width: 24%;"></th>
<th style="width: 16%;">
...
...
@@ -355,22 +238,44 @@ class MaterialList {
</th>
<th style="width: 18%;">Nº calculations</th>
</tr> </thead>
<tbody>
`
;
systemData
.
materials
.
forEach
((
mats
,
formula
)
=>
{
<tbody> </tbody>
</table>
`
;
this
.
tbody
=
this
.
element
.
querySelector
(
'
tbody
'
);
this
.
tbody
.
addEventListener
(
'
click
'
,
e
=>
{
let
rFormula
=
util
.
getSubscriptedFormula
(
formula
);
html
+=
'
<tr> <td class="formula" colspan="5"><b>
'
+
rFormula
+
'
</b>
'
;
if
(
mats
.
length
>
1
)
let
materialRow
=
event
.
target
.
closest
(
'
tr.mat-row
'
);
if
(
materialRow
)
util
.
setBrowserHashPath
(
'
material
'
,
materialRow
.
getAttribute
(
'
data-mat-id
'
));
e
.
stopPropagation
();
});
}
updateList
(
matMap
){
//console.log('matMap', matMap);
if
(
matMap
.
size
===
0
){
this
.
tbody
.
innerHTML
=
''
;
return
}
let
html
=
''
matMap
.
forEach
(
(
mats
,
formula
)
=>
{
let
rFormula
=
util
.
getSubscriptedFormula
(
formula
);
html
+=
'
<tr> <td class="formula" colspan="5"><b>
'
+
rFormula
+
'
</b>
'
;
if
(
mats
.
length
>
1
)
html
+=
'
<span style="font-size: 0.86em;"> (
'
+
mats
.
length
+
'
structures)</span>
'
;
html
+=
'
</td></tr>
'
;
html
+=
'
</td></tr>
'
;
mats
.
forEach
(
mat
=>
{
let
label
=
(
mat
.
material_name
!==
null
?
mat
.
material_name
:
rFormula
);
//console.log("MATERIAL ",mat
, mat.system_type
);
html
+=
`<tr class="mat-row" data-mat-id="
${
mat
.
id
}
">
mats
.
forEach
(
mat
=>
{
let
label
=
(
mat
.
material_name
?
mat
.
material_name
:
rFormula
);
//console.log("MATERIAL ",
mat
.formula, mat.material_name, rFormula, label
);
html
+=
`<tr class="mat-row" data-mat-id="
${
mat
.
material_
id
}
">
<td >
${
label
}
[
${
mat
.
formula
}
] </td>
<td style="text-align:center" >
${
mat
.
space_group_number
===
null
?
''
:
mat
.
space_group_number
}
...
...
@@ -383,17 +288,16 @@ class MaterialList {
<td>
${
mat
.
structure_type
===
null
?
''
:
mat
.
structure_type
}
</td>
<td style="text-align:center" >
${
mat
.
nr_of_calculations
}
</td>
</tr>`
;
});
});
});
html
+=
` </tbody> </table>`
;
}
this
.
resultsContainer
.
innerHTML
=
html
;
this
.
tbody
.
innerHTML
=
html
;
InfoSys
.
addToInfoSystem
(
this
.
resultsContainer
);
InfoSys
.
addToInfoSystem
(
this
.
element
);
}
}
module
.
exports
=
MaterialList
;
client/src/search-mod/NewSearchMod.js
View file @
c98a54f4
...
...
@@ -344,11 +344,12 @@ class NewSearchMod {
let
optimadeQueryForProps
=
getOptimadeQueryFromProps
(
this
.
filterPanel
.
getValues
());
if
(
optimadeQuery
!==
''
){
// if there are items in the serach box
optimadeQuery
+=
(
optimadeQueryForProps
.
length
>
0
?
'
AND
'
+
optimadeQueryForProps
:
''
);
console
.
log
(
'
sendQuery optimadeQuery:
'
,
optimadeQuery
,
optimadeQueryForProps
);
console
.
log
(
'
sendQuery optimadeQuery:
'
,
optimadeQuery
);
this
.
materialList
.
initSearch
(
optimadeQuery
);
}
}
else
this
.
materialList
.
invalidateSearch
();
function
getOptimadeQueryFromProps
(
propsValuesMap
){
let
query
=
''
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment