49
49
<div v-if =" description" v-html =" description" />
50
50
51
51
<b-tabs v-model =" tabIndex" >
52
+ <b-tab
53
+ v-if =" visibleTabs.includes('collections')"
54
+ key =" collections"
55
+ title =" Collections (API)"
56
+ >
57
+ <b-table
58
+ :items =" collections"
59
+ :fields =" collectionFields"
60
+ :per-page =" childrenPerPage"
61
+ :current-page =" currentCollectionPage"
62
+ :outlined =" true"
63
+ responsive
64
+ small
65
+ striped
66
+ >
67
+ <template slot="cell(link)" slot-scope="data">
68
+ <router-link :to =" data.item.to" >{{
69
+ data.item.id
70
+ }}</router-link >
71
+ </template >
72
+ </b-table >
73
+ <b-pagination
74
+ v-if =" collectionCount > childrenPerPage"
75
+ v-model =" currentCollectionPage"
76
+ :limit =" 15"
77
+ :total-rows =" collectionCount"
78
+ :per-page =" childrenPerPage"
79
+ :hide-goto-end-buttons =" true"
80
+ />
81
+ </b-tab >
82
+
52
83
<b-tab
53
84
v-if =" visibleTabs.includes('catalogs')"
54
85
key =" catalogs"
@@ -181,6 +212,8 @@ import MetadataSidebar from './MetadataSidebar.vue'
181
212
182
213
import { transformCatalog } from " ../migrate"
183
214
215
+ import { fetchUri } from " ../util" ;
216
+
184
217
const ITEMS_PER_PAGE = 25 ;
185
218
186
219
export default {
@@ -229,13 +262,26 @@ export default {
229
262
sortable: true
230
263
}
231
264
],
265
+ collectionFields: [
266
+ {
267
+ key: " link" ,
268
+ label: " Identifier" ,
269
+ sortable: false // Sorting doesn't work for links
270
+ },
271
+ {
272
+ key: " title" ,
273
+ label: " Title" ,
274
+ sortable: true
275
+ }
276
+ ],
232
277
currentChildPage: 1 ,
233
- childrenPerPage: 25 ,
278
+ currentCollectionPage: 1 ,
279
+ childrenPerPage: 25 , // also applies to collections
234
280
itemFields: [
235
281
{
236
282
key: " link" ,
237
283
label: " Title" ,
238
- sortable: true
284
+ sortable: false // Sorting doesn't work for links
239
285
},
240
286
{
241
287
key: " dateAcquired" ,
@@ -259,18 +305,75 @@ export default {
259
305
};
260
306
},
261
307
asyncComputed: {
308
+ collections: {
309
+ default: [],
310
+ lazy: true ,
311
+ async get () {
312
+ const externalCollections = this .links .find (x => x .rel === " data" );
313
+ if (externalCollections === undefined ) {
314
+ return [];
315
+ }
316
+
317
+ try {
318
+ const rsp = await fetchUri (externalCollections .href );
319
+ if (! rsp .ok ) {
320
+ console .warn (await rsp .text ());
321
+ return [];
322
+ }
323
+
324
+ const data = await rsp .json ();
325
+ if (! data || ! Array .isArray (data .collections )) {
326
+ console .warn (await rsp .text ());
327
+ return [];
328
+ }
329
+
330
+ return data .collections
331
+ .map (collection => {
332
+ // strip /collection from the target path
333
+ let p = this .path .replace (/ ^ \/ collection/ , " " );
334
+ if (! p .endsWith (" /" )) {
335
+ p += " /" ;
336
+ }
337
+
338
+ // Try to get the location of the collection
339
+ let href = externalCollections .href + ' /collections/' + collection .id ;
340
+ if (Array .isArray (collection .links )) {
341
+ let selfLink = collection .links .find (l => l .rel == ' self' );
342
+ if (selfLink && selfLink .href ) {
343
+ href = selfLink .href ;
344
+ }
345
+ }
346
+
347
+ const resolved = this .resolve (href, this .url );
348
+ const slug = this .slugify (resolved);
349
+ const to = [p, slug].join (" " );
350
+
351
+ return Object .assign (collection, {
352
+ path: href,
353
+ to,
354
+ title: collection .title || collection .id || href,
355
+ url: resolved
356
+ });
357
+ });
358
+ } catch (err) {
359
+ console .warn (err);
360
+
361
+ return [];
362
+ }
363
+ }
364
+ },
262
365
externalItems: {
263
366
default: [],
264
367
lazy: true ,
265
368
async get () {
266
369
const externalItemsLink = this .links .find (x => x .rel === " items" );
267
370
268
- if (externalItemsLink == null ) {
371
+ if (externalItemsLink === undefined ) {
269
372
return [];
270
373
}
271
374
272
375
try {
273
- const rsp = await fetch (
376
+ const rsp = await fetchUri (
274
377
` ${ externalItemsLink .href } ?page=${ this .currentItemPage } `
275
378
);
276
379
@@ -347,8 +450,11 @@ export default {
347
450
catalog () {
348
451
return this .entity ;
349
452
},
453
+ collectionCount () {
454
+ return this .collections .length ;
455
+ },
350
456
childCount () {
351
- return this .links . filter ( x => x . rel === " child " ) .length ;
457
+ return this .children .length ;
352
458
},
353
459
children () {
354
460
return this .links
@@ -361,15 +467,16 @@ export default {
361
467
p += " /" ;
362
468
}
363
469
364
- const slug = this .slugify (this .resolve (child .href , this .url ));
470
+ const resolved = this .resolve (child .href , this .url );
471
+ const slug = this .slugify (resolved);
365
472
const to = [p, slug].join (" " );
366
473
367
474
return {
368
475
path: child .href ,
369
476
to,
370
477
// child.id is a workaround for https://earthengine-stac.storage.googleapis.com/catalog/catalog.json
371
478
title: child .title || child .id || child .href ,
372
- url: this . resolve ( child . href , this . url )
479
+ url: resolved
373
480
};
374
481
});
375
482
},
@@ -616,6 +723,7 @@ export default {
616
723
},
617
724
visibleTabs () {
618
725
return [
726
+ this .collectionCount > 0 && " collections" ,
619
727
this .childCount > 0 && " catalogs" ,
620
728
(this .hasExternalItems || this .itemCount > 0 ) && " items" ,
621
729
this .bands .length > 0 && " bands" ,
0 commit comments