Skip to content

Commit 17a5b9b

Browse files
authored
Merge pull request #59 from m-mohr/collections-api
Support API Collections + bug fixes
2 parents 2e4e37e + 4dd7c7e commit 17a5b9b

File tree

5 files changed

+118
-11
lines changed

5 files changed

+118
-11
lines changed

src/components/Catalog.vue

Lines changed: 115 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,37 @@
4949
<div v-if="description" v-html="description" />
5050

5151
<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+
5283
<b-tab
5384
v-if="visibleTabs.includes('catalogs')"
5485
key="catalogs"
@@ -181,6 +212,8 @@ import MetadataSidebar from './MetadataSidebar.vue'
181212
182213
import { transformCatalog } from "../migrate"
183214
215+
import { fetchUri } from "../util";
216+
184217
const ITEMS_PER_PAGE = 25;
185218
186219
export default {
@@ -229,13 +262,26 @@ export default {
229262
sortable: true
230263
}
231264
],
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+
],
232277
currentChildPage: 1,
233-
childrenPerPage: 25,
278+
currentCollectionPage: 1,
279+
childrenPerPage: 25, // also applies to collections
234280
itemFields: [
235281
{
236282
key: "link",
237283
label: "Title",
238-
sortable: true
284+
sortable: false // Sorting doesn't work for links
239285
},
240286
{
241287
key: "dateAcquired",
@@ -259,18 +305,75 @@ export default {
259305
};
260306
},
261307
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+
},
262365
externalItems: {
263366
default: [],
264367
lazy: true,
265368
async get() {
266369
const externalItemsLink = this.links.find(x => x.rel === "items");
267370
268-
if (externalItemsLink == null) {
371+
if (externalItemsLink === undefined) {
269372
return [];
270373
}
271374
272375
try {
273-
const rsp = await fetch(
376+
const rsp = await fetchUri(
274377
`${externalItemsLink.href}?page=${this.currentItemPage}`
275378
);
276379
@@ -347,8 +450,11 @@ export default {
347450
catalog() {
348451
return this.entity;
349452
},
453+
collectionCount() {
454+
return this.collections.length;
455+
},
350456
childCount() {
351-
return this.links.filter(x => x.rel === "child").length;
457+
return this.children.length;
352458
},
353459
children() {
354460
return this.links
@@ -361,15 +467,16 @@ export default {
361467
p += "/";
362468
}
363469
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);
365472
const to = [p, slug].join("");
366473
367474
return {
368475
path: child.href,
369476
to,
370477
// child.id is a workaround for https://earthengine-stac.storage.googleapis.com/catalog/catalog.json
371478
title: child.title || child.id || child.href,
372-
url: this.resolve(child.href, this.url)
479+
url: resolved
373480
};
374481
});
375482
},
@@ -616,6 +723,7 @@ export default {
616723
},
617724
visibleTabs() {
618725
return [
726+
this.collectionCount > 0 && "collections",
619727
this.childCount > 0 && "catalogs",
620728
(this.hasExternalItems || this.itemCount > 0) && "items",
621729
this.bands.length > 0 && "bands",

src/components/MetadataSidebar.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
<td v-html="prop.value" />
4848
</tr>
4949
</template>
50-
<template v-if="providers">
50+
<template v-if="Array.isArray(providers) && providers.length > 0">
5151
<tr>
5252
<td colspan="2" class="group">
5353
<h4>

src/components/common.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import clone from "clone";
55
import { HtmlRenderer, Parser } from "commonmark";
66
import escape from "lodash.escape";
77
import isEqual from "lodash.isequal";
8-
import isEmpty from "lodash.isempty";
98
import jsonQuery from "json-query";
109
import spdxToHTML from "spdx-to-html";
1110
import spdxLicenseIds from "spdx-license-ids";

src/main.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ const main = async () => {
9999
};
100100

101101
const catalogValidator = async (data) => {
102-
if (data.license != null || data.extent != null) {
102+
if (data.license || data.extent) {
103103
// contains Collection properties
104104
return collectionValidator(data);
105105
}

src/migrate.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* Methods that transform STAC object JSON from older versions to
22
allow for a more consistent usage in other parts of the codebase */
3-
import { STAC_VERISON } from './config';
3+
import { STAC_VERSION } from './config';
44

55
export const transformCatalog = (entity) => {
66
if(!entity) { return entity; }

0 commit comments

Comments
 (0)