8484 :color =" selectedDatabases > 0 ? hits.results[selectedDatabases - 1].color : null"
8585 center-active
8686 grow
87- v-model =" tabModel "
87+ v-model =" selectedDatabases "
8888 show-arrows
8989 @change =" handleChangeDatabase()"
9090 v-if =" hits.results.length > 1"
9191 >
92- <!-- < v-tab>All databases </v-tab> -- >
92+ <v-tab >Summary </v-tab >
9393 <v-tab v-for =" entry in hits.results" :key =" entry.db" >{{ entry.db.replaceAll(/_folddisco$/g, '') }} ({{ entry.alignments ? Object.values(entry.alignments).length : 0 }})</v-tab >
9494 </v-tabs >
9595 </v-sheet >
96+ <TopHits
97+ v-if =" hits && hits.results && hits.results.length > 1"
98+ v-show =" selectedDatabases == 0"
99+ :hits =" hits" :mode =" 2"
100+ @jumpTo =" i => selectedDatabases = i+1"
101+ />
102+ <keep-alive >
103+ <Top100Folddisco
104+ v-if =" hits && hits.results && hits.results.length > 1 && selectedDatabases == 0"
105+ ref =" top100" :hits =" hits" :alignment =" alignment" :selectedStates =" selectedStates"
106+ :selectedCounts =" selectedCounts" :selectUpperbound =" selectUpperbound"
107+ @showAlignment =" (o, db, e) => showAlignment(o, db, e)"
108+ @toggleSelection =" (db, i, v) => handleToggleSelection(db, i, v, true)"
109+ @bulkToggle =" (a, v) => handleBulkToggleFromTop100(a, v)"
110+ @forwardDropdown =" (e, h) => forwardDropdown(e, h)"
111+ @clearAll =" clearAllEntries" @jumpTo =" i => selectedDatabases = i+1"
112+ />
113+ </keep-alive >
96114 <ResultFoldDiscoDB v-for =" (entry, entryidx) in hits.results" :key =" entry.db"
97- v-if =" selectedDatabases == 0 || (entryidx + 1) == selectedDatabases"
115+ :ref =" 'dbComponent' + entryidx"
116+ v-if =" (entryidx + 1) == selectedDatabases"
98117 :entryidx =" entryidx" :entry =" entry" :toggleSourceDb =" toggleSourceDb"
99118 :selectedStates =" selectedStates[entryidx]" :selectedCounts =" selectedCountPerDb[entryidx]"
100119 :totalSelectedCounts =" selectedCounts" :selectUpperbound =" selectUpperbound" :alignment =" alignment"
105124 @toggleSelection =" (i, v) => handleToggleSelection(entryidx, i, v)"
106125 @bulkToggle =" (a, v) => handleBulkToggle(entryidx, a, v)"
107126 @updateScroll =" () => updateScrollOffsetArr()"
127+ @clusterInfo =" (info) => handleClusterInfo(entryidx, info)"
108128 ></ResultFoldDiscoDB >
109129 </template >
110130 </panel >
126146 <NavigationButton :selectedDatabases =" selectedDatabases"
127147 :scrollOffsetArr =" scrollOffsetArr"
128148 :tabOffset =" tabOffset"
149+ :hasMoreClusters =" hasMoreClusters"
129150 @needUpdate =" updateScrollOffsetArr"
151+ @needRenderNext =" handleNeedRenderNext"
130152 ></NavigationButton >
131153 </v-flex >
132154 </v-layout >
@@ -169,6 +191,8 @@ import NavigationButton from './NavigationButton.vue';
169191import ResultFoldDiscoDB from ' ./ResultFoldDiscoDB.vue' ;
170192import SelectToSendPanel from ' ./SelectToSendPanel.vue' ;
171193import NameField from ' ./NameField.vue' ;
194+ import TopHits from ' ./TopHits.vue' ;
195+ import Top100Folddisco from ' ./Top100Folddisco.vue' ;
172196
173197function getAbsOffsetTop ($el ) {
174198 var sum = 0 ;
@@ -183,7 +207,15 @@ function getAbsOffsetTop($el) {
183207export default {
184208 name: ' ResultFoldDisco' ,
185209 tool: ' folddisco' ,
186- components: { Panel, StructureViewerMotif, NavigationButton, ResultFoldDiscoDB, SelectToSendPanel, NameField },
210+ components: { Panel,
211+ StructureViewerMotif,
212+ NavigationButton,
213+ ResultFoldDiscoDB,
214+ SelectToSendPanel,
215+ NameField,
216+ TopHits,
217+ Top100Folddisco,
218+ },
187219 // components: { ResultView },
188220 mixins: [ ResultMixin, ResultSankeyMixin ],
189221 data () {
@@ -205,11 +237,12 @@ export default {
205237 toggleSourceDb: " " ,
206238 dbToIdx: null ,
207239 selectUpperbound: 100 ,
208- selectedStates: {} ,
240+ selectedStates: null ,
209241 selectedCounts: 0 ,
210- selectedCountPerDb: {} ,
242+ selectedCountPerDb: null ,
211243 selectedSets: new Set (),
212244 scrollOffsetArr: [],
245+ clusterInfoPerDb: {},
213246 }
214247 },
215248 created () {
@@ -273,19 +306,18 @@ export default {
273306 }
274307 return dbGaps;
275308 },
276- tabModel: {
277- get () {
278- return this .selectedDatabases - 1 ;
279- },
280- set (val ) {
281- this .selectedDatabases = val + 1 ;
282- }
283- },
284309 tabOffset () {
285310 let addend = this .hits ? .results ? .length == 1 ? 92 : 140
286311 let sheetHeight = this .$vuetify .breakpoint .xsOnly ? 356 : this .$vuetify .breakpoint .mdAndDown ? 304 : 180
287312 let colheadHeight = 32
288313 return addend + sheetHeight + colheadHeight
314+ },
315+ hasMoreClusters () {
316+ for (const key in this .clusterInfoPerDb ) {
317+ const info = this .clusterInfoPerDb [key]
318+ if (info .totalClusterCount > info .renderedClusterCount ) return true
319+ }
320+ return false
289321 }
290322 },
291323 mounted () {
@@ -358,6 +390,7 @@ export default {
358390 this .updateScrollOffsetArr ()
359391 }, 0 )
360392 })
393+ this .selectedDatabases = n .results .length == 1 ? 1 : 0
361394 }
362395 },
363396 immediate: false ,
@@ -387,7 +420,7 @@ export default {
387420 },
388421 async getTargetPdb (item , db ) {
389422 let target = item .dbkey ;
390- if (db .startsWith (" pdb_ " )) {
423+ if (db .startsWith (" pdb " )) {
391424 target = item .target ;
392425 }
393426 const re = " api/result/folddisco/" + this .$route .params .ticket + ' ?database=' + db + ' &id=' + target;
@@ -397,9 +430,9 @@ export default {
397430 try {
398431 const request = await this .$axios .get (re, {
399432 headers: {
400- ' Cache-Control' : ' no-cache, no-store, must-revalidate' ,
401- ' Pragma' : ' no-cache' ,
402- ' Expires' : ' 0' ,
433+ // 'Cache-Control': 'no-cache, no-store, must-revalidate',
434+ // 'Pragma': 'no-cache',
435+ // 'Expires': '0',
403436 ' Accept' : ' text/plain' ,
404437 },
405438 transformResponse: [(d ) => d],
@@ -436,7 +469,7 @@ export default {
436469 handleChangeDatabase () {
437470 this .closeAlignment ();
438471 },
439- handleToggleSelection (db , idx , value ) {
472+ handleToggleSelection (db , idx , value , fromTop100 = false ) {
440473 if (! this .selectedStates || ! this .selectedStates [db]
441474 || this .selectedCounts > this .selectUpperbound && value) {
442475 return
@@ -449,21 +482,36 @@ export default {
449482 if (this .selectedStates [db][idx] != value) {
450483 // Does it really reflect changes?
451484 this .selectedStates [db][idx] = value
452- let el = document .getElementById (id)
453- if (el) {
454- el .classList .toggle (' selected' , value)
485+
486+ if (fromTop100) {
487+ document .getElementById (' top.' + id)? .classList .toggle (' selected' , value)
488+ } else {
489+ document .getElementById (id)? .classList .toggle (' selected' , value)
455490 }
491+
492+
456493 const newVal = this .selectedCountPerDb [db] + deltaUnit
457494 this .selectedCountPerDb [db] = newVal
458495 this .selectedCounts += deltaUnit
459496 toCall (id)
460497
461498 // update select-all button state
462- const targetDbLength = this .selectedStates [db].length
463- el = document .getElementById (db + ' #select-all' )
464- if (el) {
465- el .classList .toggle (' any-selected' , newVal > 0 )
466- el .classList .toggle (' all-selected' , newVal == targetDbLength)
499+ if (! fromTop100) {
500+ const targetDbLength = this .selectedStates [db].length
501+ let el = document .getElementById (db + ' #select-all' )
502+ if (el) {
503+ el .classList .toggle (' any-selected' , newVal > 0 )
504+ el .classList .toggle (' all-selected' , newVal == targetDbLength)
505+ }
506+ } else {
507+ const length = this .$refs .top100 .entryLength
508+ const newValTop = this .$refs .top100 .selectedTopEntries + deltaUnit
509+ const selectAllButton = document .getElementById (' top#select-all' )
510+ if (selectAllButton) {
511+ selectAllButton .classList .toggle (' any-selected' , newValTop > 0 )
512+ selectAllButton .classList .toggle (' all-selected' , newValTop == length)
513+ }
514+ this .$refs .top100 .selectedTopEntries = newValTop
467515 }
468516 }
469517 },
@@ -485,10 +533,8 @@ export default {
485533 }
486534 if (this .selectedStates [db][i] != value) {
487535 let id = db + ' #' + i .toString ()
488- let el = document .getElementById (id)
489- if (el) {
490- el .classList .toggle (' selected' , value)
491- }
536+ document .getElementById (id)? .classList .toggle (' selected' , value)
537+
492538 this .selectedStates [db][i] = value
493539 toCall (id)
494540 delta += deltaUnit
@@ -507,6 +553,54 @@ export default {
507553 selectAllButton .classList .toggle (' all-selected' , newVal == dbLength)
508554 }
509555 },
556+ handleBulkToggleFromTop100 (indices , value ) {
557+ // This method is called by Top100 component only
558+
559+ if (! this .selectedStates
560+ || this .selectedCounts > this .selectUpperbound && value) {
561+ return
562+ }
563+
564+ let delta = 0
565+ let deltaPerDb = Object .fromEntries (Object .keys (this .selectedStates ).map (k => [k, 0 ]))
566+ const deltaUnit = value ? 1 : - 1
567+ const deltaUpperbound = this .selectUpperbound - this .selectedCounts
568+ const toCall = value ? this .selectedSets .add .bind (this .selectedSets ) :
569+ this .selectedSets .delete .bind (this .selectedSets )
570+ let dbSet = new Set ()
571+
572+ for (const idx of indices) {
573+ if (value && delta >= deltaUpperbound) {
574+ break ;
575+ }
576+ let [db, i] = idx .split (" #" )
577+ dbSet .add (db)
578+
579+ if (this .selectedStates [db][i] != value) {
580+ document .getElementById (' top.' + idx)? .classList .toggle (' selected' , value)
581+ this .selectedStates [db][i] = value
582+ toCall (idx)
583+ delta += deltaUnit
584+ deltaPerDb[db] += deltaUnit
585+ }
586+ }
587+
588+ this .selectedCounts += delta
589+ for (let db of dbSet) {
590+ this .selectedCountPerDb [db] += delta
591+ }
592+
593+ const length = this .$refs .top100 .entryLength
594+ const newVal = this .$refs .top100 .selectedTopEntries + delta
595+ this .$refs .top100 .selectedTopEntries = newVal
596+
597+ // update select-all button state
598+ const selectAllButton = document .getElementById (' top#select-all' )
599+ if (selectAllButton) {
600+ selectAllButton .classList .toggle (' any-selected' , newVal > 0 )
601+ selectAllButton .classList .toggle (' all-selected' , newVal == length)
602+ }
603+ },
510604 updateToggleSourceDb (db ) {
511605 this .toggleSourceDb = db
512606 },
@@ -532,6 +626,11 @@ export default {
532626 el .classList .toggle (' all-selected' , false )
533627 }
534628 }
629+ el = document .getElementById (' top#select-all' )
630+ if (el) {
631+ el .classList .toggle (' any-selected' , false )
632+ el .classList .toggle (' all-selected' , false )
633+ }
535634
536635 // update selected states manually
537636 let prevSelected = document .querySelectorAll (' .selected' )
@@ -661,6 +760,36 @@ export default {
661760 const arr = document .querySelectorAll (' [class^="result-entry-"]' )
662761 const offsetArr = [... arr].map (n => Math .ceil (n .getBoundingClientRect ().top + window .scrollY ))
663762 this .scrollOffsetArr = offsetArr
763+ },
764+ handleClusterInfo (entryidx , info ) {
765+ this .$set (this .clusterInfoPerDb , entryidx, info)
766+ },
767+ async handleNeedRenderNext () {
768+ // Find the first child component that has unrendered clusters
769+ const results = this .hits ? .results
770+ if (! results) return
771+ for (let i = 0 ; i < results .length ; i++ ) {
772+ if (this .selectedDatabases != 0 && (i + 1 ) != this .selectedDatabases ) continue
773+ const refs = this .$refs [' dbComponent' + i]
774+ const comp = Array .isArray (refs) ? refs[0 ] : refs
775+ if (! comp) continue
776+ const info = this .clusterInfoPerDb [i]
777+ if (! info || info .totalClusterCount <= info .renderedClusterCount ) continue
778+ // Find the next unrendered cluster key
779+ const nextKey = comp .clusterKeys [comp .renderedClusterKeys .length ]
780+ if (! nextKey) continue
781+ await comp .renderUpToCluster (nextKey)
782+ this .$nextTick (() => {
783+ this .updateScrollOffsetArr ()
784+ // Scroll to the newly rendered cluster
785+ const el = document .querySelector (' .result-entry-' + i + nextKey)
786+ if (el) {
787+ const top = Math .ceil (el .getBoundingClientRect ().top + window .scrollY ) - this .tabOffset
788+ window .scrollTo ({ top, left: 0 , behavior: ' smooth' })
789+ }
790+ })
791+ return
792+ }
664793 }
665794 },
666795};
0 commit comments