@abi-software/map-side-bar 2.7.0 → 2.7.1-isan.1
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 +6265 -6115
- package/dist/map-side-bar.umd.cjs +60 -62
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/App.vue +27 -13
- package/src/algolia/algolia.js +42 -28
- package/src/algolia/utils.js +0 -1
- package/src/components/DatasetCard.vue +10 -0
- package/src/components/PMRDatasetCard.vue +317 -0
- package/src/components/SearchFilters.vue +17 -0
- package/src/components/SideBar.vue +10 -15
- package/src/components/SidebarContent.vue +165 -29
- package/src/components.d.ts +1 -2
- package/src/flatmapQueries/flatmapQueries.js +227 -0
- package/src/mixins/mixedPageCalculation.vue +108 -0
- package/src/components/ConnectivityCard.vue +0 -163
- package/src/components/ConnectivityExplorer.vue +0 -352
|
@@ -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
|
|
@@ -99,21 +115,27 @@ var initial_state = {
|
|
|
99
115
|
searchInput: '',
|
|
100
116
|
lastSearch: '',
|
|
101
117
|
results: [],
|
|
102
|
-
|
|
118
|
+
pmrNumberOfHits: 0,
|
|
119
|
+
sparcNumberOfHits: 0,
|
|
103
120
|
filter: [],
|
|
104
121
|
loadingCards: false,
|
|
105
122
|
numberPerPage: 10,
|
|
106
123
|
page: 1,
|
|
107
|
-
|
|
108
|
-
|
|
124
|
+
pmrResultsOnlyFlag: false,
|
|
125
|
+
noPMRResultsFlag: false,
|
|
109
126
|
hasSearched: false,
|
|
110
127
|
contextCardEnabled: false,
|
|
111
|
-
|
|
128
|
+
pmrResults: [],
|
|
129
|
+
RatioOfPMRResults: RatioOfPMRResults,
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
|
|
112
133
|
|
|
113
134
|
export default {
|
|
114
135
|
components: {
|
|
115
136
|
SearchFilters,
|
|
116
137
|
DatasetCard,
|
|
138
|
+
PMRDatasetCard,
|
|
117
139
|
SearchHistory,
|
|
118
140
|
Button,
|
|
119
141
|
Card,
|
|
@@ -123,6 +145,7 @@ export default {
|
|
|
123
145
|
Pagination
|
|
124
146
|
},
|
|
125
147
|
name: 'SideBarContent',
|
|
148
|
+
mixins: [mixedPageCalculation],
|
|
126
149
|
props: {
|
|
127
150
|
visible: {
|
|
128
151
|
type: Boolean,
|
|
@@ -136,6 +159,13 @@ export default {
|
|
|
136
159
|
type: Object,
|
|
137
160
|
default: () => initial_state,
|
|
138
161
|
},
|
|
162
|
+
initFilters: {
|
|
163
|
+
type: Object,
|
|
164
|
+
default: {
|
|
165
|
+
filter: [],
|
|
166
|
+
searchInput: '',
|
|
167
|
+
}
|
|
168
|
+
},
|
|
139
169
|
envVars: {
|
|
140
170
|
type: Object,
|
|
141
171
|
default: () => {},
|
|
@@ -144,6 +174,7 @@ export default {
|
|
|
144
174
|
data: function () {
|
|
145
175
|
return {
|
|
146
176
|
...this.entry,
|
|
177
|
+
...this.initFilters,
|
|
147
178
|
algoliaClient: undefined,
|
|
148
179
|
bodyStyle: {
|
|
149
180
|
flex: '1 1 auto',
|
|
@@ -161,21 +192,54 @@ export default {
|
|
|
161
192
|
filterFacets: this.filter,
|
|
162
193
|
}
|
|
163
194
|
},
|
|
195
|
+
// npp_SPARC: Number per page for SPARC datasets
|
|
196
|
+
npp_SPARC: function () {
|
|
197
|
+
return Math.round(this.numberPerPage * (1 - RatioOfPMRResults))
|
|
198
|
+
},
|
|
199
|
+
// npp_PMR: Number per page for PMR datasets
|
|
200
|
+
npp_PMR: function () {
|
|
201
|
+
return Math.round(this.numberPerPage * RatioOfPMRResults)
|
|
202
|
+
},
|
|
203
|
+
numberOfHits: function () {
|
|
204
|
+
return this.sparcNumberOfHits + this.pmrNumberOfHits
|
|
205
|
+
},
|
|
206
|
+
|
|
164
207
|
},
|
|
165
208
|
methods: {
|
|
166
209
|
hoverChanged: function (data) {
|
|
167
210
|
this.$emit('hover-changed', data)
|
|
168
211
|
},
|
|
212
|
+
onPmrActionClick: function (data) {
|
|
213
|
+
this.$emit('pmr-action-click', data);
|
|
214
|
+
},
|
|
215
|
+
// resetSearch: Resets the results, and page, and variable results ratio
|
|
216
|
+
// Does not: reset filters, search input, or search history
|
|
169
217
|
resetSearch: function () {
|
|
170
|
-
this.
|
|
218
|
+
this.pmrNumberOfHits = 0
|
|
219
|
+
this.sparcNumberOfHits = 0
|
|
220
|
+
this.page = 1
|
|
221
|
+
this.calculateVariableRatio()
|
|
171
222
|
this.discoverIds = []
|
|
172
223
|
this._dois = []
|
|
173
224
|
this.results = []
|
|
174
225
|
this.loadingCards = false
|
|
175
226
|
},
|
|
227
|
+
// openPMRSearch: Resets the results, populates dataset cards and filters with PMR data.
|
|
228
|
+
openPMRSearch: function (filter, search = '') {
|
|
229
|
+
this.resetSearch()
|
|
230
|
+
this.loadingCards = true;
|
|
231
|
+
this.flatmapQueries.updateOffset(this.calculatePMROffest())
|
|
232
|
+
this.flatmapQueries.updateLimit(this.PMRLimit(this.pmrResultsOnlyFlag))
|
|
233
|
+
this.flatmapQueries.pmrSearch(filter, search).then((data) => {
|
|
234
|
+
data.forEach((result) => {
|
|
235
|
+
this.results.push(result)
|
|
236
|
+
})
|
|
237
|
+
this.pmrNumberOfHits = this.flatmapQueries.numberOfHits
|
|
238
|
+
this.loadingCards = false;
|
|
239
|
+
})
|
|
240
|
+
},
|
|
176
241
|
openSearch: function (filter, search = '', option = { withSearch: true }) {
|
|
177
242
|
this.searchInput = search
|
|
178
|
-
this.resetPageNavigation()
|
|
179
243
|
//Proceed normally if cascader is ready
|
|
180
244
|
if (this.cascaderIsReady) {
|
|
181
245
|
this.filter =
|
|
@@ -193,7 +257,14 @@ export default {
|
|
|
193
257
|
this.resetSearch()
|
|
194
258
|
} else if (this.filter) {
|
|
195
259
|
if (option.withSearch) {
|
|
196
|
-
|
|
260
|
+
if (this.pmrResultsOnlyFlag) {
|
|
261
|
+
this.openPMRSearch(this.filter, search);
|
|
262
|
+
} else if (this.noPMRResultsFlag) {
|
|
263
|
+
this.searchAlgolia(this.filter, search);
|
|
264
|
+
} else {
|
|
265
|
+
this.searchAlgolia(this.filter, search);
|
|
266
|
+
this.openPMRSearch(this.filter, search);
|
|
267
|
+
}
|
|
197
268
|
}
|
|
198
269
|
this.$refs.filtersRef.setCascader(this.filter)
|
|
199
270
|
}
|
|
@@ -202,13 +273,20 @@ export default {
|
|
|
202
273
|
//otherwise waith for cascader to be ready
|
|
203
274
|
this.filter = filter
|
|
204
275
|
if ((!filter || filter.length == 0) && option.withSearch) {
|
|
205
|
-
|
|
276
|
+
if (this.pmrResultsOnlyFlag) {
|
|
277
|
+
this.openPMRSearch(this.filter, search);
|
|
278
|
+
} else if (this.noPMRResultsFlag) {
|
|
279
|
+
this.searchAlgolia(this.filter, search);
|
|
280
|
+
} else {
|
|
281
|
+
this.searchAlgolia(this.filter, search);
|
|
282
|
+
this.openPMRSearch(this.filter, search);
|
|
283
|
+
}
|
|
206
284
|
}
|
|
207
285
|
}
|
|
208
286
|
},
|
|
209
287
|
addFilter: function (filter) {
|
|
210
288
|
if (this.cascaderIsReady) {
|
|
211
|
-
this.
|
|
289
|
+
this.resetSearch()
|
|
212
290
|
if (filter) {
|
|
213
291
|
if (this.$refs.filtersRef.addFilter(filter))
|
|
214
292
|
this.$refs.filtersRef.initiateSearch()
|
|
@@ -226,18 +304,52 @@ export default {
|
|
|
226
304
|
this.openSearch(this.filter, this.searchInput)
|
|
227
305
|
},
|
|
228
306
|
clearSearchClicked: function () {
|
|
229
|
-
this.searchInput = ''
|
|
230
|
-
this.
|
|
307
|
+
this.searchInput = ''
|
|
308
|
+
this.resetSearch()
|
|
309
|
+
this.openSearch(this.filter, this.searchInput)
|
|
310
|
+
this.$refs.searchHistory.selectValue = 'Full search history'
|
|
231
311
|
},
|
|
232
312
|
searchEvent: function (event = false) {
|
|
233
313
|
if (event.keyCode === 13 || event instanceof MouseEvent) {
|
|
234
|
-
this.
|
|
235
|
-
this.
|
|
314
|
+
this.openSearch(this.filter, this.searchInput)
|
|
315
|
+
this.$refs.searchHistory.selectValue = 'Full search history'
|
|
316
|
+
this.$refs.searchHistory.addSearchToHistory(
|
|
317
|
+
this.filter,
|
|
318
|
+
this.searchInput
|
|
319
|
+
)
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
updatePMROnlyFlag: function (filters) {
|
|
323
|
+
const dataTypeFilters = filters.filter((item) => item.facetPropPath === 'item.types.name');
|
|
324
|
+
const pmrFilter = dataTypeFilters.filter((item) => item.facet === 'PMR');
|
|
325
|
+
const showAllFilter = dataTypeFilters.filter((item) => item.facet === 'Show all');
|
|
326
|
+
|
|
327
|
+
this.pmrResultsOnlyFlag = false;
|
|
328
|
+
this.noPMRResultsFlag = false;
|
|
329
|
+
|
|
330
|
+
if (dataTypeFilters.length === 1 && pmrFilter.length === 1) {
|
|
331
|
+
this.pmrResultsOnlyFlag = true;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if (dataTypeFilters.length > 0 && pmrFilter.length === 0 && showAllFilter.length === 0) {
|
|
335
|
+
this.noPMRResultsFlag = true;
|
|
236
336
|
}
|
|
237
337
|
},
|
|
238
338
|
filterUpdate: function (filters) {
|
|
239
|
-
this.
|
|
339
|
+
this.filter = [...filters]
|
|
240
340
|
this.searchAndFilterUpdate();
|
|
341
|
+
// Check if PMR is in the filters
|
|
342
|
+
this.updatePMROnlyFlag(filters)
|
|
343
|
+
// Note that we cannot use the openSearch function as that modifies filters
|
|
344
|
+
this.resetSearch()
|
|
345
|
+
if (this.pmrResultsOnlyFlag) {
|
|
346
|
+
this.openPMRSearch(filters, this.searchInput)
|
|
347
|
+
} else if (this.noPMRResultsFlag) {
|
|
348
|
+
this.searchAlgolia(filters, this.searchInput)
|
|
349
|
+
} else {
|
|
350
|
+
this.searchAlgolia(filters, this.searchInput)
|
|
351
|
+
this.openPMRSearch(filters, this.searchInput)
|
|
352
|
+
}
|
|
241
353
|
this.$emit('search-changed', {
|
|
242
354
|
value: filters,
|
|
243
355
|
type: 'filter-update',
|
|
@@ -270,6 +382,13 @@ export default {
|
|
|
270
382
|
}
|
|
271
383
|
},
|
|
272
384
|
searchAlgolia(filters, query = '') {
|
|
385
|
+
|
|
386
|
+
// Remove loading if we dont expect any results
|
|
387
|
+
if (this.SPARCLimit() === 0) {
|
|
388
|
+
this.loadingCards = false
|
|
389
|
+
return
|
|
390
|
+
}
|
|
391
|
+
|
|
273
392
|
// Algolia search
|
|
274
393
|
|
|
275
394
|
this.loadingCards = true
|
|
@@ -281,12 +400,17 @@ export default {
|
|
|
281
400
|
EventBus.emit('number-of-datasets-for-anatomies', r.forScaffold)
|
|
282
401
|
})
|
|
283
402
|
this.algoliaClient
|
|
284
|
-
.search(getFilters(filters), query, this.
|
|
403
|
+
.search(getFilters(filters), query, this.calculateSPARCOffest(), this.SPARCLimit(this.pmrResultsOnlyFlag) )
|
|
285
404
|
.then((searchData) => {
|
|
286
|
-
this.
|
|
405
|
+
this.sparcNumberOfHits = searchData.total
|
|
287
406
|
this.discoverIds = searchData.discoverIds
|
|
288
407
|
this._dois = searchData.dois
|
|
289
|
-
|
|
408
|
+
searchData.items.forEach((item) => {
|
|
409
|
+
item.detailsReady = false
|
|
410
|
+
this.results.push(item)
|
|
411
|
+
})
|
|
412
|
+
// add the items to the results
|
|
413
|
+
this.results.concat(searchData.items)
|
|
290
414
|
this.loadingCards = false
|
|
291
415
|
this.scrollToTop()
|
|
292
416
|
this.$emit('search-changed', {
|
|
@@ -308,14 +432,10 @@ export default {
|
|
|
308
432
|
this.pageChange(1)
|
|
309
433
|
},
|
|
310
434
|
pageChange: function (page) {
|
|
311
|
-
this.start = (page - 1) * this.numberPerPage
|
|
312
435
|
this.page = page
|
|
313
|
-
this.
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
this.numberPerPage,
|
|
317
|
-
this.page
|
|
318
|
-
)
|
|
436
|
+
this.results = []
|
|
437
|
+
this.calculateVariableRatio()
|
|
438
|
+
this.openSearch(this.filter, this.searchInput, false)
|
|
319
439
|
},
|
|
320
440
|
handleMissingData: function (doi) {
|
|
321
441
|
let i = this.results.findIndex((res) => res.doi === doi)
|
|
@@ -357,7 +477,6 @@ export default {
|
|
|
357
477
|
}
|
|
358
478
|
},
|
|
359
479
|
resetPageNavigation: function () {
|
|
360
|
-
this.start = 0
|
|
361
480
|
this.page = 1
|
|
362
481
|
},
|
|
363
482
|
resultsProcessing: function (data) {
|
|
@@ -473,7 +592,13 @@ export default {
|
|
|
473
592
|
this.envVars.PENNSIEVE_API_LOCATION
|
|
474
593
|
))
|
|
475
594
|
this.algoliaClient.initIndex(this.envVars.ALGOLIA_INDEX)
|
|
476
|
-
|
|
595
|
+
|
|
596
|
+
// initialise flatmap queries
|
|
597
|
+
this.flatmapQueries = new FlatmapQueries()
|
|
598
|
+
this.flatmapQueries.initialise(this.envVars.FLATMAP_API_LOCATION)
|
|
599
|
+
|
|
600
|
+
// open search
|
|
601
|
+
this.openSearch(this.filter, this.searchInput, this.mode )
|
|
477
602
|
},
|
|
478
603
|
created: function () {
|
|
479
604
|
//Create non-reactive local variables
|
|
@@ -515,6 +640,17 @@ export default {
|
|
|
515
640
|
border-bottom-right-radius: 0;
|
|
516
641
|
}
|
|
517
642
|
|
|
643
|
+
.data-type-select {
|
|
644
|
+
width: 90px;
|
|
645
|
+
margin-left: 10px;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
.button {
|
|
649
|
+
background-color: $app-primary-color;
|
|
650
|
+
border: $app-primary-color;
|
|
651
|
+
color: white;
|
|
652
|
+
}
|
|
653
|
+
|
|
518
654
|
.step-item {
|
|
519
655
|
font-size: 14px;
|
|
520
656
|
margin-bottom: 18px;
|
package/src/components.d.ts
CHANGED
|
@@ -9,8 +9,6 @@ declare module 'vue' {
|
|
|
9
9
|
export interface GlobalComponents {
|
|
10
10
|
AnnotationTool: typeof import('./components/AnnotationTool.vue')['default']
|
|
11
11
|
BadgesGroup: typeof import('./components/BadgesGroup.vue')['default']
|
|
12
|
-
ConnectivityCard: typeof import('./components/ConnectivityCard.vue')['default']
|
|
13
|
-
ConnectivityExplorer: typeof import('./components/ConnectivityExplorer.vue')['default']
|
|
14
12
|
ConnectivityInfo: typeof import('./components/ConnectivityInfo.vue')['default']
|
|
15
13
|
DatasetCard: typeof import('./components/DatasetCard.vue')['default']
|
|
16
14
|
ElButton: typeof import('element-plus/es')['ElButton']
|
|
@@ -37,6 +35,7 @@ declare module 'vue' {
|
|
|
37
35
|
ElSelect: typeof import('element-plus/es')['ElSelect']
|
|
38
36
|
ElTag: typeof import('element-plus/es')['ElTag']
|
|
39
37
|
ImageGallery: typeof import('./components/ImageGallery.vue')['default']
|
|
38
|
+
PMRDatasetCard: typeof import('./components/PMRDatasetCard.vue')['default']
|
|
40
39
|
SearchFilters: typeof import('./components/SearchFilters.vue')['default']
|
|
41
40
|
SearchHistory: typeof import('./components/SearchHistory.vue')['default']
|
|
42
41
|
SideBar: typeof import('./components/SideBar.vue')['default']
|
|
@@ -0,0 +1,227 @@
|
|
|
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 params = []
|
|
52
|
+
let validFilter = false
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
if (terms && terms.length > 0) {
|
|
56
|
+
sql += 'and '
|
|
57
|
+
terms.forEach((t, i) => {
|
|
58
|
+
if (i == 0) {
|
|
59
|
+
sql += '('
|
|
60
|
+
}
|
|
61
|
+
if (t !== '') {
|
|
62
|
+
params.push(terms)
|
|
63
|
+
sql += `m.term=?`
|
|
64
|
+
validFilter = true
|
|
65
|
+
if (i < terms.length - 1) {
|
|
66
|
+
sql += ' or '
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (i == terms.length - 1) {
|
|
70
|
+
sql += ') '
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
}
|
|
74
|
+
if (!validFilter) {
|
|
75
|
+
sql = ''
|
|
76
|
+
params = []
|
|
77
|
+
}
|
|
78
|
+
return {sql, params}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
this.pmrSQL = function (terms=[], search='') {
|
|
83
|
+
let sql = 'select distinct m.term, m.exposure, m.score, m.workspace, d.metadata from pmr_text '
|
|
84
|
+
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 '
|
|
85
|
+
sql += 'where d.metadata is not null '
|
|
86
|
+
|
|
87
|
+
// add filters for the terms
|
|
88
|
+
const requestDetails = this.createTermSQL(terms)
|
|
89
|
+
sql += requestDetails.sql
|
|
90
|
+
const params = [...requestDetails.params]
|
|
91
|
+
|
|
92
|
+
// Add the text search
|
|
93
|
+
if (search && search !== '') {
|
|
94
|
+
sql += `and (t.pmr_text match ?)`
|
|
95
|
+
params.push(search)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Add exposure and score filters if we aren't text searching
|
|
99
|
+
if (!search || search === '') {
|
|
100
|
+
sql += 'and m.exposure is not null and score > 0.69'
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// group by exposure
|
|
104
|
+
sql += ' group by m.exposure'
|
|
105
|
+
|
|
106
|
+
this.sqlPreOffset = sql
|
|
107
|
+
|
|
108
|
+
// add the limit and offset for pagination
|
|
109
|
+
sql += ' ' + this.offsetText() + ';'
|
|
110
|
+
|
|
111
|
+
console.log(sql)
|
|
112
|
+
return {sql, params}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
this.convertTermsToIds = function (terms) {
|
|
116
|
+
return terms.filter(t => this.lookUpId(t))
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
this.labelSQL = function (){
|
|
120
|
+
return "select entity, label from labels"
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
this.countSQL = function (sql) {
|
|
124
|
+
sql = `select count(*) from (${sql})`
|
|
125
|
+
return sql
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
this.flatmapQuery = function (sql, params = [] ) {
|
|
130
|
+
const data = { sql, params }
|
|
131
|
+
return fetch(`${this.flatmapApi}knowledge/query/`, {
|
|
132
|
+
method: 'POST',
|
|
133
|
+
headers: {
|
|
134
|
+
'Content-Type': 'application/json',
|
|
135
|
+
},
|
|
136
|
+
body: JSON.stringify(data),
|
|
137
|
+
})
|
|
138
|
+
.then((response) => response.json())
|
|
139
|
+
.catch((error) => {
|
|
140
|
+
console.error('Error:', error)
|
|
141
|
+
})
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
this.processFilters = function (filters) {
|
|
145
|
+
let featureFacets = []
|
|
146
|
+
filters.forEach((f) => {
|
|
147
|
+
if (f.facet !== 'Show all' && f.facet !== 'PMR')
|
|
148
|
+
featureFacets.push(f.facet)
|
|
149
|
+
})
|
|
150
|
+
return featureFacets
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
this.pmrSearch = function (filters=[], search='') {
|
|
156
|
+
let features = this.processFilters(filters)
|
|
157
|
+
let featureIds = this.convertTermsToIds(features)
|
|
158
|
+
return new Promise((resolve, reject) => {
|
|
159
|
+
const {sql, params} = this.pmrSQL(featureIds, search)
|
|
160
|
+
this.flatmapQuery(sql, params)
|
|
161
|
+
.then(data => {
|
|
162
|
+
const pd = this.processPMRData(data, featureIds)
|
|
163
|
+
this.setAvailableFeatures(pd)
|
|
164
|
+
|
|
165
|
+
// get the number of hits for pagination
|
|
166
|
+
this.flatmapQuery(this.countSQL(this.sqlPreOffset), params).then(data => {
|
|
167
|
+
this.numberOfHits = data.values[0][0]
|
|
168
|
+
resolve(pd);
|
|
169
|
+
})
|
|
170
|
+
})
|
|
171
|
+
.catch(reject);
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// setAvailableFeatures returns the available features in the flatmap for filtering
|
|
176
|
+
// pd is the processed data from the flatmap
|
|
177
|
+
this.setAvailableFeatures = function (pd) {
|
|
178
|
+
pd.forEach((d) => {
|
|
179
|
+
Object.keys(d).forEach((key) => {
|
|
180
|
+
if (!this.features.includes(key)) {
|
|
181
|
+
this.features.push(key)
|
|
182
|
+
}
|
|
183
|
+
})
|
|
184
|
+
})
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
this.processPMRData = function (data, featureIds=[]) {
|
|
189
|
+
// Convert the flatmap data into an array of objects
|
|
190
|
+
let dataObj = transformKeyValueArrayToObject(data)
|
|
191
|
+
console.log(dataObj)
|
|
192
|
+
// Only use the results with metadata
|
|
193
|
+
let metadataResults = dataObj.filter(d => d.metadata)
|
|
194
|
+
let metadataOnly = metadataResults.map(d => {
|
|
195
|
+
let md = JSON.parse(d.metadata)
|
|
196
|
+
md.dataSource = 'PMR'
|
|
197
|
+
return md
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
// If there are featureIds, filter the results
|
|
201
|
+
if (featureIds.length > 0) {
|
|
202
|
+
metadataOnly = metadataOnly.filter(d => featureIds.includes(d.term))
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Remove duplicates
|
|
206
|
+
let uniqueResults = removeDuplicates(metadataOnly)
|
|
207
|
+
return uniqueResults
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
this.createLookup = function () {
|
|
211
|
+
this.flatmapQuery(this.labelSQL())
|
|
212
|
+
.then(data => {
|
|
213
|
+
data.values.forEach(d => {
|
|
214
|
+
if (d[1] && (typeof d[1] === 'string' || d[1] instanceof String)) {
|
|
215
|
+
this.lookup[d[1].toLowerCase()] = d[0]
|
|
216
|
+
}
|
|
217
|
+
})
|
|
218
|
+
})
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
this.lookUpId = function (label) {
|
|
222
|
+
return this.lookup[label.toLowerCase()]
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export default FlatmapQueries
|