@abi-software/map-side-bar 2.11.3 → 2.11.4-acupoints.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 +10235 -9570
- package/dist/map-side-bar.umd.cjs +63 -63
- package/dist/style.css +1 -1
- package/package.json +2 -2
- package/src/App.vue +24 -1
- package/src/acupoints.js +49 -0
- package/src/components/AcupointsCard.vue +212 -0
- package/src/components/AcupointsInfoSearch.vue +389 -0
- package/src/components/ConnectivityExplorer.vue +104 -8
- package/src/components/SideBar.vue +46 -3
- package/src/components.d.ts +5 -0
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div v-if="entry" class="main">
|
|
3
|
+
<div class="header">
|
|
4
|
+
<el-row>
|
|
5
|
+
<el-input
|
|
6
|
+
class="search-input"
|
|
7
|
+
placeholder="Search"
|
|
8
|
+
v-model="searchInput"
|
|
9
|
+
@keyup="search(searchInput)"
|
|
10
|
+
clearable
|
|
11
|
+
@clear="clearSearchClicked"
|
|
12
|
+
></el-input>
|
|
13
|
+
<el-button
|
|
14
|
+
v-show="false"
|
|
15
|
+
type="primary"
|
|
16
|
+
class="button"
|
|
17
|
+
@click="search(searchInput)"
|
|
18
|
+
size="large"
|
|
19
|
+
>
|
|
20
|
+
Search
|
|
21
|
+
</el-button>
|
|
22
|
+
</el-row>
|
|
23
|
+
<el-row>
|
|
24
|
+
<span class="filterText">
|
|
25
|
+
Display:
|
|
26
|
+
</span>
|
|
27
|
+
<el-radio-group v-model="currentFilter" size="small" class="acuRadioGroup">
|
|
28
|
+
<el-radio-button
|
|
29
|
+
v-for="(value, key) in filters"
|
|
30
|
+
:key="key"
|
|
31
|
+
:label="key"
|
|
32
|
+
:value="value"
|
|
33
|
+
/>
|
|
34
|
+
</el-radio-group>
|
|
35
|
+
</el-row>
|
|
36
|
+
</div>
|
|
37
|
+
<div class="content scrollbar" ref="content">
|
|
38
|
+
<div v-if="paginatedResults.length > 0" v-for="result in paginatedResults" :key="result.Acupoint" class="step-item">
|
|
39
|
+
<AcupointsCard
|
|
40
|
+
class="dataset-card"
|
|
41
|
+
:entry="result"
|
|
42
|
+
@mouseenter="hoverChanged(result)"
|
|
43
|
+
@mouseleave="hoverChanged(undefined)"
|
|
44
|
+
/>
|
|
45
|
+
</div>
|
|
46
|
+
<div v-else class="error-feedback">
|
|
47
|
+
No results found - Please change your search / filter criteria.
|
|
48
|
+
</div>
|
|
49
|
+
<el-pagination
|
|
50
|
+
class="pagination"
|
|
51
|
+
v-model:current-page="page"
|
|
52
|
+
hide-on-single-page
|
|
53
|
+
large
|
|
54
|
+
layout="prev, pager, next"
|
|
55
|
+
:page-size="numberPerPage"
|
|
56
|
+
:total="numberOfHits"
|
|
57
|
+
@current-change="pageChange"
|
|
58
|
+
></el-pagination>
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
</template>
|
|
62
|
+
|
|
63
|
+
<script>
|
|
64
|
+
/* eslint-disable no-alert, no-console */
|
|
65
|
+
import {
|
|
66
|
+
ElButton as Button,
|
|
67
|
+
ElCard as Card,
|
|
68
|
+
ElRadioButton as RadioButton,
|
|
69
|
+
ElRadioGroup as RadioGroup,
|
|
70
|
+
ElDrawer as Drawer,
|
|
71
|
+
ElIcon as Icon,
|
|
72
|
+
ElInput as Input,
|
|
73
|
+
ElPagination as Pagination,
|
|
74
|
+
ElRow as Row,
|
|
75
|
+
} from 'element-plus'
|
|
76
|
+
import AcupointsCard from './AcupointsCard.vue'
|
|
77
|
+
|
|
78
|
+
export default {
|
|
79
|
+
components: {
|
|
80
|
+
AcupointsCard,
|
|
81
|
+
Button,
|
|
82
|
+
Card,
|
|
83
|
+
RadioButton,
|
|
84
|
+
RadioGroup,
|
|
85
|
+
Drawer,
|
|
86
|
+
Icon,
|
|
87
|
+
Input,
|
|
88
|
+
Pagination,
|
|
89
|
+
Row
|
|
90
|
+
},
|
|
91
|
+
name: 'AcupointsInfoSearch',
|
|
92
|
+
props: {
|
|
93
|
+
entry: {
|
|
94
|
+
type: Object,
|
|
95
|
+
default: () => {},
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
data: function () {
|
|
99
|
+
return {
|
|
100
|
+
filters: {
|
|
101
|
+
"Curated Only": "Curated",
|
|
102
|
+
"Uncurated Only": "Uncurated",
|
|
103
|
+
"Both": "Both"
|
|
104
|
+
},
|
|
105
|
+
currentFilter: "Both",
|
|
106
|
+
previousFilter: undefined,
|
|
107
|
+
previousInput: undefined,
|
|
108
|
+
results: [],
|
|
109
|
+
paginatedResults: [],
|
|
110
|
+
searchInput: "",
|
|
111
|
+
lastSearch: "",
|
|
112
|
+
numberOfHits: 0,
|
|
113
|
+
numberPerPage: 10,
|
|
114
|
+
page: 1,
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
watch: {
|
|
118
|
+
currentFilter: {
|
|
119
|
+
handler: function () {
|
|
120
|
+
this.search(
|
|
121
|
+
this.searchInput,
|
|
122
|
+
this.numberPerPage,
|
|
123
|
+
this.page
|
|
124
|
+
)
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
entry: {
|
|
128
|
+
handler: function () {
|
|
129
|
+
this.search(
|
|
130
|
+
this.searchInput,
|
|
131
|
+
this.numberPerPage,
|
|
132
|
+
this.page
|
|
133
|
+
)
|
|
134
|
+
},
|
|
135
|
+
immediate: true,
|
|
136
|
+
deep: true,
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
methods: {
|
|
140
|
+
hoverChanged: function (data) {
|
|
141
|
+
this.$emit('hover-changed', data)
|
|
142
|
+
},
|
|
143
|
+
resetSearch: function () {
|
|
144
|
+
this.numberOfHits = 0
|
|
145
|
+
this.search(this.searchInput)
|
|
146
|
+
},
|
|
147
|
+
clearSearchClicked: function () {
|
|
148
|
+
this.searchInput = '';
|
|
149
|
+
this.search("");
|
|
150
|
+
},
|
|
151
|
+
search: function(input) {
|
|
152
|
+
this.results = []
|
|
153
|
+
if ((input !== this.previousInput) ||
|
|
154
|
+
(this.currentFilter !== this.previousFilter)) {
|
|
155
|
+
this.previousFilter = this.currentFilter
|
|
156
|
+
this.previousInput = this.input
|
|
157
|
+
let filteredList = Object.values(this.entry)
|
|
158
|
+
if (this.currentFilter !== "Both") {
|
|
159
|
+
const curated = this.currentFilter === "Curated" ? true : false
|
|
160
|
+
filteredList = filteredList.filter(
|
|
161
|
+
item => (item.Curated ? true : false) === curated)
|
|
162
|
+
}
|
|
163
|
+
if (input === "") {
|
|
164
|
+
this.results = filteredList
|
|
165
|
+
} else {
|
|
166
|
+
const lowerCase = input.toLowerCase()
|
|
167
|
+
for (const value of filteredList) {
|
|
168
|
+
const searchFields = [
|
|
169
|
+
value["Acupoint"],
|
|
170
|
+
value["Synonym"],
|
|
171
|
+
value["Chinese Name"],
|
|
172
|
+
value["English Name"],
|
|
173
|
+
value["Reference"],
|
|
174
|
+
value["Indications"],
|
|
175
|
+
value["Acupuncture Method"],
|
|
176
|
+
value["Vasculature"],
|
|
177
|
+
value["Innervation"],
|
|
178
|
+
value["Note"],
|
|
179
|
+
];
|
|
180
|
+
const allstrings = searchFields.join();
|
|
181
|
+
const myJSON = allstrings.toLowerCase();
|
|
182
|
+
if (myJSON.includes(lowerCase)) {
|
|
183
|
+
this.results.push(value)
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const start = this.numberPerPage * (this.page - 1)
|
|
189
|
+
this.paginatedResults = this.results.slice(start, start + this.numberPerPage)
|
|
190
|
+
this.numberOfHits = this.results.length
|
|
191
|
+
this.searchInput = input
|
|
192
|
+
this.lastSearch = input
|
|
193
|
+
},
|
|
194
|
+
numberPerPageUpdate: function (val) {
|
|
195
|
+
this.numberPerPage = val
|
|
196
|
+
this.pageChange(1)
|
|
197
|
+
},
|
|
198
|
+
pageChange: function (page) {
|
|
199
|
+
this.page = page
|
|
200
|
+
this.search( this.searchInput)
|
|
201
|
+
},
|
|
202
|
+
scrollToTop: function () {
|
|
203
|
+
if (this.$refs.content) {
|
|
204
|
+
this.$refs.content.scroll({ top: 0, behavior: 'smooth' })
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
resetPageNavigation: function () {
|
|
208
|
+
this.page = 1
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
}
|
|
212
|
+
</script>
|
|
213
|
+
|
|
214
|
+
<style lang="scss" scoped>
|
|
215
|
+
|
|
216
|
+
.acuRadioGroup {
|
|
217
|
+
padding-top: 8px;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.dataset-card {
|
|
221
|
+
position: relative;
|
|
222
|
+
|
|
223
|
+
&::before {
|
|
224
|
+
content: "";
|
|
225
|
+
display: block;
|
|
226
|
+
width: calc(100% - 15px);
|
|
227
|
+
height: 100%;
|
|
228
|
+
position: absolute;
|
|
229
|
+
top: 7px;
|
|
230
|
+
left: 7px;
|
|
231
|
+
border-style: solid;
|
|
232
|
+
border-radius: 5px;
|
|
233
|
+
border-color: transparent;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
&:hover {
|
|
237
|
+
&::before {
|
|
238
|
+
border-color: var(--el-color-primary);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.main {
|
|
244
|
+
font-size: 14px;
|
|
245
|
+
text-align: left;
|
|
246
|
+
line-height: 1.5em;
|
|
247
|
+
font-family: Asap, sans-serif, Helvetica;
|
|
248
|
+
font-weight: 400;
|
|
249
|
+
/* outline: thin red solid; */
|
|
250
|
+
overflow-y: auto;
|
|
251
|
+
scrollbar-width: thin;
|
|
252
|
+
min-width: 16rem;
|
|
253
|
+
background-color: #f7faff;
|
|
254
|
+
height: 100%;
|
|
255
|
+
border-left: 1px solid var(--el-border-color);
|
|
256
|
+
border-top: 1px solid var(--el-border-color);
|
|
257
|
+
display: flex;
|
|
258
|
+
flex-direction: column;
|
|
259
|
+
gap: 1rem;
|
|
260
|
+
padding: 1rem;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.step-item {
|
|
264
|
+
font-size: 14px;
|
|
265
|
+
margin-bottom: 18px;
|
|
266
|
+
text-align: left;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.search-input {
|
|
270
|
+
width: 298px !important;
|
|
271
|
+
height: 40px;
|
|
272
|
+
padding-right: 14px;
|
|
273
|
+
|
|
274
|
+
:deep(.el-input__inner) {
|
|
275
|
+
font-family: inherit;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.header {
|
|
280
|
+
.el-button {
|
|
281
|
+
font-family: inherit;
|
|
282
|
+
|
|
283
|
+
&:hover,
|
|
284
|
+
&:focus {
|
|
285
|
+
background: $app-primary-color;
|
|
286
|
+
box-shadow: -3px 2px 4px #00000040;
|
|
287
|
+
color: #fff;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.pagination {
|
|
293
|
+
padding-bottom: 16px;
|
|
294
|
+
background-color: white;
|
|
295
|
+
padding-left: 95px;
|
|
296
|
+
font-weight: bold;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.pagination :deep(button) {
|
|
300
|
+
background-color: white !important;
|
|
301
|
+
}
|
|
302
|
+
.pagination :deep(li) {
|
|
303
|
+
background-color: white !important;
|
|
304
|
+
}
|
|
305
|
+
.pagination :deep(li.is-active) {
|
|
306
|
+
color: $app-primary-color;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.error-feedback {
|
|
310
|
+
font-family: Asap;
|
|
311
|
+
font-size: 14px;
|
|
312
|
+
font-style: italic;
|
|
313
|
+
padding-top: 15px;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
.content-card :deep(.el-card__header) {
|
|
317
|
+
background-color: #292b66;
|
|
318
|
+
padding: 1rem;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.content-card :deep(.el-card__body) {
|
|
322
|
+
background-color: #f7faff;
|
|
323
|
+
overflow-y: hidden;
|
|
324
|
+
padding: 1rem;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
.content {
|
|
328
|
+
// width: 515px;
|
|
329
|
+
flex: 1 1 auto;
|
|
330
|
+
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.06);
|
|
331
|
+
border: solid 1px #e4e7ed;
|
|
332
|
+
background-color: #ffffff;
|
|
333
|
+
overflow-y: scroll;
|
|
334
|
+
scrollbar-width: thin;
|
|
335
|
+
border-radius: var(--el-border-radius-base);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
.content :deep(.el-loading-spinner .path) {
|
|
339
|
+
stroke: $app-primary-color;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
.content :deep(.step-item:first-child .seperator-path) {
|
|
343
|
+
display: none;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
.content :deep(.step-item:not(:first-child) .seperator-path) {
|
|
347
|
+
width: 455px;
|
|
348
|
+
height: 0px;
|
|
349
|
+
border: solid 1px #e4e7ed;
|
|
350
|
+
background-color: #e4e7ed;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
.filterText {
|
|
354
|
+
margin-top:8px;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
.scrollbar::-webkit-scrollbar-track {
|
|
358
|
+
border-radius: 10px;
|
|
359
|
+
background-color: #f5f5f5;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
.scrollbar::-webkit-scrollbar {
|
|
363
|
+
width: 12px;
|
|
364
|
+
right: -12px;
|
|
365
|
+
background-color: #f5f5f5;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
.scrollbar::-webkit-scrollbar-thumb {
|
|
369
|
+
border-radius: 4px;
|
|
370
|
+
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.06);
|
|
371
|
+
background-color: #979797;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
:deep(.el-input__suffix) {
|
|
375
|
+
padding-right: 0px;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
:deep(.my-drawer) {
|
|
379
|
+
background: rgba(0, 0, 0, 0);
|
|
380
|
+
box-shadow: none;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
.error-feedback {
|
|
384
|
+
font-family: Asap;
|
|
385
|
+
font-size: 14px;
|
|
386
|
+
font-style: italic;
|
|
387
|
+
padding-top: 15px;
|
|
388
|
+
}
|
|
389
|
+
</style>
|
|
@@ -3,14 +3,56 @@
|
|
|
3
3
|
<MapSvgSpriteColor />
|
|
4
4
|
<template #header>
|
|
5
5
|
<div class="header">
|
|
6
|
-
<
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
<div class="search-input-container" :class="{'is-focus': inputFocus}">
|
|
7
|
+
<el-input
|
|
8
|
+
class="search-input"
|
|
9
|
+
placeholder="Search"
|
|
10
|
+
v-model="searchInput"
|
|
11
|
+
@focus="onInputFocus"
|
|
12
|
+
@blur="onInputBlur"
|
|
13
|
+
@input="onInputChange"
|
|
14
|
+
@keyup="searchEvent"
|
|
15
|
+
clearable
|
|
16
|
+
@clear="clearSearchClicked"
|
|
17
|
+
></el-input>
|
|
18
|
+
<el-popover
|
|
19
|
+
width="350"
|
|
20
|
+
trigger="hover"
|
|
21
|
+
popper-class="filter-help-popover"
|
|
22
|
+
>
|
|
23
|
+
<template #reference>
|
|
24
|
+
<MapSvgIcon icon="help" class="help" />
|
|
25
|
+
</template>
|
|
26
|
+
<div>
|
|
27
|
+
<strong>Search rules:</strong>
|
|
28
|
+
<ul>
|
|
29
|
+
<li>
|
|
30
|
+
<strong>Partial Matching:</strong> You don't need to type the full word or ID.
|
|
31
|
+
The search will find items that contain your search term.
|
|
32
|
+
</li>
|
|
33
|
+
<li>
|
|
34
|
+
<strong>Multiple Terms:</strong> Separate terms with a comma (<code>,</code>).
|
|
35
|
+
This will find pathways that match any of the terms (an "OR" search).
|
|
36
|
+
</li>
|
|
37
|
+
</ul>
|
|
38
|
+
<br/>
|
|
39
|
+
<strong>Examples:</strong>
|
|
40
|
+
<ul>
|
|
41
|
+
<li>
|
|
42
|
+
<strong>To find by partial ID:</strong>
|
|
43
|
+
Searching for <code>kidney/132</code> will match the full <strong>Pathway ID</strong> <code>ilxtr:sparc-nlp/kidney/132</code>
|
|
44
|
+
</li>
|
|
45
|
+
<li>
|
|
46
|
+
<strong>To find by keyword:</strong>
|
|
47
|
+
Searching for (<code>vagus nerve</code>) will match <strong>pathways</strong> that have <code>vagus nerve</code> in their title OR are linked to a related component (like UBERON:0001759).
|
|
48
|
+
</li>
|
|
49
|
+
<li>
|
|
50
|
+
<strong>To find by multiple terms:</strong>
|
|
51
|
+
Searching for <code>kidney</code>, <code>vagus nerve</code> will find pathways that are related to either <code>kidney</code> OR <code>vagus nerve</code>.</li>
|
|
52
|
+
</ul>
|
|
53
|
+
</div>
|
|
54
|
+
</el-popover>
|
|
55
|
+
</div>
|
|
14
56
|
<el-button
|
|
15
57
|
type="primary"
|
|
16
58
|
class="button"
|
|
@@ -216,6 +258,7 @@ export default {
|
|
|
216
258
|
expanded: "",
|
|
217
259
|
filterVisibility: true,
|
|
218
260
|
expandedData: null,
|
|
261
|
+
inputFocus: false,
|
|
219
262
|
};
|
|
220
263
|
},
|
|
221
264
|
computed: {
|
|
@@ -250,6 +293,7 @@ export default {
|
|
|
250
293
|
this.$refs.filtersRef.checkShowAllBoxes();
|
|
251
294
|
this.searchInput = '';
|
|
252
295
|
this.filter = [];
|
|
296
|
+
this.updateInputFocus();
|
|
253
297
|
}
|
|
254
298
|
}
|
|
255
299
|
},
|
|
@@ -306,6 +350,7 @@ export default {
|
|
|
306
350
|
onConnectivityClicked: function (data) {
|
|
307
351
|
this.searchInput = data.query;
|
|
308
352
|
this.searchAndFilterUpdate();
|
|
353
|
+
this.updateInputFocus();
|
|
309
354
|
},
|
|
310
355
|
collapseChange:function (data) {
|
|
311
356
|
this.expanded = this.expanded === data.id ? "" : data.id;
|
|
@@ -380,6 +425,7 @@ export default {
|
|
|
380
425
|
},
|
|
381
426
|
openSearch: function (filter, search = "") {
|
|
382
427
|
this.searchInput = search;
|
|
428
|
+
this.updateInputFocus();
|
|
383
429
|
this.resetPageNavigation();
|
|
384
430
|
//Proceed normally if cascader is ready
|
|
385
431
|
if (this.cascaderIsReady) {
|
|
@@ -468,13 +514,27 @@ export default {
|
|
|
468
514
|
clearSearchClicked: function () {
|
|
469
515
|
this.searchInput = "";
|
|
470
516
|
this.searchAndFilterUpdate();
|
|
517
|
+
this.updateInputFocus();
|
|
471
518
|
},
|
|
472
519
|
searchEvent: function (event = false) {
|
|
473
520
|
if (event.keyCode === 13 || event instanceof MouseEvent) {
|
|
474
521
|
this.searchInput = this.searchInput.trim();
|
|
475
522
|
this.searchAndFilterUpdate();
|
|
523
|
+
this.updateInputFocus();
|
|
476
524
|
}
|
|
477
525
|
},
|
|
526
|
+
updateInputFocus: function () {
|
|
527
|
+
this.inputFocus = this.searchInput ? true : false;
|
|
528
|
+
},
|
|
529
|
+
onInputFocus: function () {
|
|
530
|
+
this.updateInputFocus();
|
|
531
|
+
},
|
|
532
|
+
onInputBlur: function () {
|
|
533
|
+
this.updateInputFocus();
|
|
534
|
+
},
|
|
535
|
+
onInputChange: function () {
|
|
536
|
+
this.updateInputFocus();
|
|
537
|
+
},
|
|
478
538
|
filterUpdate: function (filters) {
|
|
479
539
|
this.filter = [...filters];
|
|
480
540
|
this.searchAndFilterUpdate();
|
|
@@ -554,6 +614,7 @@ export default {
|
|
|
554
614
|
this.searchInput = item.search;
|
|
555
615
|
this.filter = item.filters;
|
|
556
616
|
this.openSearch([...item.filters], item.search);
|
|
617
|
+
this.updateInputFocus();
|
|
557
618
|
},
|
|
558
619
|
onConnectivityInfoLoaded: function (result) {
|
|
559
620
|
const stepItemRef = this.$refs['stepItem-' + result.id];
|
|
@@ -650,6 +711,24 @@ export default {
|
|
|
650
711
|
}
|
|
651
712
|
}
|
|
652
713
|
|
|
714
|
+
.search-input-container {
|
|
715
|
+
position: relative;
|
|
716
|
+
display: flex;
|
|
717
|
+
align-items: center;
|
|
718
|
+
|
|
719
|
+
.map-icon {
|
|
720
|
+
position: absolute;
|
|
721
|
+
right: 18px;
|
|
722
|
+
color: $app-primary-color !important;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
&.is-focus {
|
|
726
|
+
.map-icon {
|
|
727
|
+
display: none;
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
|
|
653
732
|
.header {
|
|
654
733
|
display: flex;
|
|
655
734
|
align-items: center;
|
|
@@ -802,6 +881,19 @@ export default {
|
|
|
802
881
|
font-size: 12px !important;
|
|
803
882
|
line-height: 18px !important;
|
|
804
883
|
|
|
884
|
+
> div {
|
|
885
|
+
word-break: break-word;
|
|
886
|
+
text-align: initial;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
ul {
|
|
890
|
+
padding-left: 1.5rem;
|
|
891
|
+
|
|
892
|
+
> li + li {
|
|
893
|
+
margin-top: 0.5rem;
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
|
|
805
897
|
.el-popper__arrow::before {
|
|
806
898
|
background: #f3ecf6 !important;
|
|
807
899
|
border-color: $app-primary-color !important;
|
|
@@ -811,5 +903,9 @@ export default {
|
|
|
811
903
|
border-bottom-color: transparent !important;
|
|
812
904
|
border-right-color: transparent !important;
|
|
813
905
|
}
|
|
906
|
+
|
|
907
|
+
code {
|
|
908
|
+
font-size: 90%;
|
|
909
|
+
}
|
|
814
910
|
}
|
|
815
911
|
</style>
|
|
@@ -64,6 +64,14 @@
|
|
|
64
64
|
@connectivity-item-close="onConnectivityItemClose"
|
|
65
65
|
/>
|
|
66
66
|
</template>
|
|
67
|
+
<template v-else-if="tab.type === 'acupoints' && acupointsInfoList">
|
|
68
|
+
<acupoints-info-search
|
|
69
|
+
:ref="'acupointsTab_' + tab.id"
|
|
70
|
+
:entry="acupointsInfoList"
|
|
71
|
+
@on-acupoints-click="acupointClicked"
|
|
72
|
+
v-show="tab.id === activeTabId"
|
|
73
|
+
/>
|
|
74
|
+
</template>
|
|
67
75
|
<template v-else>
|
|
68
76
|
<DatasetExplorer
|
|
69
77
|
class="sidebar-content-container"
|
|
@@ -92,6 +100,7 @@ import { ElDrawer as Drawer, ElIcon as Icon } from 'element-plus'
|
|
|
92
100
|
import DatasetExplorer from './DatasetExplorer.vue'
|
|
93
101
|
import EventBus from './EventBus.js'
|
|
94
102
|
import Tabs from './Tabs.vue'
|
|
103
|
+
import AcupointsInfoSearch from './AcupointsInfoSearch.vue'
|
|
95
104
|
import AnnotationTool from './AnnotationTool.vue'
|
|
96
105
|
import ConnectivityExplorer from './ConnectivityExplorer.vue'
|
|
97
106
|
import { removeShowAllFacets } from '../algolia/utils.js'
|
|
@@ -151,6 +160,13 @@ export default {
|
|
|
151
160
|
type: Array,
|
|
152
161
|
default: [],
|
|
153
162
|
},
|
|
163
|
+
/**
|
|
164
|
+
* The acupoints info to show in sidebar.
|
|
165
|
+
*/
|
|
166
|
+
acupointsInfoList: {
|
|
167
|
+
type: Object,
|
|
168
|
+
default: null,
|
|
169
|
+
},
|
|
154
170
|
/**
|
|
155
171
|
* The annotation data to show in sidebar.
|
|
156
172
|
*/
|
|
@@ -204,6 +220,13 @@ export default {
|
|
|
204
220
|
}
|
|
205
221
|
},
|
|
206
222
|
methods: {
|
|
223
|
+
/**
|
|
224
|
+
* This event is emitted with a mouse click on acupoint card
|
|
225
|
+
* @arg data
|
|
226
|
+
*/
|
|
227
|
+
acupointClicked: function (data) {
|
|
228
|
+
this.$emit('acupoints-clicked', data)
|
|
229
|
+
},
|
|
207
230
|
onConnectivityCollapseChange: function (data) {
|
|
208
231
|
this.$emit('connectivity-collapse-change', data)
|
|
209
232
|
},
|
|
@@ -295,9 +318,6 @@ export default {
|
|
|
295
318
|
datasetExplorerTabRef.openSearch(facets, query);
|
|
296
319
|
})
|
|
297
320
|
},
|
|
298
|
-
/**
|
|
299
|
-
* Get the ref id of the tab by id and type.
|
|
300
|
-
*/
|
|
301
321
|
getTabRef: function (id, type, switchTab = false) {
|
|
302
322
|
const matchedTab = this.tabEntries.filter((tabEntry) => {
|
|
303
323
|
return (id === undefined || tabEntry.id === id) &&
|
|
@@ -407,6 +427,14 @@ export default {
|
|
|
407
427
|
updateConnectivityError: function (errorInfo) {
|
|
408
428
|
EventBus.emit('connectivity-error', errorInfo);
|
|
409
429
|
},
|
|
430
|
+
openAcupointsSearch: function (term) {
|
|
431
|
+
this.drawerOpen = true
|
|
432
|
+
// Because refs are in v-for, nextTick is needed here
|
|
433
|
+
this.$nextTick(() => {
|
|
434
|
+
const tabRef = this.getTabRef(undefined, 'acupoints', true);
|
|
435
|
+
tabRef.search(term);
|
|
436
|
+
})
|
|
437
|
+
},
|
|
410
438
|
/**
|
|
411
439
|
* Store available anatomy facets data for connectivity list component
|
|
412
440
|
*/
|
|
@@ -503,6 +531,11 @@ export default {
|
|
|
503
531
|
// This should respect the information provided by the property
|
|
504
532
|
tabEntries: function () {
|
|
505
533
|
return this.tabs.filter((tab) =>
|
|
534
|
+
(tab.type === "acupoints" &&
|
|
535
|
+
(
|
|
536
|
+
this.acupointsInfoList &&
|
|
537
|
+
Object.keys(this.acupointsInfoList).length > 0
|
|
538
|
+
)) ||
|
|
506
539
|
tab.type === "datasetExplorer" ||
|
|
507
540
|
tab.type === "connectivityExplorer" ||
|
|
508
541
|
(
|
|
@@ -565,6 +598,16 @@ export default {
|
|
|
565
598
|
this.$emit('connectivity-source-change', payLoad);
|
|
566
599
|
})
|
|
567
600
|
|
|
601
|
+
// Emit acupoints clicked event
|
|
602
|
+
EventBus.on('acupoints-clicked', (payLoad) => {
|
|
603
|
+
this.$emit('acupoints-clicked', payLoad);
|
|
604
|
+
})
|
|
605
|
+
|
|
606
|
+
// Emit acupoints hovered event
|
|
607
|
+
EventBus.on('acupoints-hovered', (payLoad) => {
|
|
608
|
+
this.$emit('acupoints-hovered', payLoad);
|
|
609
|
+
})
|
|
610
|
+
|
|
568
611
|
// Get available anatomy facets for the connectivity info
|
|
569
612
|
EventBus.on('available-facets', (payLoad) => {
|
|
570
613
|
this.availableAnatomyFacets = payLoad.find((facet) => facet.label === 'Anatomical Structure').children
|
package/src/components.d.ts
CHANGED
|
@@ -7,6 +7,8 @@ export {}
|
|
|
7
7
|
|
|
8
8
|
declare module 'vue' {
|
|
9
9
|
export interface GlobalComponents {
|
|
10
|
+
AcupointsCard: typeof import('./components/AcupointsCard.vue')['default']
|
|
11
|
+
AcupointsInfoSearch: typeof import('./components/AcupointsInfoSearch.vue')['default']
|
|
10
12
|
AnnotationTool: typeof import('./components/AnnotationTool.vue')['default']
|
|
11
13
|
BadgesGroup: typeof import('./components/BadgesGroup.vue')['default']
|
|
12
14
|
ConnectivityCard: typeof import('./components/ConnectivityCard.vue')['default']
|
|
@@ -19,6 +21,8 @@ declare module 'vue' {
|
|
|
19
21
|
ElCascader: typeof import('element-plus/es')['ElCascader']
|
|
20
22
|
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
|
|
21
23
|
ElCol: typeof import('element-plus/es')['ElCol']
|
|
24
|
+
ElCollapse: typeof import('element-plus/es')['ElCollapse']
|
|
25
|
+
ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
|
|
22
26
|
ElDrawer: typeof import('element-plus/es')['ElDrawer']
|
|
23
27
|
ElDropdown: typeof import('element-plus/es')['ElDropdown']
|
|
24
28
|
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
|
|
@@ -38,6 +42,7 @@ declare module 'vue' {
|
|
|
38
42
|
ElPagination: typeof import('element-plus/es')['ElPagination']
|
|
39
43
|
ElPopover: typeof import('element-plus/es')['ElPopover']
|
|
40
44
|
ElRadio: typeof import('element-plus/es')['ElRadio']
|
|
45
|
+
ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
|
|
41
46
|
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
|
|
42
47
|
ElRow: typeof import('element-plus/es')['ElRow']
|
|
43
48
|
ElSelect: typeof import('element-plus/es')['ElSelect']
|