@abi-software/map-side-bar 1.3.37 → 1.3.38-staging

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.
Files changed (37) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +146 -146
  3. package/babel.config.js +14 -14
  4. package/del.json +27 -0
  5. package/dist/map-side-bar.common.js +2082 -1229
  6. package/dist/map-side-bar.common.js.map +1 -1
  7. package/dist/map-side-bar.css +1 -1
  8. package/dist/map-side-bar.umd.js +2082 -1229
  9. package/dist/map-side-bar.umd.js.map +1 -1
  10. package/dist/map-side-bar.umd.min.js +3 -1
  11. package/dist/map-side-bar.umd.min.js.map +1 -1
  12. package/package-lock.json +13716 -13716
  13. package/package.json +67 -67
  14. package/public/index.html +17 -17
  15. package/scaffold_context_info.json +31 -0
  16. package/src/App.vue +149 -155
  17. package/src/algolia/algolia.js +182 -182
  18. package/src/algolia/utils.js +69 -69
  19. package/src/components/BadgesGroup.vue +141 -142
  20. package/src/components/Cascader.vue +49 -49
  21. package/src/components/ContextCard.vue +384 -391
  22. package/src/components/DatasetCard.vue +385 -325
  23. package/src/components/EventBus.js +3 -3
  24. package/src/components/ImageGallery.vue +509 -525
  25. package/src/components/SearchFilters.vue +609 -585
  26. package/src/components/SideBar.vue +245 -224
  27. package/src/components/SidebarContent.vue +511 -508
  28. package/src/components/Tabs.vue +78 -78
  29. package/src/components/hardcoded-context-info.js +79 -79
  30. package/src/components/index.js +8 -8
  31. package/src/components/processFilters.js +22 -0
  32. package/src/components/species-map.js +8 -8
  33. package/src/main.js +8 -8
  34. package/src/mixins/GalleryHelpers.js +104 -0
  35. package/static.json +6 -6
  36. package/vue.config.js +11 -11
  37. package/src/mixins/S3Bucket.vue +0 -31
