From aa9bb74fc60d8ac6f1851d735cf9ec23d96f26ed Mon Sep 17 00:00:00 2001 From: "Hurtado, Iker (ikerh)" <iker.hurtado@bsc.es> Date: Sat, 27 Oct 2018 20:45:25 +0200 Subject: [PATCH] Properties search filter integration --- client/bundle.js | 114 +++++++++------------ client/css/styles.css | 4 +- client/src/search-mod/MaterialList.view.js | 48 +++++---- client/src/search-mod/NewSearchMod.js | 66 ++++-------- 4 files changed, 99 insertions(+), 133 deletions(-) diff --git a/client/bundle.js b/client/bundle.js index dcd3298f..a908f867 100644 --- a/client/bundle.js +++ b/client/bundle.js @@ -7796,11 +7796,7 @@ this.materialNameBox.disable(true); } }); - /* - this.propertiesBox= new PropertiesBox(); - this.propertiesBox.setAddPropertiesListener(propsMap => { - this.addPropertiesInSearchQuery(propsMap); - });*/ + this.filterPanel = new FilterPanel(); this.filterSidePanel.appendChild(this.filterPanel.element); @@ -7826,7 +7822,7 @@ if (this.searchQuery.lenght === 0){ util.showUserMsg('No query'); }else{ - let rootQueryObj; + let searchExpressionQuery; //************** Material name or complex search expression //if (this.queryTypes[i] === 'MN'){ @@ -7834,18 +7830,15 @@ if (this.element.querySelector('#allow-other-elements').checked) - rootQueryObj = this._getESQueryFromSearchQuery_otherElements( + searchExpressionQuery = this._getESQueryFromSearchQuery_otherElements( this.searchQuery, this.queryTypes); // Regular case: search containing only the elements in the search expression - else rootQueryObj = + else searchExpressionQuery = this._getESQueryFromSearchQuery(this.searchQuery, this.queryTypes); - - /* Pending to ADD *************/ - //let filterMap = this.filterPanel.getValues(); - //this._addFiltersInSearchQuery(filterMap, queryObj); - - this.materialList.initSearch(rootQueryObj); + this.materialList.initSearch( + this._addFiltersInSearchQuery( this.filterPanel.getValues(), + searchExpressionQuery)); //util.setBrowserHashPath('search','results'); this.element.querySelector('.add-box').style.display = 'none'; @@ -7877,7 +7870,7 @@ if (selectingTab === 'element') selectingElement = this.elementTable.element; else if (selectingTab === 'name') - selectingElement = this.materialNameBox.element;//this.propertiesBox.element; + selectingElement = this.materialNameBox.element; else if (selectingTab === 'formula') selectingElement = this.formulaBox.element; @@ -8081,30 +8074,37 @@ - _addFiltersInSearchQuery(filterMap, queryFilterArray){ - //let filters = []; + _addFiltersInSearchQuery(filterMap, searchExpressionQuery){ + let rootQueryObj = { 'bool' : {} }; + rootQueryObj.bool.must = []; + rootQueryObj.bool.must.push( searchExpressionQuery ); + + filterMap.forEach((values/*Array*/, filterName) => { let filterNameDef = replaceDashes(filterName); if (filterName === 'mass-density' || filterName === 'band-gap'){ //***** util.eV2J() apply? - queryFilterArray.push( this._getFieldESRange(filterNameDef, values) ); + rootQueryObj.bool.must.push( this._getFieldESRange(filterNameDef, values) ); }else if (filterName === 'band-gap-type'){ // special case if ( values !== 'both') - queryFilterArray.push( this._getESSimpleMatch('band_gap_direct', + rootQueryObj.bool.must.push( this._getESSimpleMatch('band_gap_direct', ( values === 'direct' ? true : false ) ) ); }else if (filterName.startsWith('has')){ // has- filters - queryFilterArray.push( this._getESSimpleMatch(filterNameDef, values, false) ); + rootQueryObj.bool.must.push( this._getESSimpleMatch(filterNameDef, values, false) ); }else{ // normal case - queryFilterArray.push( this._getESOperatorMatch(filterNameDef, values, false) ); + rootQueryObj.bool.must.push( this._getESOperatorMatch(filterNameDef, values, false) ); + console.log(this._getESOperatorMatch(filterNameDef, values, false) ); } }); - //return filters; + + + return rootQueryObj; } @@ -8201,28 +8201,6 @@ //this._showSearchBox(); } - /* - addPropertiesInSearchQuery(propsMap){ - propsMap.forEach((values, propName) => { - let i = this.queryTypes.indexOf(propName); - if (i < 0) - this.addTagInSearchQuery(values.join(' | '), propName); - else{ - let currentValues = this.searchQuery[i].split(' | '); - //console.log('Current VAlues: ',currentValues); - values.forEach(value => { - if (currentValues.indexOf(value) < 0) currentValues.push(value); - }); - this.searchQuery[i] = currentValues.join(' | '); - this.updateSearchQuery(); - //this._showSearchBox(); - } - }); - }*/ - - - - removeElementORFormulaInSearchQuery(item){ //console.log(" removeElementORFormulaInSearchQuery item: ",item, this.searchQuery.indexOf(item)); @@ -9285,7 +9263,6 @@ let systemData = this.matMap.get(this.currentSystemType); if (systemData.page === systemData.totalPages) return; systemData.page++; - console.log('nextButton page:', systemData.page); this._paginationSearch(); }); @@ -9293,7 +9270,6 @@ let systemData = this.matMap.get(this.currentSystemType); if (systemData.page === 1) return; systemData.page--; - console.log('nextButton page:', systemData.page); this._paginationSearch(); }); @@ -9325,7 +9301,7 @@ 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); console.log('GETTING: ', data); + let data = JSON.parse(e.target.response); this.matMap.set(this.currentSystemType, this._createSystemTypeData(data, page, true)); //console.log('this.matMap: ', this.matMap); @@ -9335,17 +9311,21 @@ } - initSearch(searchJson){ + initSearch(rootQueryObj){ //this.resultsContainer.style.visibility = 'hidden'; this.matMap.clear(); - + this.currentSystemType = 'bulk'; + /* let rootQueryObj = { 'bool' : {} }; rootQueryObj.bool.must = []; rootQueryObj.bool.must.push( searchJson ); rootQueryObj.bool.must.push( { "match": {"system_type" : "bulk"} } ); + */ + rootQueryObj.bool.must.push( { "match": {"system_type" : "bulk"} } ); + let systemTypePosition = rootQueryObj.bool.must.length-1; this.esQueryObject = rootQueryObj; - console.log('SENDING: ', JSON.stringify(rootQueryObj)); + console.log('SENDING: ', JSON.stringify(rootQueryObj)); console.log(': ', rootQueryObj.bool.must); LoadingPopup.show(); @@ -9358,33 +9338,33 @@ let bulkData = JSON.parse(bulke.target.response); console.log('GETTING: ', bulkData); this.matMap.set('bulk', this._createSystemTypeData(bulkData, 1, bulke.target.status === 200)); - console.log('this.matMap: ', this.matMap); // 2D materials request - rootQueryObj.bool.must[1].match.system_type = '2D'; - console.log('SENDING: ', JSON.stringify(rootQueryObj)); + 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 => { let twoDData = JSON.parse(twoDe.target.response); this.matMap.set('2D', this._createSystemTypeData(twoDData, 1, twoDe.target.status === 200)); - console.log('this.matMap: ', this.matMap); // 1D materials request - rootQueryObj.bool.must[1].match.system_type = '1D'; - console.log('SENDING: ', JSON.stringify(rootQueryObj)); + 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 => { let oneDData = JSON.parse(oneDe.target.response); this.matMap.set('1D', this._createSystemTypeData(oneDData, 1, oneDe.target.status === 200)); - console.log('this.matMap: ', this.matMap); - this._updateUI('bulk'); + this._updateUI(this.currentSystemType); + this.matMap.forEach( (materials, systemType) => { + this.element.querySelector('#system-tab-'+systemType).disabled = + (materials.total === 0); + }); + //this.resultsContainer.style.visibility = 'visible'; LoadingPopup.hide(); this._launchMaterialViewerIfOnlyOne(); @@ -9449,8 +9429,7 @@ _updateUI(systemType){ let systemData = this.matMap.get(systemType); - console.log('_updateUI',systemType, systemData); - + //console.log('_updateUI',systemType, systemData); this.titleBox.innerHTML= 'Results (total: '+systemData.total+')'; this.pageElement.innerHTML= 'page '+systemData.page+' / '+systemData.totalPages; @@ -9472,12 +9451,13 @@ <table> <thead> <tr> <th style="width: 24%;"></th> - <th style="width: 20%;"> - <span info-sys-data="system-type">System type</span> - </th> <th style="width: 16%;"> <span info-sys-data="space-group">Space group</span> </th> + <th style="width: 20%;"> + <span >Space gr. int. symbol</span> + </th> + <th style="width: 22%;"> <span info-sys-data="structure-type">Structure type</span> </th> @@ -9500,12 +9480,14 @@ html+= `<tr class="mat-row" data-mat-id="${mat.id}"> <td > ${label} [${mat.formula}] </td> - <td style="text-align:center" > - <!--<span info-sys-data="system-type">-->${mat.system_type} <!--</span>--> - </td> <td style="text-align:center" > ${mat.space_group_number === null ? '' : mat.space_group_number} </td> + <td> + ${mat.space_group_international_short_symbol === null ? '' : + mat.space_group_international_short_symbol} + </td> + <td> ${mat.structure_type === null ? '' : mat.structure_type } </td> <td style="text-align:center" > ${mat.nr_of_calculations} </td> </tr>`; diff --git a/client/css/styles.css b/client/css/styles.css index ef01996f..1e551bc6 100644 --- a/client/css/styles.css +++ b/client/css/styles.css @@ -635,9 +635,11 @@ div#specialRows{margin: 30px 40px;} #matlist{ width: 742px; margin: 40px auto 40px;} -#system-type-tabs{width: 100%; } +#system-type-tabs{ width: 100%; } #system-type-tabs button{ font-size: 1.2em; } #system-type-tabs button.selected { color: #E56400;} +#system-type-tabs button:disabled { color: #BBB; cursor: default} + span.results-total { float: right;} /* #paginationWg erased*/ diff --git a/client/src/search-mod/MaterialList.view.js b/client/src/search-mod/MaterialList.view.js index 22145c60..3c8eb209 100644 --- a/client/src/search-mod/MaterialList.view.js +++ b/client/src/search-mod/MaterialList.view.js @@ -103,7 +103,6 @@ class MaterialList { let systemData = this.matMap.get(this.currentSystemType); if (systemData.page === systemData.totalPages) return; systemData.page++; - console.log('nextButton page:', systemData.page); this._paginationSearch(); }); @@ -111,7 +110,6 @@ class MaterialList { let systemData = this.matMap.get(this.currentSystemType); if (systemData.page === 1) return; systemData.page--; - console.log('nextButton page:', systemData.page); this._paginationSearch(); }); @@ -143,7 +141,7 @@ class MaterialList { 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); console.log('GETTING: ', data); + let data = JSON.parse(e.target.response); this.matMap.set(this.currentSystemType, this._createSystemTypeData(data, page, true)); //console.log('this.matMap: ', this.matMap); @@ -153,17 +151,21 @@ class MaterialList { } - initSearch(searchJson){ + initSearch(rootQueryObj){ //this.resultsContainer.style.visibility = 'hidden'; this.matMap.clear(); - + this.currentSystemType = 'bulk'; +/* let rootQueryObj = { 'bool' : {} }; rootQueryObj.bool.must = []; rootQueryObj.bool.must.push( searchJson ); rootQueryObj.bool.must.push( { "match": {"system_type" : "bulk"} } ); + */ + rootQueryObj.bool.must.push( { "match": {"system_type" : "bulk"} } ); + let systemTypePosition = rootQueryObj.bool.must.length-1; this.esQueryObject = rootQueryObj; - console.log('SENDING: ', JSON.stringify(rootQueryObj)); + console.log('SENDING: ', JSON.stringify(rootQueryObj)); console.log(': ', rootQueryObj.bool.must); LoadingPopup.show(); @@ -176,33 +178,33 @@ class MaterialList { let bulkData = JSON.parse(bulke.target.response); console.log('GETTING: ', bulkData); this.matMap.set('bulk', this._createSystemTypeData(bulkData, 1, bulke.target.status === 200)); - console.log('this.matMap: ', this.matMap); // 2D materials request - rootQueryObj.bool.must[1].match.system_type = '2D'; - console.log('SENDING: ', JSON.stringify(rootQueryObj)); + 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 => { let twoDData = JSON.parse(twoDe.target.response); this.matMap.set('2D', this._createSystemTypeData(twoDData, 1, twoDe.target.status === 200)); - console.log('this.matMap: ', this.matMap); // 1D materials request - rootQueryObj.bool.must[1].match.system_type = '1D'; - console.log('SENDING: ', JSON.stringify(rootQueryObj)); + 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 => { let oneDData = JSON.parse(oneDe.target.response); this.matMap.set('1D', this._createSystemTypeData(oneDData, 1, oneDe.target.status === 200)); - console.log('this.matMap: ', this.matMap); - this._updateUI('bulk'); + this._updateUI(this.currentSystemType); + this.matMap.forEach( (materials, systemType) => { + this.element.querySelector('#system-tab-'+systemType).disabled = + (materials.total === 0); + }); + //this.resultsContainer.style.visibility = 'visible'; LoadingPopup.hide(); this._launchMaterialViewerIfOnlyOne(); @@ -267,8 +269,7 @@ class MaterialList { _updateUI(systemType){ let systemData = this.matMap.get(systemType); - console.log('_updateUI',systemType, systemData); - + //console.log('_updateUI',systemType, systemData); this.titleBox.innerHTML= 'Results (total: '+systemData.total+')'; this.pageElement.innerHTML= 'page '+systemData.page+' / '+systemData.totalPages; @@ -290,12 +291,13 @@ class MaterialList { <table> <thead> <tr> <th style="width: 24%;"></th> - <th style="width: 20%;"> - <span info-sys-data="system-type">System type</span> - </th> <th style="width: 16%;"> <span info-sys-data="space-group">Space group</span> </th> + <th style="width: 20%;"> + <span >Space gr. int. symbol</span> + </th> + <th style="width: 22%;"> <span info-sys-data="structure-type">Structure type</span> </th> @@ -318,12 +320,14 @@ class MaterialList { html+= `<tr class="mat-row" data-mat-id="${mat.id}"> <td > ${label} [${mat.formula}] </td> - <td style="text-align:center" > - <!--<span info-sys-data="system-type">-->${mat.system_type} <!--</span>--> - </td> <td style="text-align:center" > ${mat.space_group_number === null ? '' : mat.space_group_number} </td> + <td> + ${mat.space_group_international_short_symbol === null ? '' : + mat.space_group_international_short_symbol} + </td> + <td> ${mat.structure_type === null ? '' : mat.structure_type } </td> <td style="text-align:center" > ${mat.nr_of_calculations} </td> </tr>`; diff --git a/client/src/search-mod/NewSearchMod.js b/client/src/search-mod/NewSearchMod.js index b7018bdd..800132d2 100644 --- a/client/src/search-mod/NewSearchMod.js +++ b/client/src/search-mod/NewSearchMod.js @@ -191,11 +191,7 @@ class NewSearchMod { this.materialNameBox.disable(true); } }); - /* - this.propertiesBox= new PropertiesBox(); - this.propertiesBox.setAddPropertiesListener(propsMap => { - this.addPropertiesInSearchQuery(propsMap); - });*/ + this.filterPanel = new FilterPanel(); this.filterSidePanel.appendChild(this.filterPanel.element); @@ -221,7 +217,7 @@ class NewSearchMod { if (this.searchQuery.lenght === 0){ util.showUserMsg('No query'); }else{ - let rootQueryObj; + let searchExpressionQuery; //************** Material name or complex search expression //if (this.queryTypes[i] === 'MN'){ @@ -229,18 +225,15 @@ class NewSearchMod { if (this.element.querySelector('#allow-other-elements').checked) - rootQueryObj = this._getESQueryFromSearchQuery_otherElements( + searchExpressionQuery = this._getESQueryFromSearchQuery_otherElements( this.searchQuery, this.queryTypes); // Regular case: search containing only the elements in the search expression - else rootQueryObj = + else searchExpressionQuery = this._getESQueryFromSearchQuery(this.searchQuery, this.queryTypes); - - /* Pending to ADD *************/ - //let filterMap = this.filterPanel.getValues(); - //this._addFiltersInSearchQuery(filterMap, queryObj); - - this.materialList.initSearch(rootQueryObj); + this.materialList.initSearch( + this._addFiltersInSearchQuery( this.filterPanel.getValues(), + searchExpressionQuery)); //util.setBrowserHashPath('search','results'); this.element.querySelector('.add-box').style.display = 'none'; @@ -272,7 +265,7 @@ class NewSearchMod { if (selectingTab === 'element') selectingElement = this.elementTable.element; else if (selectingTab === 'name') - selectingElement = this.materialNameBox.element;//this.propertiesBox.element; + selectingElement = this.materialNameBox.element; else if (selectingTab === 'formula') selectingElement = this.formulaBox.element; @@ -476,30 +469,37 @@ class NewSearchMod { - _addFiltersInSearchQuery(filterMap, queryFilterArray){ - //let filters = []; + _addFiltersInSearchQuery(filterMap, searchExpressionQuery){ + let rootQueryObj = { 'bool' : {} }; + rootQueryObj.bool.must = []; + rootQueryObj.bool.must.push( searchExpressionQuery ); + + filterMap.forEach((values/*Array*/, filterName) => { let filterNameDef = replaceDashes(filterName); if (filterName === 'mass-density' || filterName === 'band-gap'){ //***** util.eV2J() apply? - queryFilterArray.push( this._getFieldESRange(filterNameDef, values) ); + rootQueryObj.bool.must.push( this._getFieldESRange(filterNameDef, values) ); }else if (filterName === 'band-gap-type'){ // special case if ( values !== 'both') - queryFilterArray.push( this._getESSimpleMatch('band_gap_direct', + rootQueryObj.bool.must.push( this._getESSimpleMatch('band_gap_direct', ( values === 'direct' ? true : false ) ) ); }else if (filterName.startsWith('has')){ // has- filters - queryFilterArray.push( this._getESSimpleMatch(filterNameDef, values, false) ); + rootQueryObj.bool.must.push( this._getESSimpleMatch(filterNameDef, values, false) ); }else{ // normal case - queryFilterArray.push( this._getESOperatorMatch(filterNameDef, values, false) ); + rootQueryObj.bool.must.push( this._getESOperatorMatch(filterNameDef, values, false) ); + console.log(this._getESOperatorMatch(filterNameDef, values, false) ); } }); - //return filters; + + + return rootQueryObj; } @@ -596,28 +596,6 @@ class NewSearchMod { //this._showSearchBox(); } -/* - addPropertiesInSearchQuery(propsMap){ - propsMap.forEach((values, propName) => { - let i = this.queryTypes.indexOf(propName); - if (i < 0) - this.addTagInSearchQuery(values.join(' | '), propName); - else{ - let currentValues = this.searchQuery[i].split(' | '); - //console.log('Current VAlues: ',currentValues); - values.forEach(value => { - if (currentValues.indexOf(value) < 0) currentValues.push(value); - }); - this.searchQuery[i] = currentValues.join(' | '); - this.updateSearchQuery(); - //this._showSearchBox(); - } - }); - }*/ - - - - removeElementORFormulaInSearchQuery(item){ //console.log(" removeElementORFormulaInSearchQuery item: ",item, this.searchQuery.indexOf(item)); -- GitLab