@abi-software/flatmapvuer 1.2.0 → 1.3.1-beta.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/flatmapvuer.js +25060 -28716
- package/dist/flatmapvuer.umd.cjs +164 -164
- package/dist/style.css +1 -1
- package/package.json +3 -2
- package/src/App.vue +5 -6
- package/src/components/FlatmapVuer.vue +233 -103
- package/src/components/MultiFlatmapVuer.vue +17 -1
- package/src/components/index.js +3 -5
- package/src/components.d.ts +0 -18
- package/src/services/flatmapQueries.js +6 -5
- package/vite.config.js +3 -2
- package/src/components/AnnotationTool.vue +0 -501
- package/src/components/ConnectionDialog.vue +0 -134
- package/src/components/DrawTool.vue +0 -502
- package/src/components/ExternalResourceCard.vue +0 -109
- package/src/components/HelpModeDialog.vue +0 -360
- package/src/components/ProvenancePopup.vue +0 -530
- package/src/components/Tooltip.vue +0 -50
- package/src/components/TreeControls.vue +0 -236
|
@@ -56,6 +56,9 @@
|
|
|
56
56
|
@resource-selected="resourceSelected"
|
|
57
57
|
@ready="FlatmapReady"
|
|
58
58
|
@pan-zoom-callback="panZoomCallback"
|
|
59
|
+
:connectivityInfoSidebar="connectivityInfoSidebar"
|
|
60
|
+
@connectivity-info-open="onConnectivityInfoOpen"
|
|
61
|
+
@connectivity-info-close="onConnectivityInfoClose"
|
|
59
62
|
@open-map="
|
|
60
63
|
/**
|
|
61
64
|
* This event is emitted when the user chooses a different map option
|
|
@@ -261,6 +264,12 @@ export default {
|
|
|
261
264
|
*/
|
|
262
265
|
this.$emit('pan-zoom-callback', payload)
|
|
263
266
|
},
|
|
267
|
+
onConnectivityInfoClose: function () {
|
|
268
|
+
this.$emit('connectivity-info-close');
|
|
269
|
+
},
|
|
270
|
+
onConnectivityInfoOpen: function (entryData) {
|
|
271
|
+
this.$emit('connectivity-info-open', entryData);
|
|
272
|
+
},
|
|
264
273
|
onSelectionsDataChanged: function (data) {
|
|
265
274
|
this.$emit('pathway-selection-changed', data);
|
|
266
275
|
},
|
|
@@ -697,7 +706,14 @@ export default {
|
|
|
697
706
|
disableUI: {
|
|
698
707
|
type: Boolean,
|
|
699
708
|
default: false,
|
|
700
|
-
}
|
|
709
|
+
},
|
|
710
|
+
/**
|
|
711
|
+
* The option to show connectivity information in sidebar
|
|
712
|
+
*/
|
|
713
|
+
connectivityInfoSidebar: {
|
|
714
|
+
type: Boolean,
|
|
715
|
+
default: false,
|
|
716
|
+
},
|
|
701
717
|
},
|
|
702
718
|
data: function () {
|
|
703
719
|
return {
|
package/src/components/index.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
// The Vue build version to load with the `import` command
|
|
2
2
|
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
|
|
3
|
-
import FlatmapVuer from
|
|
4
|
-
import MultiFlatmapVuer from
|
|
5
|
-
import Tooltip from './Tooltip.vue'
|
|
6
|
-
import HelpModeDialog from './HelpModeDialog.vue'
|
|
3
|
+
import FlatmapVuer from "./FlatmapVuer.vue";
|
|
4
|
+
import MultiFlatmapVuer from "./MultiFlatmapVuer.vue";
|
|
7
5
|
|
|
8
|
-
export { FlatmapVuer, MultiFlatmapVuer
|
|
6
|
+
export { FlatmapVuer, MultiFlatmapVuer };
|
package/src/components.d.ts
CHANGED
|
@@ -7,44 +7,26 @@ export {}
|
|
|
7
7
|
|
|
8
8
|
declare module 'vue' {
|
|
9
9
|
export interface GlobalComponents {
|
|
10
|
-
AnnotationTool: typeof import('./components/AnnotationTool.vue')['default']
|
|
11
|
-
ConnectionDialog: typeof import('./components/ConnectionDialog.vue')['default']
|
|
12
|
-
DrawTool: typeof import('./components/DrawTool.vue')['default']
|
|
13
10
|
DynamicLegends: typeof import('./components/legends/DynamicLegends.vue')['default']
|
|
14
11
|
ElButton: typeof import('element-plus/es')['ElButton']
|
|
15
|
-
ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup']
|
|
16
|
-
ElCard: typeof import('element-plus/es')['ElCard']
|
|
17
12
|
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
|
|
18
13
|
ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
|
|
19
14
|
ElCol: typeof import('element-plus/es')['ElCol']
|
|
20
15
|
ElIcon: typeof import('element-plus/es')['ElIcon']
|
|
21
16
|
ElIconArrowDown: typeof import('@element-plus/icons-vue')['ArrowDown']
|
|
22
17
|
ElIconArrowLeft: typeof import('@element-plus/icons-vue')['ArrowLeft']
|
|
23
|
-
ElIconArrowUp: typeof import('@element-plus/icons-vue')['ArrowUp']
|
|
24
|
-
ElIconClose: typeof import('@element-plus/icons-vue')['Close']
|
|
25
|
-
ElIconDelete: typeof import('@element-plus/icons-vue')['Delete']
|
|
26
|
-
ElIconEdit: typeof import('@element-plus/icons-vue')['Edit']
|
|
27
|
-
ElIconFinished: typeof import('@element-plus/icons-vue')['Finished']
|
|
28
18
|
ElIconWarning: typeof import('@element-plus/icons-vue')['Warning']
|
|
29
19
|
ElIconWarningFilled: typeof import('@element-plus/icons-vue')['WarningFilled']
|
|
30
|
-
ElInput: typeof import('element-plus/es')['ElInput']
|
|
31
|
-
ElMain: typeof import('element-plus/es')['ElMain']
|
|
32
20
|
ElOption: typeof import('element-plus/es')['ElOption']
|
|
33
21
|
ElPopover: typeof import('element-plus/es')['ElPopover']
|
|
34
22
|
ElRadio: typeof import('element-plus/es')['ElRadio']
|
|
35
23
|
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
|
|
36
24
|
ElRow: typeof import('element-plus/es')['ElRow']
|
|
37
25
|
ElSelect: typeof import('element-plus/es')['ElSelect']
|
|
38
|
-
ElTree: typeof import('element-plus/es')['ElTree']
|
|
39
|
-
ExternalResourceCard: typeof import('./components/ExternalResourceCard.vue')['default']
|
|
40
26
|
FlatmapVuer: typeof import('./components/FlatmapVuer.vue')['default']
|
|
41
|
-
HelpModeDialog: typeof import('./components/HelpModeDialog.vue')['default']
|
|
42
27
|
MultiFlatmapVuer: typeof import('./components/MultiFlatmapVuer.vue')['default']
|
|
43
|
-
ProvenancePopup: typeof import('./components/ProvenancePopup.vue')['default']
|
|
44
28
|
SelectionsGroup: typeof import('./components/SelectionsGroup.vue')['default']
|
|
45
29
|
SvgLegends: typeof import('./components/legends/SvgLegends.vue')['default']
|
|
46
|
-
Tooltip: typeof import('./components/Tooltip.vue')['default']
|
|
47
|
-
TreeControls: typeof import('./components/TreeControls.vue')['default']
|
|
48
30
|
}
|
|
49
31
|
export interface ComponentCustomProperties {
|
|
50
32
|
vLoading: typeof import('element-plus/es')['ElLoadingDirective']
|
|
@@ -222,7 +222,7 @@ let FlatmapQueries = function () {
|
|
|
222
222
|
this.origins = []
|
|
223
223
|
this.components = []
|
|
224
224
|
if (!keastIds || keastIds.length == 0) return
|
|
225
|
-
|
|
225
|
+
|
|
226
226
|
let prom1 = this.queryForConnectivity(keastIds, signal) // This on returns a promise so dont need 'await'
|
|
227
227
|
let prom2 = await this.pubmedQueryOnIds(eventData)
|
|
228
228
|
let results = await Promise.all([prom1, prom2])
|
|
@@ -281,10 +281,10 @@ let FlatmapQueries = function () {
|
|
|
281
281
|
if (node.length === 1) { // If the node is in the form [id]
|
|
282
282
|
console.error("Server returns a single node", node)
|
|
283
283
|
return node[0]
|
|
284
|
-
} else {
|
|
284
|
+
} else {
|
|
285
285
|
if (node.length === 2 && node[1].length === 0) { // If the node is in the form [id, []]
|
|
286
286
|
return node[0]
|
|
287
|
-
} else {
|
|
287
|
+
} else {
|
|
288
288
|
return false // If the node is in the form [id, [id1, id2]]
|
|
289
289
|
}
|
|
290
290
|
}
|
|
@@ -294,7 +294,7 @@ let FlatmapQueries = function () {
|
|
|
294
294
|
|
|
295
295
|
// Check if the node is a single node or a node with multiple children
|
|
296
296
|
let nodeIsSingle = this.findIfNodeIsSingle(node)
|
|
297
|
-
|
|
297
|
+
|
|
298
298
|
// Case where node is in the form [id]
|
|
299
299
|
if (nodeIsSingle) {
|
|
300
300
|
return lookUp[nodeIsSingle]
|
|
@@ -467,7 +467,8 @@ let FlatmapQueries = function () {
|
|
|
467
467
|
this.pubmedSearchUrl = function (ids) {
|
|
468
468
|
let url = 'https://pubmed.ncbi.nlm.nih.gov/?'
|
|
469
469
|
let params = new URLSearchParams()
|
|
470
|
-
|
|
470
|
+
const decodedIDs = ids.map((id) => decodeURIComponent(id));
|
|
471
|
+
params.append('term', decodedIDs);
|
|
471
472
|
return url + params.toString()
|
|
472
473
|
}
|
|
473
474
|
}
|
package/vite.config.js
CHANGED
|
@@ -50,11 +50,12 @@ export default defineConfig(({ command, mode }) => {
|
|
|
50
50
|
fileName: 'flatmapvuer',
|
|
51
51
|
},
|
|
52
52
|
rollupOptions: {
|
|
53
|
-
external: ["vue", "@abi-software/svg-sprite"],
|
|
53
|
+
external: ["vue", "@abi-software/svg-sprite", "@abi-software/map-utilities"],
|
|
54
54
|
output: {
|
|
55
55
|
globals: {
|
|
56
56
|
vue: "Vue",
|
|
57
|
-
"@abi-software/svg-sprite": "@abi-software/svg-sprite"
|
|
57
|
+
"@abi-software/svg-sprite": "@abi-software/svg-sprite",
|
|
58
|
+
"@abi-software/map-utilities": "@abi-software/map-utilities"
|
|
58
59
|
},
|
|
59
60
|
},
|
|
60
61
|
},
|
|
@@ -1,501 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<el-main class="main">
|
|
3
|
-
<div class="block">
|
|
4
|
-
<el-row class="info-field">
|
|
5
|
-
<div class="title">Feature Annotations</div>
|
|
6
|
-
</el-row>
|
|
7
|
-
<template v-if="annotationEntry">
|
|
8
|
-
<el-row
|
|
9
|
-
v-for="(key, label) in displayPair"
|
|
10
|
-
v-show="annotationEntry[key]"
|
|
11
|
-
class="dialog-text"
|
|
12
|
-
:key="key"
|
|
13
|
-
>
|
|
14
|
-
<strong>{{ label }}: </strong> {{ annotationEntry[key] }}
|
|
15
|
-
</el-row>
|
|
16
|
-
<template v-if="prevSubs.length > 0">
|
|
17
|
-
<div
|
|
18
|
-
v-show="showSubmissions"
|
|
19
|
-
class="hide"
|
|
20
|
-
@click="showSubmissions = false"
|
|
21
|
-
>
|
|
22
|
-
Hide previous submissions
|
|
23
|
-
<el-icon><el-icon-arrow-up /></el-icon>
|
|
24
|
-
</div>
|
|
25
|
-
<div
|
|
26
|
-
v-show="!showSubmissions"
|
|
27
|
-
class="hide"
|
|
28
|
-
@click="showSubmissions = true"
|
|
29
|
-
>
|
|
30
|
-
Show previous {{ prevSubs.length }} submission(s)
|
|
31
|
-
<el-icon><el-icon-arrow-down /></el-icon>
|
|
32
|
-
</div>
|
|
33
|
-
<template v-if="showSubmissions">
|
|
34
|
-
<el-row class="dialog-spacer"></el-row>
|
|
35
|
-
<el-row class="dialog-text">
|
|
36
|
-
<strong class="sub-title">Previous submissions:</strong>
|
|
37
|
-
</el-row>
|
|
38
|
-
<div class="entry" v-for="(sub, index) in prevSubs" :key="index">
|
|
39
|
-
<el-row class="dialog-text">
|
|
40
|
-
<strong>{{ formatTime(sub.created) }}</strong>
|
|
41
|
-
{{ sub.creator.name }}
|
|
42
|
-
</el-row>
|
|
43
|
-
<el-row class="dialog-text">
|
|
44
|
-
<strong>Evidence: </strong>
|
|
45
|
-
<el-row
|
|
46
|
-
v-for="evidence in sub.body.evidence"
|
|
47
|
-
:key="evidence"
|
|
48
|
-
class="dialog-text"
|
|
49
|
-
>
|
|
50
|
-
<a :href="evidence" target="_blank"> {{ evidence }}</a>
|
|
51
|
-
</el-row>
|
|
52
|
-
</el-row>
|
|
53
|
-
<el-row class="dialog-text">
|
|
54
|
-
<strong>Comment: </strong> {{ sub.body.comment }}
|
|
55
|
-
</el-row>
|
|
56
|
-
</div>
|
|
57
|
-
</template>
|
|
58
|
-
</template>
|
|
59
|
-
<template v-if="authenticated">
|
|
60
|
-
<template v-if="isEditable">
|
|
61
|
-
<el-row class="dialog-spacer"></el-row>
|
|
62
|
-
<el-row v-if="!editing">
|
|
63
|
-
<el-icon class="standard-icon">
|
|
64
|
-
<el-icon-edit @click="editing = true" />
|
|
65
|
-
</el-icon>
|
|
66
|
-
<el-icon
|
|
67
|
-
class="standard-icon"
|
|
68
|
-
v-if="isDeleted"
|
|
69
|
-
>
|
|
70
|
-
<el-icon-delete @click="submit"/>
|
|
71
|
-
</el-icon>
|
|
72
|
-
<el-icon
|
|
73
|
-
class="standard-icon"
|
|
74
|
-
v-else-if="isPositionUpdated"
|
|
75
|
-
>
|
|
76
|
-
<el-icon-finished @click="submit" />
|
|
77
|
-
</el-icon>
|
|
78
|
-
</el-row>
|
|
79
|
-
<template v-else>
|
|
80
|
-
<el-row class="dialog-text">
|
|
81
|
-
<strong class="sub-title">Suggest changes:</strong>
|
|
82
|
-
</el-row>
|
|
83
|
-
<template v-if="!isDeleted">
|
|
84
|
-
<el-row class="dialog-text">
|
|
85
|
-
<strong>Evidence:</strong>
|
|
86
|
-
</el-row>
|
|
87
|
-
<el-row v-for="(value, index) in evidence" :key="value">
|
|
88
|
-
<el-col :span="20">
|
|
89
|
-
{{ evidence[index] }}
|
|
90
|
-
</el-col>
|
|
91
|
-
<el-col :span="4">
|
|
92
|
-
<el-icon class="standard-icon">
|
|
93
|
-
<el-icon-close @click="removeEvidence(index)" />
|
|
94
|
-
</el-icon>
|
|
95
|
-
</el-col>
|
|
96
|
-
</el-row>
|
|
97
|
-
<el-row>
|
|
98
|
-
<el-input
|
|
99
|
-
size="small"
|
|
100
|
-
placeholder="Enter"
|
|
101
|
-
v-model="newEvidence"
|
|
102
|
-
@change="evidenceEntered($event)"
|
|
103
|
-
>
|
|
104
|
-
<template #prepend>
|
|
105
|
-
<el-select
|
|
106
|
-
:teleported="false"
|
|
107
|
-
v-model="evidencePrefix"
|
|
108
|
-
placeholder="Select"
|
|
109
|
-
class="select-box"
|
|
110
|
-
popper-class="flatmap_dropdown"
|
|
111
|
-
>
|
|
112
|
-
<el-option
|
|
113
|
-
v-for="item in evidencePrefixes"
|
|
114
|
-
:key="item"
|
|
115
|
-
:label="item"
|
|
116
|
-
:value="item"
|
|
117
|
-
>
|
|
118
|
-
<el-row>
|
|
119
|
-
<el-col :span="12">{{ item }}</el-col>
|
|
120
|
-
</el-row>
|
|
121
|
-
</el-option>
|
|
122
|
-
</el-select>
|
|
123
|
-
</template>
|
|
124
|
-
</el-input>
|
|
125
|
-
</el-row>
|
|
126
|
-
</template>
|
|
127
|
-
<el-row>
|
|
128
|
-
<strong>Comment:</strong>
|
|
129
|
-
</el-row>
|
|
130
|
-
<el-row class="dialog-text">
|
|
131
|
-
<el-input
|
|
132
|
-
type="textarea"
|
|
133
|
-
:autosize="{ minRows: 2, maxRows: 4 }"
|
|
134
|
-
placeholder="Enter"
|
|
135
|
-
v-model="comment"
|
|
136
|
-
/>
|
|
137
|
-
</el-row>
|
|
138
|
-
<el-row class="dialog-text">
|
|
139
|
-
<el-button class="button" type="primary" plain @click="submit">
|
|
140
|
-
Submit
|
|
141
|
-
</el-button>
|
|
142
|
-
</el-row>
|
|
143
|
-
</template>
|
|
144
|
-
<el-row class="dialog-text" v-if="errorMessage">
|
|
145
|
-
<strong class="sub-title"> {{ errorMessage }} </strong>
|
|
146
|
-
</el-row>
|
|
147
|
-
</template>
|
|
148
|
-
</template>
|
|
149
|
-
</template>
|
|
150
|
-
</div>
|
|
151
|
-
</el-main>
|
|
152
|
-
</template>
|
|
153
|
-
|
|
154
|
-
<script>
|
|
155
|
-
import {
|
|
156
|
-
ArrowUp as ElIconArrowUp,
|
|
157
|
-
ArrowDown as ElIconArrowDown,
|
|
158
|
-
Edit as ElIconEdit,
|
|
159
|
-
Close as ElIconClose,
|
|
160
|
-
Delete as ElIconDelete,
|
|
161
|
-
Finished as ElIconFinished,
|
|
162
|
-
} from '@element-plus/icons-vue'
|
|
163
|
-
/* eslint-disable no-alert, no-console */
|
|
164
|
-
import {
|
|
165
|
-
ElButton as Button,
|
|
166
|
-
ElCol as Col,
|
|
167
|
-
ElInput as Input,
|
|
168
|
-
ElMain as Main,
|
|
169
|
-
ElRow as Row,
|
|
170
|
-
ElSelect as Select,
|
|
171
|
-
} from 'element-plus'
|
|
172
|
-
|
|
173
|
-
export default {
|
|
174
|
-
name: 'AnnotationTool',
|
|
175
|
-
components: {
|
|
176
|
-
Button,
|
|
177
|
-
Col,
|
|
178
|
-
Input,
|
|
179
|
-
Main,
|
|
180
|
-
Row,
|
|
181
|
-
Select,
|
|
182
|
-
ElIconArrowUp,
|
|
183
|
-
ElIconArrowDown,
|
|
184
|
-
ElIconEdit,
|
|
185
|
-
ElIconClose,
|
|
186
|
-
},
|
|
187
|
-
props: {
|
|
188
|
-
annotationEntry: {
|
|
189
|
-
type: Object,
|
|
190
|
-
},
|
|
191
|
-
},
|
|
192
|
-
inject: ['flatmapAPI', '$annotator', 'userApiKey'],
|
|
193
|
-
data: function () {
|
|
194
|
-
return {
|
|
195
|
-
displayPair: {
|
|
196
|
-
'Feature ID': 'featureId',
|
|
197
|
-
Tooltip: 'label',
|
|
198
|
-
Models: 'models',
|
|
199
|
-
Name: 'name',
|
|
200
|
-
Resource: 'resourceId',
|
|
201
|
-
},
|
|
202
|
-
editing: false,
|
|
203
|
-
evidencePrefixes: ['DOI:', 'PMID:'],
|
|
204
|
-
evidencePrefix: 'DOI:',
|
|
205
|
-
evidence: [],
|
|
206
|
-
authenticated: false,
|
|
207
|
-
newEvidence: '',
|
|
208
|
-
comment: '',
|
|
209
|
-
prevSubs: [],
|
|
210
|
-
showSubmissions: true,
|
|
211
|
-
errorMessage: '',
|
|
212
|
-
creator: undefined
|
|
213
|
-
}
|
|
214
|
-
},
|
|
215
|
-
computed: {
|
|
216
|
-
isEditable: function () {
|
|
217
|
-
return (
|
|
218
|
-
this.annotationEntry['resourceId'] &&
|
|
219
|
-
this.annotationEntry['featureId']
|
|
220
|
-
)
|
|
221
|
-
},
|
|
222
|
-
isPositionUpdated: function () {
|
|
223
|
-
return (
|
|
224
|
-
this.annotationEntry['resourceId'] &&
|
|
225
|
-
this.annotationEntry['type'] === 'updated' &&
|
|
226
|
-
this.annotationEntry['positionUpdated']
|
|
227
|
-
)
|
|
228
|
-
},
|
|
229
|
-
isDeleted: function () {
|
|
230
|
-
return (
|
|
231
|
-
this.annotationEntry['resourceId'] &&
|
|
232
|
-
this.annotationEntry['type'] === 'deleted'
|
|
233
|
-
)
|
|
234
|
-
}
|
|
235
|
-
},
|
|
236
|
-
methods: {
|
|
237
|
-
evidenceEntered: function (value) {
|
|
238
|
-
if (value) {
|
|
239
|
-
this.evidence.push(this.evidencePrefix + value)
|
|
240
|
-
this.newEvidence = ''
|
|
241
|
-
}
|
|
242
|
-
},
|
|
243
|
-
formatTime: function (dateString) {
|
|
244
|
-
const options = {
|
|
245
|
-
year: 'numeric',
|
|
246
|
-
month: 'long',
|
|
247
|
-
day: 'numeric',
|
|
248
|
-
hour: 'numeric',
|
|
249
|
-
minute: 'numeric',
|
|
250
|
-
second: 'numeric',
|
|
251
|
-
}
|
|
252
|
-
return new Date(dateString).toLocaleDateString(undefined, options)
|
|
253
|
-
},
|
|
254
|
-
updatePrevSubmissions: function () {
|
|
255
|
-
if (this.$annotator && this.authenticated) {
|
|
256
|
-
if (
|
|
257
|
-
this.annotationEntry['resourceId'] &&
|
|
258
|
-
this.annotationEntry['featureId']
|
|
259
|
-
) {
|
|
260
|
-
this.$annotator
|
|
261
|
-
.itemAnnotations(
|
|
262
|
-
this.userApiKey,
|
|
263
|
-
this.annotationEntry['resourceId'],
|
|
264
|
-
this.annotationEntry['featureId']
|
|
265
|
-
)
|
|
266
|
-
.then((value) => {
|
|
267
|
-
this.prevSubs = value
|
|
268
|
-
})
|
|
269
|
-
.catch((reason) => {
|
|
270
|
-
console.log(reason) // Error!
|
|
271
|
-
})
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
},
|
|
275
|
-
submit: function () {
|
|
276
|
-
// User can either update/delete annotation directly
|
|
277
|
-
// or provide extra comments for update/delete action
|
|
278
|
-
if (
|
|
279
|
-
this.annotationEntry['type'] === 'updated' &&
|
|
280
|
-
this.annotationEntry['positionUpdated']
|
|
281
|
-
) {
|
|
282
|
-
this.comment = this.comment ?
|
|
283
|
-
`Position Updated: ${this.comment}` :
|
|
284
|
-
'Position Updated'
|
|
285
|
-
} else if (this.annotationEntry['type'] === 'deleted') {
|
|
286
|
-
this.comment = this.comment ?
|
|
287
|
-
`Feature Deleted: ${this.comment}` :
|
|
288
|
-
'Feature Deleted'
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
if (this.evidence.length > 0 || this.comment) {
|
|
292
|
-
if (
|
|
293
|
-
this.annotationEntry['resourceId'] &&
|
|
294
|
-
this.annotationEntry['featureId']
|
|
295
|
-
) {
|
|
296
|
-
const evidenceURLs = []
|
|
297
|
-
this.evidence.forEach((evidence) => {
|
|
298
|
-
if (evidence.includes('DOI:')) {
|
|
299
|
-
const link = evidence.replace('DOI:', 'https://doi.org/')
|
|
300
|
-
evidenceURLs.push(new URL(link))
|
|
301
|
-
} else if (evidence.includes('PMID:')) {
|
|
302
|
-
const link = evidence.replace(
|
|
303
|
-
'PMID:',
|
|
304
|
-
'https://pubmed.ncbi.nlm.nih.gov/'
|
|
305
|
-
)
|
|
306
|
-
evidenceURLs.push(new URL(link))
|
|
307
|
-
}
|
|
308
|
-
})
|
|
309
|
-
const userAnnotation = {
|
|
310
|
-
resource: this.annotationEntry['resourceId'],
|
|
311
|
-
item: Object.assign({id: this.annotationEntry['featureId']},
|
|
312
|
-
Object.fromEntries(
|
|
313
|
-
Object.entries(this.annotationEntry)
|
|
314
|
-
.filter(([key]) => ['label', 'models'].includes(key)))),
|
|
315
|
-
body: {
|
|
316
|
-
evidence: evidenceURLs,
|
|
317
|
-
comment: this.comment,
|
|
318
|
-
},
|
|
319
|
-
feature: this.annotationEntry['feature']
|
|
320
|
-
}
|
|
321
|
-
Object.assign(userAnnotation.body, this.annotationEntry['body'])
|
|
322
|
-
if (this.annotationEntry['type'] === 'deleted') {
|
|
323
|
-
userAnnotation.feature = undefined
|
|
324
|
-
}
|
|
325
|
-
if (this.creator) userAnnotation.creator = this.creator
|
|
326
|
-
this.$annotator
|
|
327
|
-
.addAnnotation(this.userApiKey, userAnnotation)
|
|
328
|
-
.then(() => {
|
|
329
|
-
this.$emit('annotation', userAnnotation)
|
|
330
|
-
this.errorMessage = ''
|
|
331
|
-
this.resetSubmission()
|
|
332
|
-
this.updatePrevSubmissions()
|
|
333
|
-
})
|
|
334
|
-
.catch(() => {
|
|
335
|
-
this.errorMessage =
|
|
336
|
-
'There is a problem with the submission, please try again later'
|
|
337
|
-
})
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
},
|
|
341
|
-
removeEvidence: function (index) {
|
|
342
|
-
this.evidence.splice(index, 1)
|
|
343
|
-
},
|
|
344
|
-
resetSubmission: function () {
|
|
345
|
-
this.editing = false
|
|
346
|
-
this.evidence = []
|
|
347
|
-
this.newFeature = ''
|
|
348
|
-
this.comment = ''
|
|
349
|
-
},
|
|
350
|
-
},
|
|
351
|
-
watch: {
|
|
352
|
-
annotationEntry: {
|
|
353
|
-
handler: function (newVal, oldVal) {
|
|
354
|
-
if (newVal !== oldVal) {
|
|
355
|
-
this.resetSubmission()
|
|
356
|
-
this.updatePrevSubmissions()
|
|
357
|
-
}
|
|
358
|
-
},
|
|
359
|
-
immediate: false,
|
|
360
|
-
deep: false,
|
|
361
|
-
},
|
|
362
|
-
},
|
|
363
|
-
mounted: function () {
|
|
364
|
-
this.$annotator.authenticate(this.userApiKey).then((userData) => {
|
|
365
|
-
if (userData.name && userData.email) {
|
|
366
|
-
this.creator = userData
|
|
367
|
-
if (!userData.orcid) this.creator.orcid = '0000-0000-0000-0000'
|
|
368
|
-
this.authenticated = true
|
|
369
|
-
this.updatePrevSubmissions()
|
|
370
|
-
} else {
|
|
371
|
-
this.errorMessage = ''
|
|
372
|
-
}
|
|
373
|
-
})
|
|
374
|
-
},
|
|
375
|
-
}
|
|
376
|
-
</script>
|
|
377
|
-
|
|
378
|
-
<style lang="scss" scoped>
|
|
379
|
-
|
|
380
|
-
.info-field {
|
|
381
|
-
display: flex;
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
.block {
|
|
385
|
-
margin-bottom: 0.5em;
|
|
386
|
-
|
|
387
|
-
.main > &:first-of-type {
|
|
388
|
-
margin-right: 0.5em;
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
.button {
|
|
393
|
-
padding-top: 5px;
|
|
394
|
-
padding-bottom: 5px;
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
.standard-icon {
|
|
398
|
-
color: $app-primary-color;
|
|
399
|
-
&:hover {
|
|
400
|
-
cursor: pointer;
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
.dialog-text {
|
|
405
|
-
color: rgb(48, 49, 51);
|
|
406
|
-
font-size: 14px;
|
|
407
|
-
font-weight: normal;
|
|
408
|
-
line-height: 20px;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
.main {
|
|
412
|
-
font-size: 14px;
|
|
413
|
-
text-align: left;
|
|
414
|
-
line-height: 1.5em;
|
|
415
|
-
font-family: Asap, sans-serif, Helvetica;
|
|
416
|
-
font-weight: 400;
|
|
417
|
-
/* outline: thin red solid; */
|
|
418
|
-
padding: 1em !important;
|
|
419
|
-
overflow-x: hidden;
|
|
420
|
-
overflow-y: auto;
|
|
421
|
-
min-width: 300px; // .maplibregl-popup max-width
|
|
422
|
-
max-height: 400px;
|
|
423
|
-
scrollbar-width: thin;
|
|
424
|
-
|
|
425
|
-
&::-webkit-scrollbar {
|
|
426
|
-
width: 4px;
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
&::-webkit-scrollbar-thumb {
|
|
430
|
-
border-radius: 10px;
|
|
431
|
-
box-shadow: inset 0 0 6px #c0c4cc;
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
.title {
|
|
436
|
-
font-size: 18px;
|
|
437
|
-
font-weight: 500;
|
|
438
|
-
font-weight: bold;
|
|
439
|
-
padding-bottom: 8px;
|
|
440
|
-
color: rgb(131, 0, 191);
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
.sub-title {
|
|
444
|
-
font-size: 16px;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
.dialog-spacer {
|
|
448
|
-
border-bottom: 1px solid #e4e7ed;
|
|
449
|
-
margin-bottom: 10px;
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
.submit {
|
|
453
|
-
color: $app-primary-color;
|
|
454
|
-
&:hover {
|
|
455
|
-
cursor: pointer;
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
.entry ~ .entry {
|
|
460
|
-
border-top: 1px solid #e4e7ed;
|
|
461
|
-
margin-top: 10px;
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
.hide {
|
|
465
|
-
color: $app-primary-color;
|
|
466
|
-
cursor: pointer;
|
|
467
|
-
margin-right: 6px;
|
|
468
|
-
margin-top: 3px;
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
:deep(.el-input__inner),
|
|
472
|
-
:deep(.el-textarea__inner) {
|
|
473
|
-
font-family: Asap, sans-serif;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
.select-box {
|
|
477
|
-
width: 80px;
|
|
478
|
-
background-color: var(--white);
|
|
479
|
-
font-weight: 500;
|
|
480
|
-
color: rgb(48, 49, 51);
|
|
481
|
-
:deep(.el-input__inner) {
|
|
482
|
-
height: 30px;
|
|
483
|
-
color: rgb(48, 49, 51);
|
|
484
|
-
}
|
|
485
|
-
:deep(.el-input__icon) {
|
|
486
|
-
line-height: 30px;
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
:deep(.flatmap_dropdown) {
|
|
491
|
-
min-width: 80px !important;
|
|
492
|
-
.el-select-dropdown__item {
|
|
493
|
-
white-space: nowrap;
|
|
494
|
-
text-align: left;
|
|
495
|
-
&.selected {
|
|
496
|
-
color: $app-primary-color;
|
|
497
|
-
font-weight: normal;
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
</style>
|