@abi-software/map-side-bar 2.5.1 → 2.5.2-isan.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/map-side-bar.js +12034 -11575
- package/dist/map-side-bar.umd.cjs +113 -112
- package/dist/style.css +1 -1
- package/package.json +2 -2
- package/src/App.vue +27 -12
- package/src/algolia/algolia.js +42 -28
- package/src/algolia/utils.js +7 -2
- package/src/components/ConnectivityInfo.vue +114 -54
- package/src/components/DatasetCard.vue +10 -0
- package/src/components/PMRDatasetCard.vue +317 -0
- package/src/components/SearchFilters.vue +19 -2
- package/src/components/SideBar.vue +11 -3
- package/src/components/SidebarContent.vue +178 -33
- package/src/components.d.ts +1 -0
- package/src/flatmapQueries/flatmapQueries.js +221 -0
- package/src/mixins/mixedPageCalculation.vue +102 -0
|
@@ -34,18 +34,29 @@
|
|
|
34
34
|
ref="searchHistory"
|
|
35
35
|
@search="searchHistorySearch"
|
|
36
36
|
></SearchHistory>
|
|
37
|
+
pmr hits: {{ pmrNumberOfHits }}
|
|
37
38
|
<div class="content scrollbar" v-loading="loadingCards" ref="content">
|
|
38
39
|
<div class="error-feedback" v-if="results.length === 0 && !loadingCards">
|
|
39
40
|
No results found - Please change your search / filter criteria.
|
|
40
41
|
</div>
|
|
41
|
-
<div v-for="result in results" :key="result.doi" class="step-item">
|
|
42
|
+
<div v-for="(result, i) in results" :key="result.doi || i" class="step-item">
|
|
42
43
|
<DatasetCard
|
|
44
|
+
v-if="result.dataSource === 'SPARC'"
|
|
43
45
|
class="dataset-card"
|
|
44
46
|
:entry="result"
|
|
45
47
|
:envVars="envVars"
|
|
46
48
|
@mouseenter="hoverChanged(result)"
|
|
47
49
|
@mouseleave="hoverChanged(undefined)"
|
|
48
|
-
|
|
50
|
+
></DatasetCard>
|
|
51
|
+
<PMRDatasetCard
|
|
52
|
+
v-else-if="result.dataSource === 'PMR'"
|
|
53
|
+
class="dataset-card"
|
|
54
|
+
:entry="result"
|
|
55
|
+
:envVars="envVars"
|
|
56
|
+
@pmr-action-click="onPmrActionClick"
|
|
57
|
+
@mouseenter="hoverChanged(result)"
|
|
58
|
+
@mouseleave="hoverChanged(undefined)"
|
|
59
|
+
></PMRDatasetCard>
|
|
49
60
|
</div>
|
|
50
61
|
<el-pagination
|
|
51
62
|
class="pagination"
|
|
@@ -73,12 +84,17 @@ import {
|
|
|
73
84
|
} from 'element-plus'
|
|
74
85
|
import SearchFilters from './SearchFilters.vue'
|
|
75
86
|
import SearchHistory from './SearchHistory.vue'
|
|
76
|
-
import DatasetCard from './DatasetCard.vue'
|
|
77
87
|
import EventBus from './EventBus.js'
|
|
78
88
|
|
|
89
|
+
import DatasetCard from "./DatasetCard.vue";
|
|
90
|
+
import PMRDatasetCard from "./PMRDatasetCard.vue";
|
|
91
|
+
|
|
79
92
|
import { AlgoliaClient } from '../algolia/algolia.js'
|
|
80
93
|
import { getFilters, facetPropPathMapping } from '../algolia/utils.js'
|
|
94
|
+
import FlatmapQueries from '../flatmapQueries/flatmapQueries.js'
|
|
95
|
+
import mixedPageCalculation from '../mixins/mixedPageCalculation.vue'
|
|
81
96
|
import { markRaw } from 'vue'
|
|
97
|
+
const RatioOfPMRResults = 0.2; // Ratio of PMR results to Sparc results
|
|
82
98
|
|
|
83
99
|
// handleErrors: A custom fetch error handler to recieve messages from the server
|
|
84
100
|
// even when an error is found
|
|
@@ -98,21 +114,27 @@ var initial_state = {
|
|
|
98
114
|
searchInput: '',
|
|
99
115
|
lastSearch: '',
|
|
100
116
|
results: [],
|
|
101
|
-
|
|
117
|
+
pmrNumberOfHits: 0,
|
|
118
|
+
sparcNumberOfHits: 0,
|
|
102
119
|
filter: [],
|
|
103
120
|
loadingCards: false,
|
|
104
121
|
numberPerPage: 10,
|
|
105
122
|
page: 1,
|
|
106
|
-
|
|
107
|
-
|
|
123
|
+
pmrResultsOnlyFlag: false,
|
|
124
|
+
noPMRResultsFlag: false,
|
|
108
125
|
hasSearched: false,
|
|
109
126
|
contextCardEnabled: false,
|
|
110
|
-
|
|
127
|
+
pmrResults: [],
|
|
128
|
+
RatioOfPMRResults: RatioOfPMRResults,
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
|
|
111
132
|
|
|
112
133
|
export default {
|
|
113
134
|
components: {
|
|
114
135
|
SearchFilters,
|
|
115
136
|
DatasetCard,
|
|
137
|
+
PMRDatasetCard,
|
|
116
138
|
SearchHistory,
|
|
117
139
|
Button,
|
|
118
140
|
Card,
|
|
@@ -122,6 +144,7 @@ export default {
|
|
|
122
144
|
Pagination
|
|
123
145
|
},
|
|
124
146
|
name: 'SideBarContent',
|
|
147
|
+
mixins: [mixedPageCalculation],
|
|
125
148
|
props: {
|
|
126
149
|
visible: {
|
|
127
150
|
type: Boolean,
|
|
@@ -135,6 +158,13 @@ export default {
|
|
|
135
158
|
type: Object,
|
|
136
159
|
default: () => initial_state,
|
|
137
160
|
},
|
|
161
|
+
initFilters: {
|
|
162
|
+
type: Object,
|
|
163
|
+
default: {
|
|
164
|
+
filter: [],
|
|
165
|
+
searchInput: '',
|
|
166
|
+
}
|
|
167
|
+
},
|
|
138
168
|
envVars: {
|
|
139
169
|
type: Object,
|
|
140
170
|
default: () => {},
|
|
@@ -143,6 +173,7 @@ export default {
|
|
|
143
173
|
data: function () {
|
|
144
174
|
return {
|
|
145
175
|
...this.entry,
|
|
176
|
+
...this.initFilters,
|
|
146
177
|
algoliaClient: undefined,
|
|
147
178
|
bodyStyle: {
|
|
148
179
|
flex: '1 1 auto',
|
|
@@ -160,21 +191,69 @@ export default {
|
|
|
160
191
|
filterFacets: this.filter,
|
|
161
192
|
}
|
|
162
193
|
},
|
|
194
|
+
// npp_SPARC: Number per page for SPARC datasets
|
|
195
|
+
npp_SPARC: function () {
|
|
196
|
+
return Math.round(this.numberPerPage * (1 - RatioOfPMRResults))
|
|
197
|
+
},
|
|
198
|
+
// npp_PMR: Number per page for PMR datasets
|
|
199
|
+
npp_PMR: function () {
|
|
200
|
+
return Math.round(this.numberPerPage * RatioOfPMRResults)
|
|
201
|
+
},
|
|
202
|
+
numberOfHits: function () {
|
|
203
|
+
return this.sparcNumberOfHits + this.pmrNumberOfHits
|
|
204
|
+
},
|
|
205
|
+
|
|
163
206
|
},
|
|
164
207
|
methods: {
|
|
165
208
|
hoverChanged: function (data) {
|
|
166
209
|
this.$emit('hover-changed', data)
|
|
167
210
|
},
|
|
211
|
+
onPmrActionClick: function (data) {
|
|
212
|
+
this.$emit('pmr-action-click', data);
|
|
213
|
+
},
|
|
214
|
+
// resetSearch: Resets the results, and page, and variable results ratio
|
|
215
|
+
// Does not: reset filters, search input, or search history
|
|
168
216
|
resetSearch: function () {
|
|
169
|
-
this.
|
|
217
|
+
this.pmrNumberOfHits = 0
|
|
218
|
+
this.sparcNumberOfHits = 0
|
|
219
|
+
this.page = 1
|
|
220
|
+
this.calculateVariableRatio()
|
|
170
221
|
this.discoverIds = []
|
|
171
222
|
this._dois = []
|
|
172
223
|
this.results = []
|
|
173
224
|
this.loadingCards = false
|
|
174
225
|
},
|
|
175
|
-
openSearch:
|
|
226
|
+
// openSearch: Resets the results, populates dataset cards and filters. Will use Algolia and SciCrunch data uness pmr mode is set
|
|
227
|
+
openSearch: function(filter, search = '', resetSearch = true) {
|
|
228
|
+
this.updatePMROnlyFlag(filter);
|
|
229
|
+
|
|
230
|
+
if (resetSearch) {
|
|
231
|
+
this.resetSearch();
|
|
232
|
+
this.openFilterSearch(filter, search);
|
|
233
|
+
} else {
|
|
234
|
+
this.searchAlgolia(filter, search);
|
|
235
|
+
this.openPMRSearch(filter, search);
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
|
|
239
|
+
// openPMRSearch: Resets the results, populates dataset cards and filters with PMR data.
|
|
240
|
+
openPMRSearch: function (filter, search = '') {
|
|
241
|
+
this.loadingCards = true;
|
|
242
|
+
this.flatmapQueries.updateOffset(this.calculatePMROffest())
|
|
243
|
+
this.flatmapQueries.updateLimit(this.PMRLimit(this.pmrResultsOnlyFlag))
|
|
244
|
+
this.flatmapQueries.pmrSearch(filter, search).then((data) => {
|
|
245
|
+
data.forEach((result) => {
|
|
246
|
+
this.results.push(result)
|
|
247
|
+
})
|
|
248
|
+
this.pmrNumberOfHits = this.flatmapQueries.numberOfHits
|
|
249
|
+
this.loadingCards = false;
|
|
250
|
+
})
|
|
251
|
+
},
|
|
252
|
+
|
|
253
|
+
// previously openAlgoliaSearch:
|
|
254
|
+
// Resets the results, populates dataset cards and filters with Algloia and SciCrunch data.
|
|
255
|
+
openFilterSearch: function (filter, search = '') {
|
|
176
256
|
this.searchInput = search
|
|
177
|
-
this.resetPageNavigation()
|
|
178
257
|
//Proceed normally if cascader is ready
|
|
179
258
|
if (this.cascaderIsReady) {
|
|
180
259
|
this.filter =
|
|
@@ -191,7 +270,14 @@ export default {
|
|
|
191
270
|
this.$refs.filtersRef.checkShowAllBoxes()
|
|
192
271
|
this.resetSearch()
|
|
193
272
|
} else if (this.filter) {
|
|
194
|
-
|
|
273
|
+
if (this.pmrResultsOnlyFlag) {
|
|
274
|
+
this.openPMRSearch(this.filter, search);
|
|
275
|
+
} else if (this.noPMRResultsFlag) {
|
|
276
|
+
this.searchAlgolia(this.filter, search);
|
|
277
|
+
} else {
|
|
278
|
+
this.searchAlgolia(this.filter, search);
|
|
279
|
+
this.openPMRSearch(this.filter, search);
|
|
280
|
+
}
|
|
195
281
|
this.$refs.filtersRef.setCascader(this.filter)
|
|
196
282
|
}
|
|
197
283
|
} else {
|
|
@@ -199,13 +285,20 @@ export default {
|
|
|
199
285
|
//otherwise waith for cascader to be ready
|
|
200
286
|
this.filter = filter
|
|
201
287
|
if (!filter || filter.length == 0) {
|
|
202
|
-
|
|
288
|
+
if (this.pmrResultsOnlyFlag) {
|
|
289
|
+
this.openPMRSearch(this.filter, search);
|
|
290
|
+
} else if (this.noPMRResultsFlag) {
|
|
291
|
+
this.searchAlgolia(this.filter, search);
|
|
292
|
+
} else {
|
|
293
|
+
this.searchAlgolia(this.filter, search);
|
|
294
|
+
this.openPMRSearch(this.filter, search);
|
|
295
|
+
}
|
|
203
296
|
}
|
|
204
297
|
}
|
|
205
298
|
},
|
|
206
299
|
addFilter: function (filter) {
|
|
207
300
|
if (this.cascaderIsReady) {
|
|
208
|
-
this.
|
|
301
|
+
this.resetSearch()
|
|
209
302
|
if (filter) {
|
|
210
303
|
if (this.$refs.filtersRef.addFilter(filter))
|
|
211
304
|
this.$refs.filtersRef.initiateSearch()
|
|
@@ -224,31 +317,66 @@ export default {
|
|
|
224
317
|
},
|
|
225
318
|
clearSearchClicked: function () {
|
|
226
319
|
this.searchInput = ''
|
|
227
|
-
this.
|
|
228
|
-
this.
|
|
320
|
+
this.resetSearch()
|
|
321
|
+
this.openSearch(this.filter, this.searchInput)
|
|
229
322
|
this.$refs.searchHistory.selectValue = 'Full search history'
|
|
230
323
|
},
|
|
231
324
|
searchEvent: function (event = false) {
|
|
232
325
|
if (event.keyCode === 13 || event instanceof MouseEvent) {
|
|
233
|
-
this.
|
|
234
|
-
this.searchAlgolia(this.filters, this.searchInput)
|
|
326
|
+
this.openSearch(this.filter, this.searchInput)
|
|
235
327
|
this.$refs.searchHistory.selectValue = 'Full search history'
|
|
236
328
|
this.$refs.searchHistory.addSearchToHistory(
|
|
237
|
-
this.
|
|
329
|
+
this.filter,
|
|
238
330
|
this.searchInput
|
|
239
331
|
)
|
|
240
332
|
}
|
|
241
333
|
},
|
|
334
|
+
updatePMROnlyFlag: function (filters) {
|
|
335
|
+
const dataTypeFilters = filters.filter((item) => item.facetPropPath === 'item.types.name');
|
|
336
|
+
const pmrFilter = dataTypeFilters.filter((item) => item.facet === 'PMR');
|
|
337
|
+
const showAllFilter = dataTypeFilters.filter((item) => item.facet === 'Show all');
|
|
338
|
+
|
|
339
|
+
this.pmrResultsOnlyFlag = false;
|
|
340
|
+
this.noPMRResultsFlag = false;
|
|
341
|
+
|
|
342
|
+
if (dataTypeFilters.length === 1 && pmrFilter.length === 1) {
|
|
343
|
+
this.pmrResultsOnlyFlag = true;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
if (dataTypeFilters.length > 0 && pmrFilter.length === 0 && showAllFilter.length === 0) {
|
|
347
|
+
this.noPMRResultsFlag = true;
|
|
348
|
+
}
|
|
349
|
+
},
|
|
242
350
|
filterUpdate: function (filters) {
|
|
243
|
-
this.
|
|
244
|
-
|
|
245
|
-
|
|
351
|
+
this.filter = [...filters]
|
|
352
|
+
|
|
353
|
+
// Check if PMR is in the filters
|
|
354
|
+
this.updatePMROnlyFlag(filters)
|
|
355
|
+
|
|
356
|
+
// Note that we cannot use the openSearch function as that modifies filters
|
|
357
|
+
this.resetSearch()
|
|
358
|
+
if (this.pmrResultsOnlyFlag) {
|
|
359
|
+
this.openPMRSearch(filters, this.searchInput)
|
|
360
|
+
} else if (this.noPMRResultsFlag) {
|
|
361
|
+
this.searchAlgolia(filters, this.searchInput)
|
|
362
|
+
} else {
|
|
363
|
+
this.searchAlgolia(filters, this.searchInput)
|
|
364
|
+
this.openPMRSearch(filters, this.searchInput)
|
|
365
|
+
}
|
|
366
|
+
|
|
246
367
|
this.$emit('search-changed', {
|
|
247
368
|
value: filters,
|
|
248
369
|
type: 'filter-update',
|
|
249
370
|
})
|
|
250
371
|
},
|
|
251
372
|
searchAlgolia(filters, query = '') {
|
|
373
|
+
|
|
374
|
+
// Remove loading if we dont expect any results
|
|
375
|
+
if (this.SPARCLimit() === 0) {
|
|
376
|
+
this.loadingCards = false
|
|
377
|
+
return
|
|
378
|
+
}
|
|
379
|
+
|
|
252
380
|
// Algolia search
|
|
253
381
|
|
|
254
382
|
this.loadingCards = true
|
|
@@ -260,12 +388,17 @@ export default {
|
|
|
260
388
|
EventBus.emit('number-of-datasets-for-anatomies', r.forScaffold)
|
|
261
389
|
})
|
|
262
390
|
this.algoliaClient
|
|
263
|
-
.search(getFilters(filters), query, this.
|
|
391
|
+
.search(getFilters(filters), query, this.calculateSPARCOffest(), this.SPARCLimit(this.pmrResultsOnlyFlag) )
|
|
264
392
|
.then((searchData) => {
|
|
265
|
-
this.
|
|
393
|
+
this.sparcNumberOfHits = searchData.total
|
|
266
394
|
this.discoverIds = searchData.discoverIds
|
|
267
395
|
this._dois = searchData.dois
|
|
268
|
-
|
|
396
|
+
searchData.items.forEach((item) => {
|
|
397
|
+
item.detailsReady = false
|
|
398
|
+
this.results.push(item)
|
|
399
|
+
})
|
|
400
|
+
// add the items to the results
|
|
401
|
+
this.results.concat(searchData.items)
|
|
269
402
|
this.loadingCards = false
|
|
270
403
|
this.scrollToTop()
|
|
271
404
|
this.$emit('search-changed', {
|
|
@@ -287,14 +420,10 @@ export default {
|
|
|
287
420
|
this.pageChange(1)
|
|
288
421
|
},
|
|
289
422
|
pageChange: function (page) {
|
|
290
|
-
this.start = (page - 1) * this.numberPerPage
|
|
291
423
|
this.page = page
|
|
292
|
-
this.
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
this.numberPerPage,
|
|
296
|
-
this.page
|
|
297
|
-
)
|
|
424
|
+
this.results = []
|
|
425
|
+
this.calculateVariableRatio()
|
|
426
|
+
this.openSearch(this.filter, this.searchInput, false)
|
|
298
427
|
},
|
|
299
428
|
handleMissingData: function (doi) {
|
|
300
429
|
let i = this.results.findIndex((res) => res.doi === doi)
|
|
@@ -336,7 +465,6 @@ export default {
|
|
|
336
465
|
}
|
|
337
466
|
},
|
|
338
467
|
resetPageNavigation: function () {
|
|
339
|
-
this.start = 0
|
|
340
468
|
this.page = 1
|
|
341
469
|
},
|
|
342
470
|
resultsProcessing: function (data) {
|
|
@@ -450,7 +578,13 @@ export default {
|
|
|
450
578
|
this.envVars.PENNSIEVE_API_LOCATION
|
|
451
579
|
))
|
|
452
580
|
this.algoliaClient.initIndex(this.envVars.ALGOLIA_INDEX)
|
|
453
|
-
|
|
581
|
+
|
|
582
|
+
// initialise flatmap queries
|
|
583
|
+
this.flatmapQueries = new FlatmapQueries()
|
|
584
|
+
this.flatmapQueries.initialise(this.envVars.FLATMAP_API_LOCATION)
|
|
585
|
+
|
|
586
|
+
// open search
|
|
587
|
+
this.openSearch(this.filter, this.searchInput, this.mode )
|
|
454
588
|
},
|
|
455
589
|
created: function () {
|
|
456
590
|
//Create non-reactive local variables
|
|
@@ -489,6 +623,17 @@ export default {
|
|
|
489
623
|
display: flex;
|
|
490
624
|
}
|
|
491
625
|
|
|
626
|
+
.data-type-select {
|
|
627
|
+
width: 90px;
|
|
628
|
+
margin-left: 10px;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
.button {
|
|
632
|
+
background-color: $app-primary-color;
|
|
633
|
+
border: $app-primary-color;
|
|
634
|
+
color: white;
|
|
635
|
+
}
|
|
636
|
+
|
|
492
637
|
.step-item {
|
|
493
638
|
font-size: 14px;
|
|
494
639
|
margin-bottom: 18px;
|
package/src/components.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ declare module 'vue' {
|
|
|
31
31
|
ElTag: typeof import('element-plus/es')['ElTag']
|
|
32
32
|
ExternalResourceCard: typeof import('./components/ExternalResourceCard.vue')['default']
|
|
33
33
|
ImageGallery: typeof import('./components/ImageGallery.vue')['default']
|
|
34
|
+
PMRDatasetCard: typeof import('./components/PMRDatasetCard.vue')['default']
|
|
34
35
|
SearchFilters: typeof import('./components/SearchFilters.vue')['default']
|
|
35
36
|
SearchHistory: typeof import('./components/SearchHistory.vue')['default']
|
|
36
37
|
SideBar: typeof import('./components/SideBar.vue')['default']
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
function transformKeyValueArrayToObject(data) {
|
|
2
|
+
try {
|
|
3
|
+
let result = data.values.map(valueArray =>
|
|
4
|
+
data.keys.reduce((acc, key, index) => {
|
|
5
|
+
acc[key] = valueArray[index];
|
|
6
|
+
return acc;
|
|
7
|
+
}, {})
|
|
8
|
+
)
|
|
9
|
+
return result
|
|
10
|
+
} catch (error) {
|
|
11
|
+
console.error(`Error occured during conversion of Key Value Array to Object: ${error}`)
|
|
12
|
+
return {}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// remove duplicates by stringifying the objects
|
|
18
|
+
const removeDuplicates = function (arrayOfAnything) {
|
|
19
|
+
if (!arrayOfAnything) return []
|
|
20
|
+
return [...new Set(arrayOfAnything.map((e) => JSON.stringify(e)))].map((e) =>
|
|
21
|
+
JSON.parse(e)
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
let FlatmapQueries = function () {
|
|
27
|
+
this.initialise = function (flatmapApi) {
|
|
28
|
+
this.flatmapApi = flatmapApi
|
|
29
|
+
this.features = []
|
|
30
|
+
this.limit = 10
|
|
31
|
+
this.offset = 0
|
|
32
|
+
this.numberOfHits = 0
|
|
33
|
+
this.sqlPreOffset = ''
|
|
34
|
+
this.lookup = {}
|
|
35
|
+
this.createLookup()
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
this.updateOffset = function (offset) {
|
|
39
|
+
this.offset = offset
|
|
40
|
+
}
|
|
41
|
+
this.updateLimit = function (limit) {
|
|
42
|
+
this.limit = limit
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
this.offsetText = function () {
|
|
46
|
+
return 'limit ' + this.limit + ' offset ' + this.offset
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
this.createTermSQL = function (terms) {
|
|
50
|
+
let sql = ''
|
|
51
|
+
let validFilter = false
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
if (terms && terms.length > 0) {
|
|
55
|
+
sql += 'and '
|
|
56
|
+
terms.forEach((t, i) => {
|
|
57
|
+
if (i == 0) {
|
|
58
|
+
sql += '('
|
|
59
|
+
}
|
|
60
|
+
if (t !== '') {
|
|
61
|
+
sql += `m.term='${t}'`
|
|
62
|
+
validFilter = true
|
|
63
|
+
if (i < terms.length - 1) {
|
|
64
|
+
sql += ' or '
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (i == terms.length - 1) {
|
|
68
|
+
sql += ') '
|
|
69
|
+
}
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
if (!validFilter) {
|
|
73
|
+
sql = ''
|
|
74
|
+
}
|
|
75
|
+
return sql
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
this.pmrSQL = function (terms=[], search='') {
|
|
80
|
+
let sql = 'select distinct m.term, m.exposure, m.score, m.workspace, d.metadata from pmr_text '
|
|
81
|
+
sql += 'as t left join pmr_metadata as d on t.entity=d.entity left join pmr_models as m on m.exposure=t.entity '
|
|
82
|
+
sql += 'where d.metadata is not null '
|
|
83
|
+
|
|
84
|
+
// add filters for the terms
|
|
85
|
+
const termsSql = this.createTermSQL(terms)
|
|
86
|
+
sql += termsSql
|
|
87
|
+
|
|
88
|
+
// Add the text search
|
|
89
|
+
if (search && search !== '') {
|
|
90
|
+
sql += `and (t.pmr_text match '${search}')`
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Add exposure and score filters if we aren't text searching
|
|
94
|
+
if (!search || search === '') {
|
|
95
|
+
sql += 'and m.exposure is not null and score > 0.69'
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// group by exposure
|
|
99
|
+
sql += ' group by m.exposure'
|
|
100
|
+
|
|
101
|
+
this.sqlPreOffset = sql
|
|
102
|
+
|
|
103
|
+
// add the limit and offset for pagination
|
|
104
|
+
sql += ' ' + this.offsetText() + ';'
|
|
105
|
+
|
|
106
|
+
console.log(sql)
|
|
107
|
+
return sql
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
this.convertTermsToIds = function (terms) {
|
|
111
|
+
return terms.filter(t => this.lookUpId(t))
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
this.labelSQL = function (){
|
|
115
|
+
return "select entity, label from labels"
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
this.countSQL = function (sql) {
|
|
119
|
+
sql = `select count(*) from (${sql})`
|
|
120
|
+
return sql
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
this.flatmapQuery = function (sql) {
|
|
125
|
+
const data = { sql: sql }
|
|
126
|
+
return fetch(`${this.flatmapApi}knowledge/query/`, {
|
|
127
|
+
method: 'POST',
|
|
128
|
+
headers: {
|
|
129
|
+
'Content-Type': 'application/json',
|
|
130
|
+
},
|
|
131
|
+
body: JSON.stringify(data),
|
|
132
|
+
})
|
|
133
|
+
.then((response) => response.json())
|
|
134
|
+
.catch((error) => {
|
|
135
|
+
console.error('Error:', error)
|
|
136
|
+
})
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
this.processFilters = function (filters) {
|
|
140
|
+
let featureFacets = []
|
|
141
|
+
filters.forEach((f) => {
|
|
142
|
+
if (f.facet !== 'Show all' && f.facet !== 'PMR')
|
|
143
|
+
featureFacets.push(f.facet)
|
|
144
|
+
})
|
|
145
|
+
return featureFacets
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
this.pmrSearch = function (filters=[], search='') {
|
|
151
|
+
let features = this.processFilters(filters)
|
|
152
|
+
let featureIds = this.convertTermsToIds(features)
|
|
153
|
+
return new Promise((resolve, reject) => {
|
|
154
|
+
this.flatmapQuery(this.pmrSQL(featureIds, search))
|
|
155
|
+
.then(data => {
|
|
156
|
+
const pd = this.processPMRData(data, featureIds)
|
|
157
|
+
this.setAvailableFeatures(pd)
|
|
158
|
+
|
|
159
|
+
// get the number of hits for pagination
|
|
160
|
+
this.flatmapQuery(this.countSQL(this.sqlPreOffset)).then(data => {
|
|
161
|
+
this.numberOfHits = data.values[0][0]
|
|
162
|
+
resolve(pd);
|
|
163
|
+
})
|
|
164
|
+
})
|
|
165
|
+
.catch(reject);
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// setAvailableFeatures returns the available features in the flatmap for filtering
|
|
170
|
+
// pd is the processed data from the flatmap
|
|
171
|
+
this.setAvailableFeatures = function (pd) {
|
|
172
|
+
pd.forEach((d) => {
|
|
173
|
+
Object.keys(d).forEach((key) => {
|
|
174
|
+
if (!this.features.includes(key)) {
|
|
175
|
+
this.features.push(key)
|
|
176
|
+
}
|
|
177
|
+
})
|
|
178
|
+
})
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
this.processPMRData = function (data, featureIds=[]) {
|
|
183
|
+
// Convert the flatmap data into an array of objects
|
|
184
|
+
let dataObj = transformKeyValueArrayToObject(data)
|
|
185
|
+
|
|
186
|
+
// Only use the results with metadata
|
|
187
|
+
let metadataResults = dataObj.filter(d => d.metadata)
|
|
188
|
+
let metadataOnly = metadataResults.map(d => {
|
|
189
|
+
let md = JSON.parse(d.metadata)
|
|
190
|
+
md.dataSource = 'PMR'
|
|
191
|
+
return md
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
// If there are featureIds, filter the results
|
|
195
|
+
if (featureIds.length > 0) {
|
|
196
|
+
metadataOnly = metadataOnly.filter(d => featureIds.includes(d.term))
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Remove duplicates
|
|
200
|
+
let uniqueResults = removeDuplicates(metadataOnly)
|
|
201
|
+
return uniqueResults
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
this.createLookup = function () {
|
|
205
|
+
this.flatmapQuery(this.labelSQL())
|
|
206
|
+
.then(data => {
|
|
207
|
+
data.values.forEach(d => {
|
|
208
|
+
if (d[1] && (typeof d[1] === 'string' || d[1] instanceof String)) {
|
|
209
|
+
this.lookup[d[1].toLowerCase()] = d[0]
|
|
210
|
+
}
|
|
211
|
+
})
|
|
212
|
+
})
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
this.lookUpId = function (label) {
|
|
216
|
+
return this.lookup[label.toLowerCase()]
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export default FlatmapQueries
|