@@ -1,391 +1,384 @@
1
- <template>
2
- <div class="context-card-container" ref="container">
3
- <div v-show="showContextCard">
4
- <div v-show="showDetails" class="hide" @click="showDetails = !showDetails">Hide information<i class="el-icon-arrow-up"></i></div>
5
- <div v-show="!showDetails" class="hide" @click="showDetails = !showDetails">Show information<i class="el-icon-arrow-down"></i></div>
6
- <el-card v-if="showDetails && Object.keys(contextData).length !== 0" v-loading="loading" class="context-card" >
7
- <div class="card-left">
8
- <img :src="banner" class="context-image">
9
- </div>
10
- <div class="card-right scrollbar">
11
- <div class="title">{{contextData.heading}}</div>
12
- <div v-html="parseMarkdown(contextData.description)"/>
13
- <br/>
14
-
15
- <!-- Show sampeles and views seperately if they do not match -->
16
- <template v-if="!samplesUnderViews">
17
- <div v-if="contextData.views && contextData.views.length > 0" class="subtitle">Scaffold Views</div>
18
- <template v-for="(view, i) in contextData.views">
19
- <div v-bind:key="i+'_1'" @click="openViewFile(view)" class="context-card-view">
20
- <img class="view-image" :src="getFileFromPath(view.thumbnail)">
21
- <div class="view-description">{{view.description}}</div>
22
- </div>
23
- <div v-bind:key="i" class="padding"/>
24
- </template>
25
- <div style="margin-bottom: 16px;"/>
26
- <div v-if="contextData.samples && contextData.samples.length > 0" class="subtitle">Samples on Scaffold</div>
27
- <template v-for="(sample, i) in contextData.samples">
28
- <span v-bind:key="i+'_3'" class="context-card-item cursor-pointer" @click="toggleSampleDetails(i)">
29
- <div v-bind:key="i+'_6'" style="display: flex">
30
- <div v-if="sample.color" class="color-box" :style="'background-color:'+ sample.color"></div>
31
- <img class="key-image" v-else-if="sample.thumbnail" :src="getFileFromPath(sample.thumbnail)">
32
- {{sample.heading}}
33
- <i class="el-icon-warning-outline info"></i>
34
- </div>
35
- </span>
36
- <div v-bind:key="i+'_4'" v-if="sampleDetails[i]" v-html="sample.description"/>
37
- <a v-bind:key="i+'_5'" v-if="sampleDetails[i] && sample.path" :href="generateFileLink(sample)" target="_blank">View Source</a>
38
- <div v-bind:key="i+'_2'" class="padding"/>
39
- </template>
40
- </template>
41
-
42
- <!-- Show samples under views if the ids match -->
43
- <template v-else>
44
- <div v-if="contextData.views && contextData.views.length > 0" class="subtitle">Scaffold Views</div>
45
- <template v-for="(view, i) in contextData.views">
46
- <span :key="i+'_1'" @click="viewClicked(view, i)" class="context-card-view">
47
- <img class="view-image" :src="getFileFromPath(view.thumbnail)"/>
48
- <div class="view-description">{{view.description}}<i class="el-icon-warning-outline info"></i> </div>
49
- </span>
50
- <div v-if="sampleDetails[i]" v-html="samplesMatching(view.id).description" :key="i+'_2'"/>
51
- <a v-bind:key="i+'_5'" v-if="sampleDetails[i] && samplesMatching(view.id).path" :href="generateFileLink(samplesMatching(view.id))" target="_blank">View Source</a>
52
- <div :key="i" class="padding"/>
53
-
54
- <!-- Extra padding if sample details is open -->
55
- <div :key="i+'_6'" v-if="sampleDetails[i]" class="padding"/>
56
- </template>
57
- </template>
58
- </div>
59
- </el-card>
60
- </div>
61
- </div>
62
- </template>
63
-
64
-
65
- <script>
66
- /* eslint-disable no-alert, no-console */
67
- import Vue from "vue";
68
- import { Link, Icon, Card, Button, Select, Input } from "element-ui";
69
- import lang from "element-ui/lib/locale/lang/en";
70
- import locale from "element-ui/lib/locale";
71
- import EventBus from "./EventBus"
72
- import hardcoded_info from './hardcoded-context-info'
73
-
74
- //provide the s3Bucket related methods and data.
75
- import S3Bucket from "../mixins/S3Bucket";
76
-
77
- import { marked } from 'marked'
78
- import xss from 'xss'
79
-
80
- locale.use(lang);
81
- Vue.use(Link);
82
- Vue.use(Icon);
83
- Vue.use(Card);
84
- Vue.use(Button);
85
- Vue.use(Select);
86
- Vue.use(Input);
87
-
88
- const addFilesToPathIfMissing = function(path){
89
- if (!path.includes('files')){
90
- return 'files/' + path
91
- } else {
92
- return path
93
- }
94
- }
95
-
96
- const convertBackslashToForwardSlash = function(path){
97
- path = path.replaceAll('\\','/')
98
- path = path.replaceAll('\\\\', '/')
99
- return path
100
- }
101
-
102
- // const switchPathToDirectory = function(path){
103
- // let newPath = path.split('/')
104
- // newPath.pop()
105
- // return newPath.join('/')
106
- // }
107
-
108
-
109
- export default {
110
- name: "contextCard",
111
- mixins: [S3Bucket],
112
- props: {
113
- /**
114
- * Object containing information for
115
- * the required viewing.
116
- */
117
- entry: Object,
118
- envVars: Object,
119
- },
120
- data: function () {
121
- return {
122
- contextData: {},
123
- showDetails: true,
124
- showContextCard: true,
125
- sampleDetails: {},
126
- loading: false
127
- };
128
- },
129
- watch: {
130
- 'entry.contextCardUrl': {
131
- handler(val){
132
- if (val) {
133
- // used for hardcoding data
134
- if (val === true){
135
- this.contextData = hardcoded_info[this.entry.discoverId]
136
- } else {
137
- this.getContextFile(val)
138
- this.showContextCard = true
139
- }
140
- } else {
141
- this.showContextCard = false
142
- }
143
- },
144
- immediate: true
145
- },
146
- 'entry.s3uri': {
147
- handler(val){
148
- this.updateS3Bucket(val);
149
- },
150
- immediate: true
151
- }
152
- },
153
- computed: {
154
- samplesUnderViews: function(){
155
- if (this.contextData){
156
- if (this.contextData.samplesUnderViews){
157
- return true
158
- } else {
159
- let viewId = this.contextData.views.map(v=>v.id)
160
- let samplesView = this.contextData.samples.map(s=>s.view)
161
-
162
- // get matching values
163
- let matching = viewId.filter(v=>samplesView.includes(v))
164
-
165
- // check all arrays have the same length (which means all values are in all three)
166
- if ( viewId.length === matching.length && matching.length === samplesView.length){
167
- return true
168
- }
169
- return false
170
- }
171
- }
172
- else return false
173
- },
174
- banner: function(){
175
- if (this.contextData.banner){
176
- return this.getFileFromPath(this.contextData.banner)
177
- } else if (this.contextData && this.contextData.views && this.contextData.views.length > 0) {
178
- if(this.contextData.views[0].thumbnail){
179
- return this.getFileFromPath(this.contextData.views[0].thumbnail)
180
- }
181
- }
182
- return this.entry.banner
183
- }
184
- },
185
- methods: {
186
- samplesMatching: function(viewId){
187
- if (this.contextData && this.contextData.samples){
188
- return this.contextData.samples.filter(s=>s.view == viewId)[0]
189
- }
190
- else return []
191
- },
192
- viewClicked: function(view, i){
193
- this.openViewFile(view)
194
- this.toggleSampleDetails(i)
195
- },
196
- getContextFile: function (contextFileUrl) {
197
- this.loading = true
198
- fetch(contextFileUrl)
199
- .then((response) =>{
200
- if (!response.ok){
201
- throw Error(response.statusText)
202
- } else {
203
- return response.json()
204
- }
205
- })
206
- .then((data) => {
207
- this.contextData = data
208
- this.loading = false
209
- this.addDiscoverIdsToContextData()
210
- })
211
- .catch((err) => {
212
- //set defaults if we hit an error
213
- console.error('caught error!', err)
214
- this.thumbnail = require('@/../assets/missing-image.svg')
215
- this.discoverId = undefined
216
- this.loading = false
217
- });
218
- },
219
- removeDoubleFilesPath: function(path){
220
- if (path.includes('files/')){
221
- return path.replace('files/', '')
222
- } else if (path.includes('files\\')) {
223
- return path.replace('files\\', '')
224
- } else {
225
- return path
226
- }
227
- },
228
- toggleSampleDetails: function(i){
229
- if (this.sampleDetails[i] === undefined){
230
- Vue.set(this.sampleDetails, i, true)
231
- } else {
232
- Vue.set(this.sampleDetails, i, !this.sampleDetails[i])
233
- }
234
- },
235
- getFileFromPath: function(path){
236
- // for hardcoded data
237
- if(this.entry.contextCardUrl === true){
238
- return path
239
- }
240
- path = this.removeDoubleFilesPath(path)
241
- return `${this.envVars.API_LOCATION}s3-resource/${this.entry.discoverId}/${this.entry.version}/files/${path}${this.getS3Args()}`
242
- },
243
- // This is used later when generateing links to the resource on sparc.science (see generateFileLink)
244
- addDiscoverIdsToContextData(){
245
- this.contextData.samples.forEach((sample, i)=>{
246
- if (sample && sample.doi && sample.doi !== ""){
247
- fetch(`${this.envVars.PENNSIEVE_API_LOCATION}/discover/datasets/doi/${this.splitDoiFromUrl(sample.doi)}`)
248
- .then((response) => response.json())
249
- .then((data) => {
250
- this.contextData.samples[i].discoverId = data.id
251
- this.contextData.samples[i].version = data.version
252
- })
253
- } else {
254
- this.contextData.samples[i].discoverId = this.entry.discoverId
255
- this.contextData.samples[i].version = this.entry.version
256
- }
257
- })
258
- },
259
- processPathForUrl(path){
260
- path = convertBackslashToForwardSlash(path)
261
- path = addFilesToPathIfMissing(path)
262
- return encodeURI(path)
263
- },
264
- splitDoiFromUrl(url){
265
- return url.split('https://doi.org/').pop()
266
- },
267
- generateFileLink(sample){
268
- return `${this.envVars.ROOT_URL}/file/${sample.discoverId}/${sample.version}?path=${this.processPathForUrl(sample.path)}`
269
-
270
- },
271
- parseMarkdown(markdown){
272
- return xss(marked.parse(markdown))
273
- },
274
- openViewFile: function(view){
275
- // note that we assume that the view file is in the same directory as the scaffold (viewUrls take relative paths)
276
- this.entry.viewUrl = `${this.envVars.API_LOCATION}s3-resource/${this.entry.discoverId}/${this.entry.version}/${view.path}${this.getS3Args()}`
277
- this.entry.type = 'Scaffold View'
278
- EventBus.$emit("PopoverActionClick", this.entry)
279
- }
280
- }
281
- };
282
- </script>
283
-
284
- <!-- Add "scoped" attribute to limit CSS to this component only -->
285
- <style scoped>
286
-
287
- .hide{
288
- color: #e4e7ed;
289
- cursor: pointer;
290
- }
291
-
292
- .context-card{
293
- background-color: white;
294
- max-height: 10 50px;
295
- padding: 8px;
296
- font-size: 14px;
297
- margin-bottom: 18px;
298
- position: relative;
299
- border: solid 1px #e4e7ed;
300
- display: flex;
301
- width: 500px;
302
- max-height: 258px;
303
- }
304
-
305
- .context-card-view{
306
- cursor: pointer;
307
- padding-bottom: 8px;
308
- display: flex;
309
- }
310
-
311
- .view-image {
312
- width: 34px;
313
- height: 34px;
314
- flex: 1;
315
- margin-right: 4px;
316
- }
317
-
318
- .view-descriptions {
319
- flex: 8;
320
- }
321
-
322
- .context-card >>> .el-card__body {
323
- padding: 0px;
324
- display: flex;
325
- width: 516px;
326
- }
327
-
328
- .context-image{
329
- width: 250px;
330
- height: auto;
331
- }
332
-
333
- .color-box {
334
- width: 16px;
335
- height: 16px;
336
- border: solid 1px #8300bf;
337
- border-radius: 2px;
338
- margin-right: 8px;
339
- }
340
-
341
- .card-left{
342
- flex: 1
343
- }
344
-
345
- .card-right {
346
- flex: 1.3;
347
- padding-left: 6px;
348
- overflow-y: scroll;
349
- scrollbar-width: thin;
350
- }
351
-
352
- .cursor-pointer {
353
- cursor: pointer;
354
- }
355
-
356
- .info{
357
- transform: rotate(180deg);
358
- color: #8300bf;
359
- margin-left: 8px;
360
- }
361
-
362
- .padding {
363
- padding-bottom: 8px;
364
- }
365
-
366
- .title{
367
- font-weight: bold;
368
- }
369
-
370
- .subtitle{
371
- font-weight: bold;
372
- }
373
-
374
- .scrollbar::-webkit-scrollbar-track {
375
- border-radius: 10px;
376
- background-color: #f5f5f5;
377
- }
378
-
379
- .scrollbar::-webkit-scrollbar {
380
- width: 12px;
381
- right: -12px;
382
- background-color: #f5f5f5;
383
- }
384
-
385
- .scrollbar::-webkit-scrollbar-thumb {
386
- border-radius: 4px;
387
- box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.06);
388
- background-color: #979797;
389
- }
390
-
391
- </style>
1
+ <template>
2
+ <div class="context-card-container" ref="container">
3
+ <div v-show="showContextCard">
4
+ <div v-show="showDetails" class="hide" @click="showDetails = !showDetails">Hide information<i class="el-icon-arrow-up"></i></div>
5
+ <div v-show="!showDetails" class="hide" @click="showDetails = !showDetails">Show information<i class="el-icon-arrow-down"></i></div>
6
+ <el-card v-if="showDetails && Object.keys(contextData).length !== 0" v-loading="loading" class="context-card" >
7
+ <div class="card-left">
8
+ <img :src="banner" class="context-image">
9
+ </div>
10
+ <div class="card-right scrollbar">
11
+ <div class="title">{{contextData.heading}}</div>
12
+ <div v-html="parseMarkdown(contextData.description)"/>
13
+ <br/>
14
+
15
+ <!-- Show sampeles and views seperately if they do not match -->
16
+ <template v-if="!samplesUnderViews">
17
+ <div v-if="contextData.views && contextData.views.length > 0" class="subtitle">Scaffold Views</div>
18
+ <template v-for="(view, i) in contextData.views">
19
+ <div v-bind:key="i+'_1'" @click="openViewFile(view)" class="context-card-view">
20
+ <img class="view-image" :src="getFileFromPath(view.thumbnail)">
21
+ <div class="view-description">{{view.description}}</div>
22
+ </div>
23
+ <div v-bind:key="i" class="padding"/>
24
+ </template>
25
+ <div style="margin-bottom: 16px;"/>
26
+ <div v-if="contextData.samples && contextData.samples.length > 0" class="subtitle">Samples on Scaffold</div>
27
+ <template v-for="(sample, i) in contextData.samples">
28
+ <span v-bind:key="i+'_3'" class="context-card-item cursor-pointer" @click="toggleSampleDetails(i)">
29
+ <div v-bind:key="i+'_6'" style="display: flex">
30
+ <div v-if="sample.color" class="color-box" :style="'background-color:'+ sample.color"></div>
31
+ <img class="key-image" v-else-if="sample.thumbnail" :src="getFileFromPath(sample.thumbnail)">
32
+ {{sample.heading}}
33
+ <i class="el-icon-warning-outline info"></i>
34
+ </div>
35
+ </span>
36
+ <div v-bind:key="i+'_4'" v-if="sampleDetails[i]" v-html="sample.description"/>
37
+ <a v-bind:key="i+'_5'" v-if="sampleDetails[i] && sample.path" :href="generateFileLink(sample)" target="_blank">View Source</a>
38
+ <div v-bind:key="i+'_2'" class="padding"/>
39
+ </template>
40
+ </template>
41
+
42
+ <!-- Show samples under views if the ids match -->
43
+ <template v-else>
44
+ <div v-if="contextData.views && contextData.views.length > 0" class="subtitle">Scaffold Views</div>
45
+ <template v-for="(view, i) in contextData.views">
46
+ <span :key="i+'_1'" @click="viewClicked(view, i)" class="context-card-view">
47
+ <img class="view-image" :src="getFileFromPath(view.thumbnail)"/>
48
+ <div class="view-description">{{view.description}}<i class="el-icon-warning-outline info"></i> </div>
49
+ </span>
50
+ <div v-if="sampleDetails[i]" v-html="samplesMatching(view.id).description" :key="i+'_2'"/>
51
+ <a v-bind:key="i+'_5'" v-if="sampleDetails[i] && samplesMatching(view.id).path" :href="generateFileLink(samplesMatching(view.id))" target="_blank">View Source</a>
52
+ <div :key="i" class="padding"/>
53
+
54
+ <!-- Extra padding if sample details is open -->
55
+ <div :key="i+'_6'" v-if="sampleDetails[i]" class="padding"/>
56
+ </template>
57
+ </template>
58
+ </div>
59
+ </el-card>
60
+ </div>
61
+ </div>
62
+ </template>
63
+
64
+
65
+ <script>
66
+ /* eslint-disable no-alert, no-console */
67
+ import Vue from "vue";
68
+ import { Link, Icon, Card, Button, Select, Input } from "element-ui";
69
+ import lang from "element-ui/lib/locale/lang/en";
70
+ import locale from "element-ui/lib/locale";
71
+ import EventBus from "./EventBus"
72
+ import hardcoded_info from './hardcoded-context-info'
73
+
74
+ import { marked } from 'marked'
75
+ import xss from 'xss'
76
+
77
+ locale.use(lang);
78
+ Vue.use(Link);
79
+ Vue.use(Icon);
80
+ Vue.use(Card);
81
+ Vue.use(Button);
82
+ Vue.use(Select);
83
+ Vue.use(Input);
84
+
85
+ const addFilesToPathIfMissing = function(path){
86
+ if (!path.includes('files')){
87
+ return 'files/' + path
88
+ } else {
89
+ return path
90
+ }
91
+ }
92
+
93
+ const convertBackslashToForwardSlash = function(path){
94
+ path = path.replaceAll('\\','/')
95
+ path = path.replaceAll('\\\\', '/')
96
+ return path
97
+ }
98
+
99
+ // const switchPathToDirectory = function(path){
100
+ // let newPath = path.split('/')
101
+ // newPath.pop()
102
+ // return newPath.join('/')
103
+ // }
104
+
105
+
106
+ export default {
107
+ name: "contextCard",
108
+ props: {
109
+ /**
110
+ * Object containing information for
111
+ * the required viewing.
112
+ */
113
+ entry: Object,
114
+ envVars: Object,
115
+ },
116
+ data: function () {
117
+ return {
118
+ contextData: {},
119
+ showDetails: true,
120
+ showContextCard: true,
121
+ sampleDetails: {},
122
+ loading: false
123
+ };
124
+ },
125
+ watch: {
126
+ 'entry.contextCardUrl': {
127
+ handler(val){
128
+ if (val) {
129
+ // used for hardcoding data
130
+ if (val === true){
131
+ this.contextData = hardcoded_info[this.entry.discoverId]
132
+ } else {
133
+ this.getContextFile(val)
134
+ this.showContextCard = true
135
+ }
136
+ } else {
137
+ this.showContextCard = false
138
+ }
139
+ },
140
+ immediate: true
141
+ }
142
+ },
143
+ computed: {
144
+ samplesUnderViews: function(){
145
+ if (this.contextData){
146
+ if (!this.contextData.views || !this.contextData.samples){
147
+ return false
148
+ }
149
+ if (this.contextData.samplesUnderViews){
150
+ return this.contextData.samplesUnderViews
151
+ } else {
152
+ let viewId = this.contextData.views.map(v=>v.id)
153
+ let samplesView = this.contextData.samples.map(s=>s.view)
154
+
155
+ // get matching values
156
+ let matching = viewId.filter(v=>samplesView.includes(v))
157
+
158
+ // check all arrays have the same length (which means all values are in all three)
159
+ if ( viewId.length === matching.length && matching.length === samplesView.length){
160
+ return true
161
+ }
162
+ return false
163
+ }
164
+ }
165
+ else return false
166
+ },
167
+ banner: function(){
168
+ if (this.contextData.banner){
169
+ return this.getFileFromPath(this.contextData.banner)
170
+ } else if (this.contextData && this.contextData.views && this.contextData.views.length > 0) {
171
+ if(this.contextData.views[0].thumbnail){
172
+ return this.getFileFromPath(this.contextData.views[0].thumbnail)
173
+ }
174
+ }
175
+ return this.entry.banner
176
+ }
177
+ },
178
+ methods: {
179
+ samplesMatching: function(viewId){
180
+ if (this.contextData && this.contextData.samples){
181
+ return this.contextData.samples.filter(s=>s.view == viewId)[0]
182
+ }
183
+ else return []
184
+ },
185
+ viewClicked: function(view, i){
186
+ this.openViewFile(view)
187
+ this.toggleSampleDetails(i)
188
+ },
189
+ getContextFile: function (contextFileUrl) {
190
+ this.loading = true
191
+ fetch(contextFileUrl)
192
+ .then((response) =>{
193
+ if (!response.ok){
194
+ throw Error(response.statusText)
195
+ } else {
196
+ return response.json()
197
+ }
198
+ })
199
+ .then((data) => {
200
+ this.contextData = data
201
+ this.loading = false
202
+ this.addDiscoverIdsToContextData()
203
+ })
204
+ .catch((err) => {
205
+ //set defaults if we hit an error
206
+ console.error('caught error!', err)
207
+ this.thumbnail = require('@/../assets/missing-image.svg')
208
+ this.discoverId = undefined
209
+ this.loading = false
210
+ });
211
+ },
212
+ removeDoubleFilesPath: function(path){
213
+ if (path.includes('files/')){
214
+ return path.replace('files/', '')
215
+ } else if (path.includes('files\\')) {
216
+ return path.replace('files\\', '')
217
+ } else {
218
+ return path
219
+ }
220
+ },
221
+ toggleSampleDetails: function(i){
222
+ if (this.sampleDetails[i] === undefined){
223
+ Vue.set(this.sampleDetails, i, true)
224
+ } else {
225
+ Vue.set(this.sampleDetails, i, !this.sampleDetails[i])
226
+ }
227
+ },
228
+ getFileFromPath: function(path){
229
+ // for hardcoded data
230
+ if(this.entry.contextCardUrl === true){
231
+ return path
232
+ }
233
+ path = this.removeDoubleFilesPath(path)
234
+ return `${this.envVars.API_LOCATION}s3-resource/${this.entry.discoverId}/${this.entry.version}/files/${path}`
235
+ },
236
+ // This is used later when generateing links to the resource on sparc.science (see generateFileLink)
237
+ addDiscoverIdsToContextData(){
238
+ this.contextData.samples.forEach((sample, i)=>{
239
+ if (sample && sample.doi && sample.doi !== ""){
240
+ fetch(`${this.envVars.PENNSIEVE_API_LOCATION}/discover/datasets/doi/${this.splitDoiFromUrl(sample.doi)}`)
241
+ .then((response) => response.json())
242
+ .then((data) => {
243
+ this.contextData.samples[i].discoverId = data.id
244
+ this.contextData.samples[i].version = data.version
245
+ })
246
+ } else {
247
+ this.contextData.samples[i].discoverId = this.entry.discoverId
248
+ this.contextData.samples[i].version = this.entry.version
249
+ }
250
+ })
251
+ },
252
+ processPathForUrl(path){
253
+ path = convertBackslashToForwardSlash(path)
254
+ path = addFilesToPathIfMissing(path)
255
+ return encodeURI(path)
256
+ },
257
+ splitDoiFromUrl(url){
258
+ return url.split('https://doi.org/').pop()
259
+ },
260
+ generateFileLink(sample){
261
+ return `${this.envVars.ROOT_URL}/file/${sample.discoverId}/${sample.version}?path=${this.processPathForUrl(sample.path)}`
262
+
263
+ },
264
+ parseMarkdown(markdown){
265
+ return xss(marked.parse(markdown))
266
+ },
267
+ openViewFile: function(view){
268
+ // note that we assume that the view file is in the same directory as the scaffold (viewUrls take relative paths)
269
+ this.entry.viewUrl = `${this.envVars.API_LOCATION}s3-resource/${this.entry.discoverId}/${this.entry.version}/${view.path}`
270
+ this.entry.type = 'Scaffold View'
271
+ EventBus.$emit("PopoverActionClick", this.entry)
272
+ }
273
+ }
274
+ };
275
+ </script>
276
+
277
+ <!-- Add "scoped" attribute to limit CSS to this component only -->
278
+ <style scoped>
279
+
280
+ .hide{
281
+ color: #e4e7ed;
282
+ cursor: pointer;
283
+ }
284
+
285
+ .context-card{
286
+ background-color: white;
287
+ max-height: 10 50px;
288
+ padding: 8px;
289
+ font-size: 14px;
290
+ margin-bottom: 18px;
291
+ position: relative;
292
+ border: solid 1px #e4e7ed;
293
+ display: flex;
294
+ width: 500px;
295
+ max-height: 258px;
296
+ }
297
+
298
+ .context-card-view{
299
+ cursor: pointer;
300
+ padding-bottom: 8px;
301
+ display: flex;
302
+ }
303
+
304
+ .view-image {
305
+ width: 34px;
306
+ height: 34px;
307
+ flex: 1;
308
+ margin-right: 4px;
309
+ }
310
+
311
+ .view-descriptions {
312
+ flex: 8;
313
+ }
314
+
315
+ .context-card >>> .el-card__body {
316
+ padding: 0px;
317
+ display: flex;
318
+ width: 516px;
319
+ }
320
+
321
+ .context-image{
322
+ width: 250px;
323
+ height: auto;
324
+ }
325
+
326
+ .color-box {
327
+ width: 16px;
328
+ height: 16px;
329
+ border: solid 1px #8300bf;
330
+ border-radius: 2px;
331
+ margin-right: 8px;
332
+ }
333
+
334
+ .card-left{
335
+ flex: 1
336
+ }
337
+
338
+ .card-right {
339
+ flex: 1.3;
340
+ padding-left: 6px;
341
+ overflow-y: scroll;
342
+ scrollbar-width: thin;
343
+ }
344
+
345
+ .cursor-pointer {
346
+ cursor: pointer;
347
+ }
348
+
349
+ .info{
350
+ transform: rotate(180deg);
351
+ color: #8300bf;
352
+ margin-left: 8px;
353
+ }
354
+
355
+ .padding {
356
+ padding-bottom: 8px;
357
+ }
358
+
359
+ .title{
360
+ font-weight: bold;
361
+ }
362
+
363
+ .subtitle{
364
+ font-weight: bold;
365
+ }
366
+
367
+ .scrollbar::-webkit-scrollbar-track {
368
+ border-radius: 10px;
369
+ background-color: #f5f5f5;
370
+ }
371
+
372
+ .scrollbar::-webkit-scrollbar {
373
+ width: 12px;
374
+ right: -12px;
375
+ background-color: #f5f5f5;
376
+ }
377
+
378
+ .scrollbar::-webkit-scrollbar-thumb {
379
+ border-radius: 4px;
380
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.06);
381
+ background-color: #979797;
382
+ }
383
+
384
+ </style>