@abi-software/map-utilities 1.4.2-beta.0 → 1.4.3-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/map-utilities.js +33796 -16774
- package/dist/map-utilities.umd.cjs +246 -67
- package/dist/style.css +1 -1
- package/package.json +6 -1
- package/src/components/ConnectivityGraph/ConnectivityGraph.vue +48 -16
- package/src/components/ConnectivityGraph/graph.js +56 -25
- package/src/components/ConnectivityList/ConnectivityList.vue +394 -0
- package/src/components/Tooltip/ExternalResourceCard.vue +69 -39
- package/src/components/Tooltip/ProvenancePopup.vue +67 -149
- package/src/components/index.js +2 -0
- package/src/components/utilities.js +47 -0
- package/src/components.d.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abi-software/map-utilities",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.3-beta.0",
|
|
4
4
|
"files": [
|
|
5
5
|
"dist/*",
|
|
6
6
|
"src/*",
|
|
@@ -30,6 +30,11 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@abi-software/svg-sprite": "^1.0.1",
|
|
33
|
+
"@citation-js/core": "^0.7.14",
|
|
34
|
+
"@citation-js/plugin-bibtex": "^0.7.17",
|
|
35
|
+
"@citation-js/plugin-csl": "^0.7.14",
|
|
36
|
+
"@citation-js/plugin-doi": "^0.7.16",
|
|
37
|
+
"@citation-js/plugin-pubmed": "^0.3.0",
|
|
33
38
|
"@element-plus/icons-vue": "^2.3.1",
|
|
34
39
|
"cytoscape": "^3.30.2",
|
|
35
40
|
"element-plus": "2.8.4",
|
|
@@ -160,6 +160,10 @@ export default {
|
|
|
160
160
|
type: Array,
|
|
161
161
|
default: [],
|
|
162
162
|
},
|
|
163
|
+
connectivityFromMap: {
|
|
164
|
+
type: Object,
|
|
165
|
+
default: () => null,
|
|
166
|
+
},
|
|
163
167
|
},
|
|
164
168
|
data: function () {
|
|
165
169
|
return {
|
|
@@ -184,26 +188,20 @@ export default {
|
|
|
184
188
|
connectivityGraphContainer: null,
|
|
185
189
|
};
|
|
186
190
|
},
|
|
191
|
+
watch: {
|
|
192
|
+
connectivityFromMap: function (oldVal, newVal) {
|
|
193
|
+
if (oldVal != newVal) {
|
|
194
|
+
this.showSpinner();
|
|
195
|
+
this.start();
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
},
|
|
187
199
|
mounted() {
|
|
188
200
|
this.showSpinner();
|
|
189
201
|
this.updateTooltipContainer();
|
|
190
202
|
this.refreshCache();
|
|
191
203
|
this.loadCacheData();
|
|
192
|
-
this.
|
|
193
|
-
.then((res) => {
|
|
194
|
-
if (res?.success) {
|
|
195
|
-
this.showGraph(this.entry);
|
|
196
|
-
} else if (res?.error) {
|
|
197
|
-
this.loadingError = res.error;
|
|
198
|
-
} else {
|
|
199
|
-
this.loadingError = 'Loading error!';
|
|
200
|
-
}
|
|
201
|
-
this.hideSpinner();
|
|
202
|
-
})
|
|
203
|
-
.catch((error) => {
|
|
204
|
-
this.loadingError = 'Loading error!';
|
|
205
|
-
this.hideSpinner();
|
|
206
|
-
});
|
|
204
|
+
this.start();
|
|
207
205
|
},
|
|
208
206
|
methods: {
|
|
209
207
|
updateTooltipContainer: function () {
|
|
@@ -275,6 +273,22 @@ export default {
|
|
|
275
273
|
|
|
276
274
|
sessionStorage.setItem('connectivity-graph-expiry', expiry);
|
|
277
275
|
},
|
|
276
|
+
start: function () {
|
|
277
|
+
this.run()
|
|
278
|
+
.then((res) => {
|
|
279
|
+
if (res?.success) {
|
|
280
|
+
this.showGraph(this.entry);
|
|
281
|
+
} else if (res?.error) {
|
|
282
|
+
this.loadingError = res.error;
|
|
283
|
+
} else {
|
|
284
|
+
this.loadingError = 'Loading error!';
|
|
285
|
+
}
|
|
286
|
+
})
|
|
287
|
+
.catch((error) => {
|
|
288
|
+
this.loadingError = 'Loading error!';
|
|
289
|
+
this.hideSpinner();
|
|
290
|
+
});
|
|
291
|
+
},
|
|
278
292
|
run: async function () {
|
|
279
293
|
if (!this.schemaVersion) {
|
|
280
294
|
this.schemaVersion = await this.getSchemaVersion();
|
|
@@ -305,8 +319,24 @@ export default {
|
|
|
305
319
|
showGraph: async function (neuronPath) {
|
|
306
320
|
const graphCanvas = this.$refs.graphCanvas;
|
|
307
321
|
|
|
322
|
+
// Update label data
|
|
323
|
+
if (this.connectivityFromMap) {
|
|
324
|
+
this.cacheLabels(this.connectivityFromMap);
|
|
325
|
+
await this.getCachedTermLabels();
|
|
326
|
+
}
|
|
327
|
+
|
|
308
328
|
this.connectivityGraph = new ConnectivityGraph(this.labelCache, graphCanvas);
|
|
309
|
-
|
|
329
|
+
const connectivityInfo = this.knowledgeByPath.get(neuronPath);
|
|
330
|
+
|
|
331
|
+
// Update connectivity
|
|
332
|
+
if (this.connectivityFromMap) {
|
|
333
|
+
connectivityInfo.axons = this.connectivityFromMap.axons;
|
|
334
|
+
connectivityInfo.connectivity = this.connectivityFromMap.connectivity;
|
|
335
|
+
connectivityInfo.dendrites = this.connectivityFromMap.dendrites;
|
|
336
|
+
connectivityInfo.somas = this.connectivityFromMap.somas;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
await this.connectivityGraph.addConnectivity(connectivityInfo);
|
|
310
340
|
|
|
311
341
|
this.connectivityGraph.showConnectivity(graphCanvas);
|
|
312
342
|
|
|
@@ -322,6 +352,8 @@ export default {
|
|
|
322
352
|
*/
|
|
323
353
|
this.$emit('tap-node', data);
|
|
324
354
|
});
|
|
355
|
+
|
|
356
|
+
this.hideSpinner();
|
|
325
357
|
},
|
|
326
358
|
query: async function (sql, params) {
|
|
327
359
|
const url = `${this.mapServer}knowledge/query/`;
|
|
@@ -72,6 +72,7 @@ export class ConnectivityGraph extends EventTarget
|
|
|
72
72
|
somas = []
|
|
73
73
|
labelCache = new Map()
|
|
74
74
|
graphCanvas = null
|
|
75
|
+
hasPhenotypes = false
|
|
75
76
|
|
|
76
77
|
constructor(labelCache, graphCanvas)
|
|
77
78
|
{
|
|
@@ -83,23 +84,32 @@ export class ConnectivityGraph extends EventTarget
|
|
|
83
84
|
async addConnectivity(knowledge)
|
|
84
85
|
//=====================================================
|
|
85
86
|
{
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
87
|
+
if (knowledge && knowledge["node-phenotypes"]) {
|
|
88
|
+
const sourceKey = ["ilxtr:hasSomaLocatedIn"]
|
|
89
|
+
const destinationKey = ["ilxtr:hasAxonPresynapticElementIn", "ilxtr:hasAxonSensorySubcellularElementIn"]
|
|
90
|
+
|
|
91
|
+
const source = []
|
|
92
|
+
const destination = []
|
|
93
|
+
sourceKey.forEach((key)=>{
|
|
94
|
+
source.push(...knowledge["node-phenotypes"][key])
|
|
95
|
+
})
|
|
96
|
+
destinationKey.forEach((key)=>{
|
|
97
|
+
destination.push(...knowledge["node-phenotypes"][key])
|
|
98
|
+
})
|
|
99
|
+
const via = findComponents(knowledge, source, destination)
|
|
100
|
+
this.dendrites = source.map(node => JSON.stringify(node))
|
|
101
|
+
this.axons = destination.map(node => JSON.stringify(node))
|
|
102
|
+
if (via?.length) {
|
|
103
|
+
this.somas = via.map(node => JSON.stringify(node))
|
|
104
|
+
}
|
|
105
|
+
this.hasPhenotypes = true
|
|
106
|
+
} else {
|
|
107
|
+
this.axons = knowledge.axons.map(node => JSON.stringify(node))
|
|
108
|
+
this.dendrites = knowledge.dendrites.map(node => JSON.stringify(node))
|
|
109
|
+
if (knowledge.somas?.length) {
|
|
110
|
+
this.somas = knowledge.somas.map(node => JSON.stringify(node))
|
|
111
|
+
}
|
|
112
|
+
this.hasPhenotypes = false
|
|
103
113
|
}
|
|
104
114
|
if (knowledge.connectivity.length) {
|
|
105
115
|
for (const edge of knowledge.connectivity) {
|
|
@@ -208,9 +218,17 @@ export class ConnectivityGraph extends EventTarget
|
|
|
208
218
|
get roots()
|
|
209
219
|
//===================
|
|
210
220
|
{
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
221
|
+
if (this.hasPhenotypes) {
|
|
222
|
+
return [
|
|
223
|
+
...this.dendrites,
|
|
224
|
+
]
|
|
225
|
+
} else {
|
|
226
|
+
return [
|
|
227
|
+
...this.dendrites,
|
|
228
|
+
...this.somas
|
|
229
|
+
]
|
|
230
|
+
}
|
|
231
|
+
|
|
214
232
|
}
|
|
215
233
|
|
|
216
234
|
async graphNode(node)
|
|
@@ -229,12 +247,25 @@ export class ConnectivityGraph extends EventTarget
|
|
|
229
247
|
id,
|
|
230
248
|
label: label.join('\n')
|
|
231
249
|
}
|
|
232
|
-
if (this.
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
250
|
+
if (this.hasPhenotypes) {
|
|
251
|
+
if (this.axons.includes(id)) {
|
|
252
|
+
result['axon'] = true
|
|
253
|
+
} else if (this.dendrites.includes(id)) {
|
|
254
|
+
result['dendrite'] = true
|
|
255
|
+
} else {
|
|
256
|
+
result['somas'] = true
|
|
257
|
+
}
|
|
236
258
|
} else {
|
|
237
|
-
|
|
259
|
+
if (this.axons.includes(id)) {
|
|
260
|
+
if (this.dendrites.includes(id) || this.somas.includes(id)) {
|
|
261
|
+
result['somas'] = true
|
|
262
|
+
} else {
|
|
263
|
+
result['axon'] = true
|
|
264
|
+
}
|
|
265
|
+
} else if (this.dendrites.includes(id) || this.somas.includes(id)) {
|
|
266
|
+
result['dendrite'] = true
|
|
267
|
+
|
|
268
|
+
}
|
|
238
269
|
}
|
|
239
270
|
return result
|
|
240
271
|
}
|
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="connectivity-list">
|
|
3
|
+
{{ entry.paths }}
|
|
4
|
+
<div v-if="origins && origins.length > 0" class="block">
|
|
5
|
+
<div class="attribute-title-container">
|
|
6
|
+
<span class="attribute-title">Origin</span>
|
|
7
|
+
<el-popover
|
|
8
|
+
width="250"
|
|
9
|
+
trigger="hover"
|
|
10
|
+
:teleported="false"
|
|
11
|
+
popper-class="popover-origin-help"
|
|
12
|
+
>
|
|
13
|
+
<template #reference>
|
|
14
|
+
<el-icon class="info"><el-icon-warning /></el-icon>
|
|
15
|
+
</template>
|
|
16
|
+
<span style="word-break: keep-all">
|
|
17
|
+
<i>Origin</i> {{ originDescription }}
|
|
18
|
+
</span>
|
|
19
|
+
</el-popover>
|
|
20
|
+
</div>
|
|
21
|
+
<div
|
|
22
|
+
v-for="(origin, i) in origins"
|
|
23
|
+
class="attribute-content"
|
|
24
|
+
:origin-item-label="origin"
|
|
25
|
+
:key="origin"
|
|
26
|
+
@mouseenter="toggleConnectivityTooltip(origin, {show: true})"
|
|
27
|
+
@mouseleave="toggleConnectivityTooltip(origin, {show: false})"
|
|
28
|
+
>
|
|
29
|
+
{{ capitalise(origin) }}
|
|
30
|
+
</div>
|
|
31
|
+
<el-button
|
|
32
|
+
v-show="
|
|
33
|
+
originsWithDatasets && originsWithDatasets.length > 0 &&
|
|
34
|
+
shouldShowExploreButton(originsWithDatasets)
|
|
35
|
+
"
|
|
36
|
+
class="button"
|
|
37
|
+
id="open-dendrites-button"
|
|
38
|
+
@click="openDendrites"
|
|
39
|
+
>
|
|
40
|
+
Explore origin data
|
|
41
|
+
</el-button>
|
|
42
|
+
</div>
|
|
43
|
+
<div
|
|
44
|
+
v-if="components && components.length > 0"
|
|
45
|
+
class="block"
|
|
46
|
+
>
|
|
47
|
+
<div class="attribute-title-container">
|
|
48
|
+
<div class="attribute-title">Components</div>
|
|
49
|
+
</div>
|
|
50
|
+
<div
|
|
51
|
+
v-for="(component, i) in components"
|
|
52
|
+
class="attribute-content"
|
|
53
|
+
:component-item-label="component"
|
|
54
|
+
:key="component"
|
|
55
|
+
@mouseenter="toggleConnectivityTooltip(component, {show: true})"
|
|
56
|
+
@mouseleave="toggleConnectivityTooltip(component, {show: false})"
|
|
57
|
+
>
|
|
58
|
+
{{ capitalise(component) }}
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
<div
|
|
62
|
+
v-if="destinations && destinations.length > 0"
|
|
63
|
+
class="block"
|
|
64
|
+
>
|
|
65
|
+
<div class="attribute-title-container">
|
|
66
|
+
<span class="attribute-title">Destination</span>
|
|
67
|
+
<el-popover
|
|
68
|
+
width="250"
|
|
69
|
+
trigger="hover"
|
|
70
|
+
:teleported="false"
|
|
71
|
+
popper-class="popover-origin-help"
|
|
72
|
+
>
|
|
73
|
+
<template #reference>
|
|
74
|
+
<el-icon class="info"><el-icon-warning /></el-icon>
|
|
75
|
+
</template>
|
|
76
|
+
<span style="word-break: keep-all">
|
|
77
|
+
<i>Destination</i> is where the axons terminate
|
|
78
|
+
</span>
|
|
79
|
+
</el-popover>
|
|
80
|
+
</div>
|
|
81
|
+
<div
|
|
82
|
+
v-for="(destination, i) in destinations"
|
|
83
|
+
class="attribute-content"
|
|
84
|
+
:destination-item-label="destination"
|
|
85
|
+
:key="destination"
|
|
86
|
+
@mouseenter="toggleConnectivityTooltip(destination, {show: true})"
|
|
87
|
+
@mouseleave="toggleConnectivityTooltip(destination, {show: false})"
|
|
88
|
+
>
|
|
89
|
+
{{ capitalise(destination) }}
|
|
90
|
+
</div>
|
|
91
|
+
<el-button
|
|
92
|
+
v-show="
|
|
93
|
+
destinationsWithDatasets &&
|
|
94
|
+
destinationsWithDatasets.length > 0 &&
|
|
95
|
+
shouldShowExploreButton(destinationsWithDatasets)
|
|
96
|
+
"
|
|
97
|
+
class="button"
|
|
98
|
+
@click="openAxons"
|
|
99
|
+
>
|
|
100
|
+
Explore destination data
|
|
101
|
+
</el-button>
|
|
102
|
+
</div>
|
|
103
|
+
<div
|
|
104
|
+
v-show="
|
|
105
|
+
componentsWithDatasets &&
|
|
106
|
+
componentsWithDatasets.length > 0 &&
|
|
107
|
+
shouldShowExploreButton(componentsWithDatasets)
|
|
108
|
+
"
|
|
109
|
+
class="block"
|
|
110
|
+
>
|
|
111
|
+
<el-button
|
|
112
|
+
class="button"
|
|
113
|
+
@click="openAll"
|
|
114
|
+
>
|
|
115
|
+
Search for data on components
|
|
116
|
+
</el-button>
|
|
117
|
+
</div>
|
|
118
|
+
|
|
119
|
+
<div class="connectivity-error-container">
|
|
120
|
+
<div class="connectivity-error" v-if="connectivityError">
|
|
121
|
+
<strong v-if="connectivityError.errorConnectivities">
|
|
122
|
+
{{ connectivityError.errorConnectivities }}
|
|
123
|
+
</strong>
|
|
124
|
+
{{ connectivityError.errorMessage }}
|
|
125
|
+
</div>
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
</template>
|
|
129
|
+
|
|
130
|
+
<script>
|
|
131
|
+
import {
|
|
132
|
+
Warning as ElIconWarning,
|
|
133
|
+
} from '@element-plus/icons-vue'
|
|
134
|
+
import {
|
|
135
|
+
ElButton as Button,
|
|
136
|
+
ElContainer as Container,
|
|
137
|
+
ElIcon as Icon,
|
|
138
|
+
} from 'element-plus'
|
|
139
|
+
import { capitalise } from '../utilities'
|
|
140
|
+
|
|
141
|
+
export default {
|
|
142
|
+
name: 'ConnectivityList',
|
|
143
|
+
components: {
|
|
144
|
+
Button,
|
|
145
|
+
Container,
|
|
146
|
+
Icon,
|
|
147
|
+
ElIconWarning,
|
|
148
|
+
},
|
|
149
|
+
props: {
|
|
150
|
+
entry: {
|
|
151
|
+
type: Object,
|
|
152
|
+
default: () => ({
|
|
153
|
+
destinations: [],
|
|
154
|
+
origins: [],
|
|
155
|
+
components: [],
|
|
156
|
+
destinationsWithDatasets: [],
|
|
157
|
+
originsWithDatasets: [],
|
|
158
|
+
componentsWithDatasets: [],
|
|
159
|
+
resource: undefined,
|
|
160
|
+
featuresAlert: undefined,
|
|
161
|
+
}),
|
|
162
|
+
},
|
|
163
|
+
origins: {
|
|
164
|
+
type: Array,
|
|
165
|
+
default: () => []
|
|
166
|
+
},
|
|
167
|
+
components: {
|
|
168
|
+
type: Array,
|
|
169
|
+
default: () => []
|
|
170
|
+
},
|
|
171
|
+
destinations: {
|
|
172
|
+
type: Array,
|
|
173
|
+
default: () => []
|
|
174
|
+
},
|
|
175
|
+
originsWithDatasets: {
|
|
176
|
+
type: Array,
|
|
177
|
+
default: () => []
|
|
178
|
+
},
|
|
179
|
+
componentsWithDatasets: {
|
|
180
|
+
type: Array,
|
|
181
|
+
default: () => []
|
|
182
|
+
},
|
|
183
|
+
destinationsWithDatasets: {
|
|
184
|
+
type: Array,
|
|
185
|
+
default: () => []
|
|
186
|
+
},
|
|
187
|
+
availableAnatomyFacets: {
|
|
188
|
+
type: Array,
|
|
189
|
+
default: () => [],
|
|
190
|
+
},
|
|
191
|
+
connectivityError: {
|
|
192
|
+
type: Object,
|
|
193
|
+
default: () => null,
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
data: function () {
|
|
197
|
+
return {
|
|
198
|
+
originDescriptions: {
|
|
199
|
+
motor: 'is the location of the initial cell body of the circuit',
|
|
200
|
+
sensory: 'is the location of the initial cell body in the PNS circuit',
|
|
201
|
+
},
|
|
202
|
+
facetList: [],
|
|
203
|
+
sckanVersion: '',
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
watch: {
|
|
207
|
+
availableAnatomyFacets: {
|
|
208
|
+
handler: function (val) {
|
|
209
|
+
this.convertFacetsToList(val)
|
|
210
|
+
},
|
|
211
|
+
immediate: true,
|
|
212
|
+
deep: true,
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
computed: {
|
|
216
|
+
originDescription: function () {
|
|
217
|
+
if (
|
|
218
|
+
this.entry &&
|
|
219
|
+
this.entry.title &&
|
|
220
|
+
this.entry.title.toLowerCase().includes('motor')
|
|
221
|
+
) {
|
|
222
|
+
return this.originDescriptions.motor
|
|
223
|
+
} else {
|
|
224
|
+
return this.originDescriptions.sensory
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
methods: {
|
|
229
|
+
capitalise: function (text) {
|
|
230
|
+
return capitalise(text)
|
|
231
|
+
},
|
|
232
|
+
toggleConnectivityTooltip: function (name, option) {
|
|
233
|
+
this.$emit('toggle-connectivity-tooltip', {
|
|
234
|
+
name,
|
|
235
|
+
option
|
|
236
|
+
});
|
|
237
|
+
},
|
|
238
|
+
// shouldShowExploreButton: Checks if the feature is in the list of available anatomy facets
|
|
239
|
+
shouldShowExploreButton: function (features) {
|
|
240
|
+
for (let i = 0; i < features.length; i++) {
|
|
241
|
+
if (this.facetList.includes(features[i].name.toLowerCase())) {
|
|
242
|
+
return true
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return false
|
|
246
|
+
},
|
|
247
|
+
// convertFacetsToList: Converts the available anatomy facets to a list for easy searching
|
|
248
|
+
convertFacetsToList: function (facets) {
|
|
249
|
+
facets.forEach((facet) => {
|
|
250
|
+
if(facet.children) {
|
|
251
|
+
this.convertFacetsToList(facet.children)
|
|
252
|
+
} else {
|
|
253
|
+
this.facetList.push(facet.label.toLowerCase())
|
|
254
|
+
}
|
|
255
|
+
})
|
|
256
|
+
},
|
|
257
|
+
openAll: function () {
|
|
258
|
+
this.$emit('connectivity-action-click', {
|
|
259
|
+
type: 'Facets',
|
|
260
|
+
labels: this.componentsWithDatasets.map((a) => a.name.toLowerCase()),
|
|
261
|
+
})
|
|
262
|
+
},
|
|
263
|
+
openAxons: function () {
|
|
264
|
+
this.$emit('connectivity-action-click', {
|
|
265
|
+
type: 'Facets',
|
|
266
|
+
labels: this.destinationsWithDatasets.map((a) => a.name.toLowerCase()),
|
|
267
|
+
})
|
|
268
|
+
},
|
|
269
|
+
openDendrites: function () {
|
|
270
|
+
this.$emit('connectivity-action-click', {
|
|
271
|
+
type: 'Facets',
|
|
272
|
+
labels: this.originsWithDatasets.map((a) => a.name.toLowerCase()),
|
|
273
|
+
})
|
|
274
|
+
},
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
</script>
|
|
278
|
+
|
|
279
|
+
<style lang="scss" scoped>
|
|
280
|
+
.connectivity-list {
|
|
281
|
+
display: flex;
|
|
282
|
+
flex-direction: column;
|
|
283
|
+
gap: 1rem;
|
|
284
|
+
position: relative;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.button {
|
|
288
|
+
margin-left: 0px !important;
|
|
289
|
+
margin-top: 0px !important;
|
|
290
|
+
font-size: 14px !important;
|
|
291
|
+
background-color: $app-primary-color;
|
|
292
|
+
color: #fff;
|
|
293
|
+
|
|
294
|
+
&:hover {
|
|
295
|
+
color: #fff !important;
|
|
296
|
+
background-color: #ac76c5 !important;
|
|
297
|
+
border: 1px solid #ac76c5 !important;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
& + .button {
|
|
301
|
+
margin-top: 10px !important;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
.icon {
|
|
306
|
+
right: 0px;
|
|
307
|
+
position: absolute;
|
|
308
|
+
top: 10px;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.icon:hover {
|
|
312
|
+
cursor: pointer;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
:deep(.popover-origin-help.el-popover) {
|
|
316
|
+
text-transform: none !important; // need to overide the tooltip text transform
|
|
317
|
+
border: 1px solid $app-primary-color;
|
|
318
|
+
font-weight: 400;
|
|
319
|
+
font-family: Asap, sans-serif, Helvetica;
|
|
320
|
+
|
|
321
|
+
.el-popper__arrow {
|
|
322
|
+
&:before {
|
|
323
|
+
border-color: $app-primary-color;
|
|
324
|
+
background-color: #ffffff;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
.info {
|
|
330
|
+
color: #8300bf;
|
|
331
|
+
transform: rotate(180deg);
|
|
332
|
+
margin-left: 8px;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
.attribute-title-container {
|
|
336
|
+
margin-bottom: 0.5em;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
.attribute-title {
|
|
340
|
+
font-size: 16px;
|
|
341
|
+
font-weight: 600;
|
|
342
|
+
/* font-weight: bold; */
|
|
343
|
+
text-transform: uppercase;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
.attribute-content {
|
|
347
|
+
font-size: 14px;
|
|
348
|
+
font-weight: 500;
|
|
349
|
+
transition: color 0.25s ease;
|
|
350
|
+
position: relative;
|
|
351
|
+
cursor: default;
|
|
352
|
+
|
|
353
|
+
&:hover {
|
|
354
|
+
color: $app-primary-color;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
+ .attribute-content {
|
|
358
|
+
&::before {
|
|
359
|
+
content: "";
|
|
360
|
+
width: 90%;
|
|
361
|
+
height: 1px;
|
|
362
|
+
background-color: var(--el-border-color);
|
|
363
|
+
position: absolute;
|
|
364
|
+
top: 0;
|
|
365
|
+
left: 0;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
&:last-of-type {
|
|
370
|
+
margin-bottom: 0.5em;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
.connectivity-error-container {
|
|
375
|
+
position: sticky;
|
|
376
|
+
bottom: 0.5rem;
|
|
377
|
+
width: 100%;
|
|
378
|
+
min-height: 31px; // placeholder
|
|
379
|
+
margin-top: -10px !important;
|
|
380
|
+
display: flex;
|
|
381
|
+
flex-direction: row;
|
|
382
|
+
align-items: center;
|
|
383
|
+
justify-content: center;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
.connectivity-error {
|
|
387
|
+
width: fit-content;
|
|
388
|
+
font-size: 12px;
|
|
389
|
+
padding: 0.25rem 0.5rem;
|
|
390
|
+
background-color: var(--el-color-error-light-9);
|
|
391
|
+
border-radius: var(--el-border-radius-small);
|
|
392
|
+
border: 1px solid var(--el-color-error);
|
|
393
|
+
}
|
|
394
|
+
</style>
|