Skip to content

Commit ffc2c4c

Browse files
committed
JS-based validation with results #307
1 parent 47dea4f commit ffc2c4c

File tree

19 files changed

+497
-222
lines changed

19 files changed

+497
-222
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,6 @@ You need to provide a field `stac_browser` and then you can set any of the follo
231231
- `defaultThumbnailSize`
232232
- `displayGeoTiffByDefault`
233233
- `showThumbnailsAsAssets`
234-
- `stacLint` (can only be disabled)
235234

236235
### Custom extensions
237236

config.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ module.exports = {
3131
showKeywordsInItemCards: false,
3232
showKeywordsInCatalogCards: false,
3333
showThumbnailsAsAssets: false,
34-
stacLint: true,
3534
geoTiffResolution: 128,
3635
redirectLegacyUrls: false,
3736
itemsPerPage: 12,

config.schema.json

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,6 @@
152152
"boolean"
153153
]
154154
},
155-
"stacLint": {
156-
"type": [
157-
"boolean"
158-
]
159-
},
160155
"geoTiffResolution": {
161156
"type": [
162157
"integer"

docs/options.md

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ The following ways to set config options are possible:
2424
* [locale](#locale)
2525
* [fallbackLocale](#fallbacklocale)
2626
* [supportedLocales](#supportedlocales)
27-
* [stacLint](#staclint)
2827
* [historyMode](#historymode)
2928
* [pathPrefix](#pathprefix)
3029
* [stacProxyUrl](#stacproxyurl)
@@ -115,18 +114,6 @@ In CLI, please provide the languages separated by a space, e.g. `--supportedLoca
115114
Please note that only left-to-right languages have been tested.
116115
I'd need help to test support for right-to-left languages.
117116

118-
## stacLint
119-
120-
***experimental***
121-
122-
Enables or disables a feature that validates the STAC catalog when opening the "Source Data" popup.
123-
Validation uses the external service [staclint.com](https://staclint.com).
124-
125-
Validation is automatically disabled in the following cases:
126-
- the host of a catalog is `localhost`, `127.0.0.1` or `::1`
127-
- [private query parameters](../README.md#private-query-parameters) have been set
128-
- `stacProxyUrl` is set
129-
130117
## historyMode
131118

132119
***build-only option***

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
"node-polyfill-webpack-plugin": "^2.0.0",
5252
"remove-markdown": "^0.5.0",
5353
"stac-layer": "^0.15.0",
54+
"stac-node-validator": "^2.0.0-beta.6",
5455
"urijs": "^1.19.11",
5556
"v-clipboard": "^3.0.0-next.1",
5657
"vue": "^2.6.12",

src/StacBrowser.vue

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<template>
22
<b-container id="stac-browser">
33
<Authentication v-if="doAuth.length > 0" />
4-
<ErrorAlert class="global-error" v-if="globalError" v-bind="globalError" @close="hideError" />
4+
<ErrorAlert v-if="globalError" dismissible class="global-error" v-bind="globalError" @close="hideError" />
55
<Sidebar v-if="sidebar" />
66
<!-- Header -->
77
<header>
@@ -227,8 +227,7 @@ export default {
227227
'crossOriginMedia',
228228
'defaultThumbnailSize',
229229
'displayGeoTiffByDefault',
230-
'showThumbnailsAsAssets',
231-
'stacLint' // can only be disabled
230+
'showThumbnailsAsAssets'
232231
];
233232
234233
let doReset = !root || (oldRoot && Utils.isObject(oldRoot['stac_browser']));
@@ -242,11 +241,6 @@ export default {
242241
if (doSet && typeof root['stac_browser'][key] !== 'undefined') {
243242
value = root['stac_browser'][key]; // Custom value from root
244243
}
245-
246-
// Don't enable stacLint if it has been disabled by default
247-
if (key === 'stacLint' && !CONFIG.stacLint) {
248-
continue;
249-
}
250244
251245
// Commit config
252246
if (typeof value !== 'undefined') {
@@ -392,4 +386,4 @@ export default {
392386
@import '~bootstrap-vue/src/index.scss';
393387
@import "./theme/page.scss";
394388
@import "./theme/custom.scss";
395-
</style>
389+
</style>

src/components/ErrorAlert.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export default {
5252
},
5353
dismissible: {
5454
type: Boolean,
55-
default: true
55+
default: false
5656
}
5757
}
5858
};
@@ -72,4 +72,4 @@ export default {
7272
dl {
7373
font-size: 0.9em;
7474
}
75-
</style>
75+
</style>

src/components/SearchFilter.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,8 @@ export default {
261261
},
262262
andOrOptions() {
263263
return [
264-
{ value: 'and', text: this.$i18n.t('search.logical.and') },
265-
{ value: 'or', text: this.$i18n.t('search.logical.or') },
264+
{ value: 'and', text: this.$t('search.logical.and') },
265+
{ value: 'or', text: this.$t('search.logical.or') },
266266
];
267267
},
268268
showAdditionalFilters() {

src/components/Source.vue

Lines changed: 7 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@
3838

3939
<b-popover
4040
v-if="stacUrl" id="popover-link" target="popover-link-btn" triggers="focus"
41-
placement="bottom" container="stac-browser" :title="$t('source.title')"
42-
@show="validate"
41+
placement="bottom" container="stac-browser" :title="$t('source.title')"
4342
>
4443
<template v-if="stac">
4544
<b-row v-if="stacId" class="stac-id">
@@ -53,13 +52,10 @@
5352
<b-col cols="4">{{ $t('source.stacVersion') }}</b-col>
5453
<b-col>{{ stacVersion }}</b-col>
5554
</b-row>
56-
<b-row v-if="canValidate" class="validation">
55+
<b-row class="stac-valid">
5756
<b-col cols="4">{{ $t('source.valid') }}</b-col>
5857
<b-col>
59-
<b-spinner v-if="valid === null" :label="$t('source.validating')" small />
60-
<template v-else-if="valid === true">✔️</template>
61-
<template v-else-if="valid === false">❌</template>
62-
<template v-else>{{ $t('source.validationNA') }}</template>
58+
<Validation :data="stac" />
6359
</b-col>
6460
</b-row>
6561
<hr>
@@ -84,7 +80,6 @@ import { mapActions, mapGetters, mapState } from 'vuex';
8480
8581
import Url from './Url.vue';
8682
87-
import URI from 'urijs';
8883
import Utils from '../utils';
8984
import { getBest, prepareSupported } from '../locale-id';
9085
import CopyButton from './CopyButton.vue';
@@ -109,6 +104,7 @@ export default {
109104
RootStats: () => import('./RootStats.vue'),
110105
Url,
111106
CopyButton,
107+
Validation: () => import('./Validation.vue')
112108
},
113109
props: {
114110
title: {
@@ -125,7 +121,7 @@ export default {
125121
}
126122
},
127123
computed: {
128-
...mapState(['conformsTo', 'dataLanguages', 'locale', 'privateQueryParameters', 'supportedLocales', 'stacLint', 'stacProxyUrl', 'uiLanguage', 'valid']),
124+
...mapState(['conformsTo', 'dataLanguages', 'locale', 'supportedLocales', 'uiLanguage', 'valid']),
129125
...mapGetters(['supportsExtension', 'root']),
130126
stacVersion() {
131127
return this.stac?.stac_version;
@@ -154,26 +150,6 @@ export default {
154150
return '-';
155151
}
156152
},
157-
canValidate() {
158-
if (!this.stacLint || typeof this.stacUrl !== 'string') {
159-
return false;
160-
}
161-
else if (Utils.size(this.privateQueryParameters) > 0) {
162-
// Don't expose private query parameters to externals
163-
return false;
164-
}
165-
else if (Array.isArray(this.stacProxyUrl)) {
166-
// Don't validate if a proxy has been set
167-
return false;
168-
}
169-
let uri = URI(this.stacUrl);
170-
let host = uri.hostname().toLowerCase();
171-
if (host === 'localhost' || host.startsWith('127.') || host === '::1') {
172-
// Can't validate localhost
173-
return false;
174-
}
175-
return true;
176-
},
177153
message() {
178154
return this.$t('source.share.message', {title: this.title, url: this.browserUrl()});
179155
},
@@ -235,12 +211,6 @@ export default {
235211
},
236212
methods: {
237213
...mapActions(['switchLocale']),
238-
async validate() {
239-
if (!this.canValidate) {
240-
return;
241-
}
242-
await this.$store.dispatch('validate', this.stacUrl);
243-
},
244214
browserUrl() {
245215
return window.location.toString();
246216
}
@@ -260,7 +230,8 @@ export default {
260230
}
261231
}
262232
263-
#popover-link .stac-id .copy-button {
233+
#popover-link .stac-id .btn-sm,
234+
#popover-link .stac-valid .btn-sm {
264235
padding-top: 0.1rem;
265236
padding-bottom: 0.1rem;
266237
font-size: 0.7rem;

src/components/StacHeader.vue

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
<template #catalog><StacLink :data="containerLink" /></template>
1414
</i18n>
1515
<b-button-group>
16+
<b-button v-if="back" :to="selfBrowserLink" :title="$t('goBack.description', {type})" variant="outline-primary" size="sm">
17+
<b-icon-arrow-left /> <span class="button-label prio">{{ $t('goBack.label') }}</span>
18+
</b-button>
1619
<b-button v-if="parentLink" :to="toBrowserPath(parentLink.href)" :title="parentLinkTitle" variant="outline-primary" size="sm">
1720
<b-icon-arrow-90deg-up /> <span class="button-label prio">{{ $t('goToParent.label') }}</span>
1821
</b-button>
@@ -43,14 +46,15 @@
4346
import { mapState, mapGetters } from 'vuex';
4447
import Source from './Source.vue';
4548
import StacLink from './StacLink.vue';
46-
import { BIconArrow90degUp, BIconBook, BIconFolderSymlink, BIconSearch, BIconLock, BIconUnlock } from "bootstrap-vue";
49+
import { BIconArrow90degUp, BIconArrowLeft, BIconBook, BIconFolderSymlink, BIconSearch, BIconLock, BIconUnlock } from "bootstrap-vue";
4750
import STAC from '../models/stac';
4851
import Utils from '../utils';
4952
5053
export default {
5154
name: 'StacHeader',
5255
components: {
5356
BIconArrow90degUp,
57+
BIconArrowLeft,
5458
BIconBook,
5559
BIconFolderSymlink,
5660
BIconSearch,
@@ -62,6 +66,29 @@ export default {
6266
computed: {
6367
...mapState(['allowSelectCatalog', 'authConfig', 'authData', 'catalogUrl', 'data', 'url', 'title']),
6468
...mapGetters(['canSearch', 'root', 'parentLink', 'collectionLink', 'toBrowserPath']),
69+
back() {
70+
return this.$route.name === 'validation';
71+
},
72+
selfBrowserLink() {
73+
return this.toBrowserPath(this.url);
74+
},
75+
type() {
76+
if (this.data instanceof STAC) {
77+
if (this.data.isItem()) {
78+
return this.$tc('stacItem');
79+
}
80+
else if (this.data.isCollection()) {
81+
return this.$tc(`stacCollection`);
82+
}
83+
else if (this.data.isCatalog()) {
84+
return this.$tc(`stacCatalog`);
85+
}
86+
else {
87+
return this.data.type;
88+
}
89+
}
90+
return null;
91+
},
6592
collectionLinkTitle() {
6693
if (this.collectionLink && Utils.hasText(this.collectionLink.title)) {
6794
return this.$t('goToCollection.descriptionWithTitle', this.collectionLink);

0 commit comments

Comments
 (0)