@abi-software/map-side-bar 2.4.1 → 2.4.2-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-side-bar.js +11904 -10915
- package/dist/map-side-bar.umd.cjs +107 -99
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/App.vue +23 -1
- package/src/components/ImageThumbnails.vue +497 -0
- package/src/components/SideBar.vue +27 -3
- package/src/components/Tabs.vue +22 -2
- package/src/components.d.ts +2 -0
- package/src/data/images.json +41 -0
package/package.json
CHANGED
package/src/App.vue
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
<el-button @click="neuronSearch">open neuron search</el-button>
|
|
15
15
|
<el-button @click="keywordSearch">keyword search</el-button>
|
|
16
16
|
<el-button @click="getFacets">Get facets</el-button>
|
|
17
|
+
<el-button @click="showImages">Show Images</el-button>
|
|
17
18
|
</div>
|
|
18
19
|
<SideBar
|
|
19
20
|
:envVars="envVars"
|
|
@@ -23,10 +24,13 @@
|
|
|
23
24
|
:tabs="tabs"
|
|
24
25
|
:activeTabId="activeId"
|
|
25
26
|
:connectivityInfo="connectivityInput"
|
|
27
|
+
:imageThumbnails="imageThumbnails"
|
|
26
28
|
@tabClicked="tabClicked"
|
|
27
29
|
@search-changed="searchChanged($event)"
|
|
28
30
|
@hover-changed="hoverChanged($event)"
|
|
29
31
|
@actionClick="action"
|
|
32
|
+
@connectivity-info-close="onConnectivityInfoClose"
|
|
33
|
+
@image-thumbnail-close="onImageThumbnailClose"
|
|
30
34
|
/>
|
|
31
35
|
</div>
|
|
32
36
|
</template>
|
|
@@ -37,6 +41,7 @@
|
|
|
37
41
|
import SideBar from './components/SideBar.vue'
|
|
38
42
|
import EventBus from './components/EventBus.js'
|
|
39
43
|
import exampleConnectivityInput from './exampleConnectivityInput.js'
|
|
44
|
+
import imageThumbnails from './data/images.json';
|
|
40
45
|
|
|
41
46
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
|
42
47
|
|
|
@@ -101,7 +106,11 @@ export default {
|
|
|
101
106
|
data: function () {
|
|
102
107
|
return {
|
|
103
108
|
contextArray: [null, null],
|
|
104
|
-
tabArray: [
|
|
109
|
+
tabArray: [
|
|
110
|
+
{ title: 'Flatmap', id: 1, type: 'search'},
|
|
111
|
+
{ title: 'Connectivity', id: 2, type: 'connectivity' },
|
|
112
|
+
{ title: 'Images', id: 3, type: 'images' },
|
|
113
|
+
],
|
|
105
114
|
sideBarVisibility: true,
|
|
106
115
|
envVars: {
|
|
107
116
|
API_LOCATION: import.meta.env.VITE_APP_API_LOCATION,
|
|
@@ -114,6 +123,7 @@ export default {
|
|
|
114
123
|
ROOT_URL: import.meta.env.VITE_APP_ROOT_URL,
|
|
115
124
|
},
|
|
116
125
|
connectivityInput: exampleConnectivityInput,
|
|
126
|
+
imageThumbnails: imageThumbnails,
|
|
117
127
|
activeId: 1,
|
|
118
128
|
}
|
|
119
129
|
},
|
|
@@ -224,6 +234,18 @@ export default {
|
|
|
224
234
|
let facets = await this.$refs.sideBar.getAlgoliaFacets()
|
|
225
235
|
console.log('Algolia facets:', facets)
|
|
226
236
|
},
|
|
237
|
+
showImages: function () {
|
|
238
|
+
if (this.$refs.sideBar) {
|
|
239
|
+
this.tabClicked({id: 3, type: 'images'});
|
|
240
|
+
this.$refs.sideBar.setDrawerOpen(true);
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
onConnectivityInfoClose: function () {
|
|
244
|
+
console.log('connectivity-info-close');
|
|
245
|
+
},
|
|
246
|
+
onImageThumbnailClose: function () {
|
|
247
|
+
console.log('image-thumbnail-close');
|
|
248
|
+
},
|
|
227
249
|
},
|
|
228
250
|
mounted: function () {
|
|
229
251
|
console.log('mounted app')
|
|
@@ -0,0 +1,497 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="image-thumbnails-container">
|
|
3
|
+
<div class="toolbar">
|
|
4
|
+
<div class="filters">
|
|
5
|
+
<el-tag
|
|
6
|
+
v-for="(species, index) in speciesFilterTags"
|
|
7
|
+
:key="index"
|
|
8
|
+
type="info"
|
|
9
|
+
class="tag"
|
|
10
|
+
:class="{ 'active-tag': species.name === activeSpecies.name }"
|
|
11
|
+
:closable="species.name === activeSpecies.name"
|
|
12
|
+
@close="removeSpeciesFilterTag"
|
|
13
|
+
@click="filterBySpecies(species)"
|
|
14
|
+
>
|
|
15
|
+
{{ species.name }} ({{ species.count }})
|
|
16
|
+
</el-tag>
|
|
17
|
+
</div>
|
|
18
|
+
<div class="view-selector">
|
|
19
|
+
<el-select
|
|
20
|
+
v-model="viewOption"
|
|
21
|
+
placeholder="Select view"
|
|
22
|
+
popper-class="view-selector-select-popper"
|
|
23
|
+
>
|
|
24
|
+
<el-option
|
|
25
|
+
v-for="item in viewOptions"
|
|
26
|
+
:key="item.value"
|
|
27
|
+
:label="item.label"
|
|
28
|
+
:value="item.value"
|
|
29
|
+
/>
|
|
30
|
+
</el-select>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
<div class="gallery-container" v-if="viewOption === 'gallery'">
|
|
34
|
+
<Gallery :items="imageItems" :imageStyle="imageStyle" />
|
|
35
|
+
</div>
|
|
36
|
+
<div class="dataset-card-container" v-if="viewOption === 'list'">
|
|
37
|
+
<div class="dataset-card" v-for="imageThumbnail in imageItems">
|
|
38
|
+
<div class="card" :key="imageThumbnail.link">
|
|
39
|
+
<div class="card-left">
|
|
40
|
+
<a :href="imageThumbnail.link" class="card-image card-button-link" target="_blank">
|
|
41
|
+
<el-image :src="imageThumbnail.imgSrc" loading="lazy">
|
|
42
|
+
<template #error>
|
|
43
|
+
<div class="image-slot">Loading...</div>
|
|
44
|
+
</template>
|
|
45
|
+
</el-image>
|
|
46
|
+
</a>
|
|
47
|
+
</div>
|
|
48
|
+
<div class="card-right">
|
|
49
|
+
<div class="details">
|
|
50
|
+
<div class="title">
|
|
51
|
+
<strong>{{ imageThumbnail.type }}</strong>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
<div class="details">
|
|
55
|
+
<div>
|
|
56
|
+
{{ formattedTitle(imageThumbnail) }}
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
<div class="details">
|
|
60
|
+
<a class="button el-button el-button--large card-button-link" :href="imageThumbnail.link" target="_blank">
|
|
61
|
+
View {{ imageThumbnail.type }}
|
|
62
|
+
</a>
|
|
63
|
+
</div>
|
|
64
|
+
<!-- Copy to clipboard button container -->
|
|
65
|
+
<div class="float-button-container">
|
|
66
|
+
<CopyToClipboard :content="getCopyContent(imageThumbnail)" />
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
</template>
|
|
74
|
+
|
|
75
|
+
<script>
|
|
76
|
+
import {
|
|
77
|
+
ElImage,
|
|
78
|
+
ElTag as Tag,
|
|
79
|
+
ElOption as Option,
|
|
80
|
+
ElSelect as Select,
|
|
81
|
+
} from 'element-plus';
|
|
82
|
+
import { CopyToClipboard } from '@abi-software/map-utilities';
|
|
83
|
+
import '@abi-software/map-utilities/dist/style.css';
|
|
84
|
+
import Gallery from "@abi-software/gallery";
|
|
85
|
+
import "@abi-software/gallery/dist/style.css";
|
|
86
|
+
|
|
87
|
+
const BASE64PREFIX = 'data:image/png;base64,';
|
|
88
|
+
const VIEW_OPTIONS = [
|
|
89
|
+
{
|
|
90
|
+
value: 'list',
|
|
91
|
+
label: 'List'
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
value: 'gallery',
|
|
95
|
+
label: 'Gallery'
|
|
96
|
+
}
|
|
97
|
+
];
|
|
98
|
+
|
|
99
|
+
export default {
|
|
100
|
+
name: 'ImageThumbnails',
|
|
101
|
+
components: {
|
|
102
|
+
Tag,
|
|
103
|
+
Option,
|
|
104
|
+
Select,
|
|
105
|
+
ElImage,
|
|
106
|
+
Gallery,
|
|
107
|
+
CopyToClipboard,
|
|
108
|
+
},
|
|
109
|
+
props: {
|
|
110
|
+
/**
|
|
111
|
+
* The image thumbnails data to show in sidebar.
|
|
112
|
+
*/
|
|
113
|
+
imageThumbnails: {
|
|
114
|
+
type: Array,
|
|
115
|
+
default: [],
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
data: function () {
|
|
119
|
+
return {
|
|
120
|
+
activeSpecies: { name: "" },
|
|
121
|
+
speciesFilterTags: [],
|
|
122
|
+
imageItems: [],
|
|
123
|
+
showImageGallery: false,
|
|
124
|
+
viewOption: 'list',
|
|
125
|
+
viewOptions: VIEW_OPTIONS,
|
|
126
|
+
};
|
|
127
|
+
},
|
|
128
|
+
computed: {
|
|
129
|
+
imageStyle() {
|
|
130
|
+
return {
|
|
131
|
+
width: "180px",
|
|
132
|
+
height: "135px",
|
|
133
|
+
};
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
mounted: function () {
|
|
137
|
+
this.injectImgSrc();
|
|
138
|
+
this.populateFilterTags();
|
|
139
|
+
this.imageItems = this.imageThumbnails;
|
|
140
|
+
},
|
|
141
|
+
watch: {
|
|
142
|
+
imageThumbnails: {
|
|
143
|
+
handler: function (value) {
|
|
144
|
+
if (value) {
|
|
145
|
+
this.injectImgSrc();
|
|
146
|
+
this.populateFilterTags();
|
|
147
|
+
this.imageItems = this.imageThumbnails;
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
deep: true,
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
methods: {
|
|
154
|
+
injectImgSrc: function() {
|
|
155
|
+
this.imageThumbnails.forEach((imageThumbnail) => {
|
|
156
|
+
return this.mapImage(imageThumbnail);
|
|
157
|
+
});
|
|
158
|
+
},
|
|
159
|
+
formattedTitle: function(imageThumbnail) {
|
|
160
|
+
const type = imageThumbnail.mimetype?.split('/')[1];
|
|
161
|
+
const title = imageThumbnail.title;
|
|
162
|
+
let formattedTitle = '';
|
|
163
|
+
if (type !== 'jpg') {
|
|
164
|
+
formattedTitle = title.replace('.' + type, '');
|
|
165
|
+
}
|
|
166
|
+
formattedTitle = formattedTitle.replaceAll('_', ' ');
|
|
167
|
+
return formattedTitle;
|
|
168
|
+
},
|
|
169
|
+
datasetURL: function(id) {
|
|
170
|
+
return `https://sparc.science/datasets/${id}?type=dataset`;
|
|
171
|
+
},
|
|
172
|
+
mapImage: async function (image) {
|
|
173
|
+
const imgSrc = await this.transformedImage(image.thumbnail);
|
|
174
|
+
if (imgSrc) {
|
|
175
|
+
image.imgSrc = imgSrc;
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
transformedImage: async function(imgUrl) {
|
|
179
|
+
try {
|
|
180
|
+
const response = await fetch(imgUrl);
|
|
181
|
+
if (!response.ok) {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
const data = await response.text();
|
|
185
|
+
return BASE64PREFIX + data;
|
|
186
|
+
} catch (error) {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
removeSpeciesFilterTag: function () {
|
|
191
|
+
this.activeSpecies = { name: "" };
|
|
192
|
+
this.imageItems = this.imageThumbnails;
|
|
193
|
+
},
|
|
194
|
+
filterBySpecies: function (tagInfo) {
|
|
195
|
+
this.activeSpecies = tagInfo;
|
|
196
|
+
let filteredImageItems = [];
|
|
197
|
+
this.imageThumbnails.forEach((image) => {
|
|
198
|
+
if (image.species && image.species.length) {
|
|
199
|
+
image.species.forEach((species) => {
|
|
200
|
+
if (species === tagInfo.name) {
|
|
201
|
+
filteredImageItems.push(image);
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
this.imageItems = filteredImageItems;
|
|
207
|
+
},
|
|
208
|
+
populateFilterTags: function () {
|
|
209
|
+
let imageObjects = {};
|
|
210
|
+
this.imageThumbnails.forEach((image) => {
|
|
211
|
+
if (image.species && image.species.length) {
|
|
212
|
+
image.species.forEach((species) => {
|
|
213
|
+
if (!(species in imageObjects)) {
|
|
214
|
+
imageObjects[species] = {
|
|
215
|
+
name: species,
|
|
216
|
+
count: 0,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
imageObjects[species].count++;
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
this.speciesFilterTags = Object.values(imageObjects);
|
|
224
|
+
},
|
|
225
|
+
getCopyContent: function (imageThumbnail) {
|
|
226
|
+
const contentArray = [];
|
|
227
|
+
|
|
228
|
+
// Use <div> instead of <h1>..<h6> or <p>
|
|
229
|
+
// to avoid default formatting on font size and margin
|
|
230
|
+
|
|
231
|
+
// Title
|
|
232
|
+
if (imageThumbnail.title) {
|
|
233
|
+
contentArray.push(`<div><strong>${this.formattedTitle(imageThumbnail)}</strong></div>`);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Type
|
|
237
|
+
if (imageThumbnail.type) {
|
|
238
|
+
let imageType = `<div><strong>Type:</strong></div>`;
|
|
239
|
+
imageType += `\n`;
|
|
240
|
+
imageType += `${imageThumbnail.type}`;
|
|
241
|
+
contentArray.push(`<div>${imageType}</div>`);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Species
|
|
245
|
+
if (imageThumbnail.species?.length) {
|
|
246
|
+
let species = `<div><strong>Species:</strong></div>`;
|
|
247
|
+
species += `\n`;
|
|
248
|
+
species += imageThumbnail.species.join(', ');
|
|
249
|
+
contentArray.push(`<div>${species}</div>`);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Image URL
|
|
253
|
+
if (imageThumbnail.link) {
|
|
254
|
+
let thumbnailLink = `<div><strong>Link:</strong></div>`;
|
|
255
|
+
thumbnailLink += `\n`;
|
|
256
|
+
thumbnailLink += `<a href="${imageThumbnail.link}">${imageThumbnail.link}</a>`;
|
|
257
|
+
contentArray.push(`<div>${thumbnailLink}</div>`);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Dataset ID
|
|
261
|
+
if (imageThumbnail.id) {
|
|
262
|
+
let datasetIdContent = `<div><strong>Dataset ID:</strong></div>`;
|
|
263
|
+
datasetIdContent += `\n`;
|
|
264
|
+
datasetIdContent += `${imageThumbnail.id}`;
|
|
265
|
+
contentArray.push(`<div>${datasetIdContent}</div>`);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Dataset URL
|
|
269
|
+
if (imageThumbnail.id) {
|
|
270
|
+
const datasetURL = this.datasetURL(imageThumbnail.id);
|
|
271
|
+
let dataLocationContent = `<div><strong>Dataset URL:</strong></div>`;
|
|
272
|
+
dataLocationContent += `\n`;
|
|
273
|
+
dataLocationContent += `<a href="${datasetURL}">${datasetURL}</a>`;
|
|
274
|
+
contentArray.push(`<div>${dataLocationContent}</div>`);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Dataset version
|
|
278
|
+
if (imageThumbnail.version) {
|
|
279
|
+
let versionContent = `<div><strong>Dataset version:</strong></div>`;
|
|
280
|
+
versionContent += `\n`;
|
|
281
|
+
versionContent += `${imageThumbnail.version}`;
|
|
282
|
+
contentArray.push(`<div>${versionContent}</div>`);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const copyContent = contentArray.join('\n\n<br>');
|
|
286
|
+
return copyContent;
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
}
|
|
290
|
+
</script>
|
|
291
|
+
|
|
292
|
+
<style lang="scss" scoped>
|
|
293
|
+
.image-thumbnails-container {
|
|
294
|
+
font-size: 14px;
|
|
295
|
+
text-align: left;
|
|
296
|
+
line-height: 1.5em;
|
|
297
|
+
font-family: $font-family;
|
|
298
|
+
font-weight: 400;
|
|
299
|
+
background-color: #f7faff;
|
|
300
|
+
border-left: 1px solid var(--el-border-color);
|
|
301
|
+
border-top: 1px solid var(--el-border-color);
|
|
302
|
+
display: flex;
|
|
303
|
+
flex-direction: column;
|
|
304
|
+
height: calc(100% - 30px); // minus tabs height
|
|
305
|
+
z-index: 1;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
.toolbar {
|
|
309
|
+
display: flex;
|
|
310
|
+
flex-direction: row;
|
|
311
|
+
align-items: center;
|
|
312
|
+
justify-content: space-between;
|
|
313
|
+
padding: 1rem;
|
|
314
|
+
gap: 1rem;
|
|
315
|
+
background-color: #f7faff;
|
|
316
|
+
position: sticky;
|
|
317
|
+
top: 0;
|
|
318
|
+
z-index: 1;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.filters {
|
|
322
|
+
display: flex;
|
|
323
|
+
flex-direction: row;
|
|
324
|
+
flex-wrap: wrap;
|
|
325
|
+
gap: 5px;
|
|
326
|
+
|
|
327
|
+
.tag {
|
|
328
|
+
cursor: pointer;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.view-selector .el-select {
|
|
333
|
+
width: 100px;
|
|
334
|
+
font-family: $font-family;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
.gallery-container,
|
|
338
|
+
.dataset-card-container {
|
|
339
|
+
margin: 1rem;
|
|
340
|
+
margin-top: 0;
|
|
341
|
+
padding: 1rem;
|
|
342
|
+
flex-grow: 1;
|
|
343
|
+
overflow-y: auto;
|
|
344
|
+
scrollbar-width: thin;
|
|
345
|
+
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.06);
|
|
346
|
+
border: solid 1px #e4e7ed;
|
|
347
|
+
background-color: #ffffff;
|
|
348
|
+
border-radius: var(--el-border-radius-base);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
.gallery-container {
|
|
352
|
+
:deep(.gallery) {
|
|
353
|
+
.gallery-strip {
|
|
354
|
+
padding: 1rem 0;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
> div {
|
|
358
|
+
min-height: max-content !important;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
.dataset-card-container {
|
|
364
|
+
display: flex;
|
|
365
|
+
flex-direction: column;
|
|
366
|
+
gap: 1.5rem;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
.dataset-card {
|
|
370
|
+
position: relative;
|
|
371
|
+
|
|
372
|
+
+ .dataset-card {
|
|
373
|
+
padding-top: 1.5rem;
|
|
374
|
+
border-top: 1px solid var(--el-border-color);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
.card {
|
|
379
|
+
position: relative;
|
|
380
|
+
display: flex;
|
|
381
|
+
gap: 1.5rem;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
.card-left {
|
|
385
|
+
flex: 1;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
.card-right {
|
|
389
|
+
flex: 1.3;
|
|
390
|
+
padding-left: 6px;
|
|
391
|
+
display: flex;
|
|
392
|
+
flex-direction: column;
|
|
393
|
+
gap: 1rem;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
.card-image {
|
|
397
|
+
display: block;
|
|
398
|
+
text-decoration: none;
|
|
399
|
+
outline: none;
|
|
400
|
+
|
|
401
|
+
.el-image {
|
|
402
|
+
display: block;
|
|
403
|
+
width: 200px;
|
|
404
|
+
height: 150px;
|
|
405
|
+
|
|
406
|
+
:deep(img) {
|
|
407
|
+
aspect-ratio: 4/3;
|
|
408
|
+
object-fit: cover;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
.image-slot {
|
|
413
|
+
display: flex;
|
|
414
|
+
justify-content: center;
|
|
415
|
+
align-items: center;
|
|
416
|
+
width: 100%;
|
|
417
|
+
height: 100%;
|
|
418
|
+
background: var(--el-fill-color-light);
|
|
419
|
+
color: var(--el-text-color-secondary);
|
|
420
|
+
font-size: 14px;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
.title {
|
|
425
|
+
font-family: $font-family;
|
|
426
|
+
font-size: 14px;
|
|
427
|
+
font-weight: bold;
|
|
428
|
+
font-stretch: normal;
|
|
429
|
+
font-style: normal;
|
|
430
|
+
line-height: 1.5;
|
|
431
|
+
letter-spacing: 1.05px;
|
|
432
|
+
color: #484848;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
.details {
|
|
436
|
+
font-family: $font-family;
|
|
437
|
+
font-size: 14px;
|
|
438
|
+
font-weight: normal;
|
|
439
|
+
font-stretch: normal;
|
|
440
|
+
font-style: normal;
|
|
441
|
+
line-height: 1.5;
|
|
442
|
+
letter-spacing: 1.05px;
|
|
443
|
+
color: #484848;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
.active-tag {
|
|
447
|
+
background-color: $app-primary-color;
|
|
448
|
+
color: #fff;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
.button {
|
|
452
|
+
margin-left: 0px !important;
|
|
453
|
+
margin-top: 0px !important;
|
|
454
|
+
font-size: 14px !important;
|
|
455
|
+
letter-spacing: initial;
|
|
456
|
+
background-color: $app-primary-color;
|
|
457
|
+
color: #fff;
|
|
458
|
+
|
|
459
|
+
& + .button {
|
|
460
|
+
margin-top: 10px !important;
|
|
461
|
+
}
|
|
462
|
+
&:hover {
|
|
463
|
+
color: #fff !important;
|
|
464
|
+
background: #ac76c5 !important;
|
|
465
|
+
border: 1px solid #ac76c5 !important;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
.card-button-link {
|
|
470
|
+
text-decoration: none;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
.float-button-container {
|
|
474
|
+
position: absolute;
|
|
475
|
+
bottom: 0;
|
|
476
|
+
right: 0;
|
|
477
|
+
opacity: 0;
|
|
478
|
+
visibility: hidden;
|
|
479
|
+
|
|
480
|
+
.dataset-card:hover & {
|
|
481
|
+
opacity: 1;
|
|
482
|
+
visibility: visible;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
</style>
|
|
486
|
+
|
|
487
|
+
<style lang="scss">
|
|
488
|
+
.view-selector-select-popper {
|
|
489
|
+
font-family: $font-family;
|
|
490
|
+
font-size: 14px;
|
|
491
|
+
color: #292b66;
|
|
492
|
+
|
|
493
|
+
.el-select-dropdown__item.is-selected {
|
|
494
|
+
color: $app-primary-color;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
</style>
|
|
@@ -22,9 +22,11 @@
|
|
|
22
22
|
</div>
|
|
23
23
|
<div class="sidebar-container">
|
|
24
24
|
<Tabs
|
|
25
|
-
v-if="tabs.length > 1 && connectivityInfo"
|
|
25
|
+
v-if="tabs.length > 1 && (connectivityInfo || imageThumbnails.length)"
|
|
26
26
|
:tabTitles="tabs"
|
|
27
27
|
:activeId="activeTabId"
|
|
28
|
+
:hasConnectivityInfo="!!connectivityInfo"
|
|
29
|
+
:hasImageThumbnails="!!imageThumbnails.length"
|
|
28
30
|
@titleClicked="tabClicked"
|
|
29
31
|
@tab-close="tabClose"
|
|
30
32
|
/>
|
|
@@ -39,6 +41,13 @@
|
|
|
39
41
|
@show-connectivity="showConnectivity"
|
|
40
42
|
/>
|
|
41
43
|
</template>
|
|
44
|
+
<template v-else-if="tab.type === 'images'">
|
|
45
|
+
<ImageThumbnails
|
|
46
|
+
v-if="imageThumbnails.length"
|
|
47
|
+
v-show="tab.id === activeTabId"
|
|
48
|
+
:imageThumbnails="imageThumbnails"
|
|
49
|
+
/>
|
|
50
|
+
</template>
|
|
42
51
|
<template v-else>
|
|
43
52
|
<SidebarContent
|
|
44
53
|
class="sidebar-content-container"
|
|
@@ -68,6 +77,7 @@ import SidebarContent from './SidebarContent.vue'
|
|
|
68
77
|
import EventBus from './EventBus.js'
|
|
69
78
|
import Tabs from './Tabs.vue'
|
|
70
79
|
import ConnectivityInfo from './ConnectivityInfo.vue'
|
|
80
|
+
import ImageThumbnails from './ImageThumbnails.vue'
|
|
71
81
|
|
|
72
82
|
/**
|
|
73
83
|
* Aims to provide a sidebar for searching capability for SPARC portal.
|
|
@@ -81,6 +91,7 @@ export default {
|
|
|
81
91
|
Drawer,
|
|
82
92
|
Icon,
|
|
83
93
|
ConnectivityInfo,
|
|
94
|
+
ImageThumbnails,
|
|
84
95
|
},
|
|
85
96
|
name: 'SideBar',
|
|
86
97
|
props: {
|
|
@@ -108,7 +119,8 @@ export default {
|
|
|
108
119
|
type: Array,
|
|
109
120
|
default: () => [
|
|
110
121
|
{ id: 1, title: 'Search', type: 'search' },
|
|
111
|
-
{ id: 2, title: 'Connectivity', type: 'connectivity' }
|
|
122
|
+
{ id: 2, title: 'Connectivity', type: 'connectivity' },
|
|
123
|
+
{ id: 3, title: 'Images', type: 'images' }, // Temporary
|
|
112
124
|
],
|
|
113
125
|
},
|
|
114
126
|
/**
|
|
@@ -132,6 +144,13 @@ export default {
|
|
|
132
144
|
type: Object,
|
|
133
145
|
default: null,
|
|
134
146
|
},
|
|
147
|
+
/**
|
|
148
|
+
* The image thumbnails data to show in sidebar.
|
|
149
|
+
*/
|
|
150
|
+
imageThumbnails: {
|
|
151
|
+
type: Array,
|
|
152
|
+
default: [],
|
|
153
|
+
},
|
|
135
154
|
},
|
|
136
155
|
data: function () {
|
|
137
156
|
return {
|
|
@@ -260,7 +279,12 @@ export default {
|
|
|
260
279
|
this.$emit('tabClicked', {id, type});
|
|
261
280
|
},
|
|
262
281
|
tabClose: function (id) {
|
|
263
|
-
this
|
|
282
|
+
const closedTab = this.tabs.find((tab) => tab.id === id);
|
|
283
|
+
if (closedTab.type === 'connectivity') {
|
|
284
|
+
this.$emit('connectivity-info-close');
|
|
285
|
+
} else if (closedTab.type === 'images') {
|
|
286
|
+
this.$emit('image-thumbnail-close');
|
|
287
|
+
}
|
|
264
288
|
},
|
|
265
289
|
},
|
|
266
290
|
created: function () {
|
package/src/components/Tabs.vue
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<div class="tab-container">
|
|
3
3
|
<div
|
|
4
4
|
class="title"
|
|
5
|
-
v-for="title in
|
|
5
|
+
v-for="title in titles"
|
|
6
6
|
:key="title.id"
|
|
7
7
|
:class="{ 'active-tab': title.id == activeId }"
|
|
8
8
|
>
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
</div>
|
|
17
17
|
</div>
|
|
18
18
|
<el-button
|
|
19
|
-
v-if="title.
|
|
19
|
+
v-if="title.type === 'connectivity' || title.type === 'images'"
|
|
20
20
|
@click="tabClose(title.id)"
|
|
21
21
|
class="button-tab-close"
|
|
22
22
|
aria-label="Close"
|
|
@@ -42,6 +42,25 @@ export default {
|
|
|
42
42
|
type: Number,
|
|
43
43
|
default: 1,
|
|
44
44
|
},
|
|
45
|
+
hasConnectivityInfo: {
|
|
46
|
+
type: Boolean,
|
|
47
|
+
default: true,
|
|
48
|
+
},
|
|
49
|
+
hasImageThumbnails: {
|
|
50
|
+
type: Boolean,
|
|
51
|
+
default: true,
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
computed: {
|
|
55
|
+
titles: function() {
|
|
56
|
+
if (!this.hasConnectivityInfo) {
|
|
57
|
+
return this.tabTitles.filter((tab) => tab.type !== 'connectivity');
|
|
58
|
+
}
|
|
59
|
+
else if (!this.hasImageThumbnails) {
|
|
60
|
+
return this.tabTitles.filter((tab) => tab.type !== 'images');
|
|
61
|
+
}
|
|
62
|
+
return this.tabTitles;
|
|
63
|
+
},
|
|
45
64
|
},
|
|
46
65
|
methods: {
|
|
47
66
|
titleClicked: function (id, type) {
|
|
@@ -73,6 +92,7 @@ $tab-height: 30px;
|
|
|
73
92
|
align-items: center;
|
|
74
93
|
position: relative;
|
|
75
94
|
cursor: pointer;
|
|
95
|
+
z-index: 2;
|
|
76
96
|
}
|
|
77
97
|
|
|
78
98
|
.title-text {
|