diff --git a/docs/actions.md b/docs/actions.md
index 2efe25805..f914a512c 100644
--- a/docs/actions.md
+++ b/docs/actions.md
@@ -1,12 +1,13 @@
# Actions
-STAC Browser has a pluggable interface to share or open assets and links with other services, which we call "actions".
+STAC Browser has a pluggable interface to share or open assets, catalogs, collections, items and links with other services, which we call "actions".
-An action adds a button to an asset or link if certain requirements are met, which can then be executed by users.
+An action adds a button to an asset, catalog, collection, item or link if certain requirements are met, which can then be executed by users.
For example, you could open COPC files in a dedicated COPC Viewer, which otherwise you could only download.
- [User Guide](#user-guide)
- [Assets](#assets)
+ - [Catalogs, Collections and Items](#catalogs-collections-and-items)
- [Links](#links)
- [Developer Guide](#developer-guide)
@@ -50,6 +51,37 @@ export default {
Save the file and restart / rebuild STAC Browser.
+### Catalogs, Collections and Items
+
+The following actions are available:
+
+- `stac-map`: Allows to open items through stac-map at .
+
+All actions for catalogs, collections and items are stored in the folder [`src/actions/stac`](../src/actions/stac) if you want to inspect them.
+
+The actions can be enabled by adding them to the [`stacActions.config.js`](../stacActions.config.js) file.
+Open the file and you'll see a number of imports and exports.
+Import the file for the action that you want to enable, e.g. for stac-map:
+
+```js
+import StacMap from './src/actions/stac/StacMap.js';
+```
+
+The path is fixed to `./src/actions/stac/`, the file extension is always `.js`.
+In-between add the file name from the list above.
+The import name should be the file name without extension (i.e. `StacMap` again).
+
+Lastly, add the import name to the list of exports, e.g.
+
+```js
+export default {
+ OtherAction,
+ StacMap
+};
+```
+
+Save the file and rebuild / restart STAC Browser.
+
### Links
The following actions are available:
@@ -86,16 +118,22 @@ Save the file and rebuild / restart STAC Browser.
## Developer Guide
-Implementing actions for assets and links follows a very similar pattern.
-The main difference is that assets implement the [`AssetActionPlugin` interface](../src/actions/AssetActionPlugin.js) while links implement the [`LinkActionPlugin` interface](../src/actions/LinkActionPlugin.js).
-Similarly, actions for assets are stored in the folder links are stored in the folder [`src/actions/assets`](../src/actions/assets) while links are stored in the folder [`src/actions/links`](../src/actions/links).
+Implementing actions for assets, items and links follows a very similar pattern.
+The main difference is that each action implements its own interface:
+- assets implement the [`AssetActionPlugin` interface](../src/actions/AssetActionPlugin.js)
+- catalogs, collections and items implement the [`StacActionPlugin` interface](../src/actions/StacActionPlugin.js)
+- links implement the [`LinkActionPlugin` interface](../src/actions/LinkActionPlugin.js)
+Similarly, actions are stored in their own folder:
+- assets are stored in the folder [`src/actions/assets`](../src/actions/assets)
+- catalogs, collections and items are stored in the folder [`src/actions/stac`](../src/actions/stac)
+- links are stored in the folder [`src/actions/links`](../src/actions/links)
-The interfaces for both look as follows:
+All interfaces look as follows:
- `constructor(data: object, component: Vue, id: string)`
- - `data`: The asset or link object, it is available in the class through `this.asset` (for assets) and `this.link` (for links).
- - `component`: The parent Asset/Link Vue component (available in the class through `this.component`)
- - `id`: Internal ID of the asset or link, not meant to be used.
+ - `data`: The asset, catalog, collection, item or link object, it is available in the class through `this.asset` (for assets), `this.object` (for items) and `this.link` (for links).
+ - `component`: The parent Asset/Catalog/Collection/Item/Link Vue component (available in the class through `this.component`)
+ - `id`: Internal ID of the asset, catalog, collection, item or link, not meant to be used.
- `get btnOptions() : object`
- This should return an object of button options, see [VueBootstrap b-button](https://bootstrap-vue.org/docs/components/button/#component-reference) for details. Returns `href`, `rel` (only for links) and `target` (set to `_blank`) by default.
- `get onClick() : function(event: MouseEvent)`
diff --git a/src/actions/StacActionPlugin.js b/src/actions/StacActionPlugin.js
new file mode 100644
index 000000000..7d3d1dc12
--- /dev/null
+++ b/src/actions/StacActionPlugin.js
@@ -0,0 +1,9 @@
+import ActionPlugin from './ActionPlugin';
+
+export default class StacActionPlugin extends ActionPlugin {
+
+ constructor(object, component, id) {
+ super(id, component);
+ this.object = object;
+ }
+}
diff --git a/src/actions/stac/StacMap.js b/src/actions/stac/StacMap.js
new file mode 100644
index 000000000..fba453819
--- /dev/null
+++ b/src/actions/stac/StacMap.js
@@ -0,0 +1,18 @@
+import StacActionPlugin from "../StacActionPlugin";
+import URI from 'urijs';
+import i18n from "../../i18n";
+
+export default class StacMap extends StacActionPlugin {
+
+ get show() {
+ return this.object.isItem();
+ }
+
+ get uri() {
+ return URI('https://developmentseed.org/stac-map/').addQuery('href', this.object.getAbsoluteUrl());
+ }
+
+ get text() {
+ return i18n.t('actions.openIn', {service: 'stac-map'});
+ }
+}
diff --git a/src/components/Item.vue b/src/components/Item.vue
index c9be71275..c59e8d780 100644
--- a/src/components/Item.vue
+++ b/src/components/Item.vue
@@ -19,6 +19,7 @@
+
@@ -26,6 +27,7 @@
import { mapState, mapGetters } from 'vuex';
import FileFormatsMixin from './FileFormatsMixin';
import ThumbnailCardMixin from './ThumbnailCardMixin';
+import StacActions from './StacActions.vue';
import StacLink from './StacLink.vue';
import { STAC } from 'stac-js';
import { formatTemporalExtent, formatTimestamp, formatMediaType } from '@radiantearth/stac-fields/formatters';
@@ -38,6 +40,7 @@ export default {
name: 'Item',
components: {
StacLink,
+ StacActions,
Keywords: () => import('./Keywords.vue')
},
filters: {
@@ -141,6 +144,10 @@ export default {
text-align: center;
position: relative;
}
+
+ &:has(.obj-actions) {
+ padding-bottom: 0.5rem;
+ }
}
}
diff --git a/src/components/StacActions.vue b/src/components/StacActions.vue
new file mode 100644
index 000000000..e11ad4d5e
--- /dev/null
+++ b/src/components/StacActions.vue
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+ {{ action.text }}
+
+
+
+
+
+
+
+ {{ action.text }}
+
+
+
+
+
+
diff --git a/src/views/Catalog.vue b/src/views/Catalog.vue
index 810e271d4..0c443a017 100644
--- a/src/views/Catalog.vue
+++ b/src/views/Catalog.vue
@@ -35,6 +35,7 @@
+
@@ -63,6 +64,7 @@
import { mapState, mapGetters } from 'vuex';
import Catalogs from '../components/Catalogs.vue';
import Description from '../components/Description.vue';
+import StacActions from '../components/StacActions.vue';
import Items from '../components/Items.vue';
import ReadMore from "vue-read-more-smooth";
import ShowAssetLinkMixin from '../components/ShowAssetLinkMixin';
@@ -85,6 +87,7 @@ export default {
CollectionLink: () => import('../components/CollectionLink.vue'),
DeprecationNotice: () => import('../components/DeprecationNotice.vue'),
Description,
+ StacActions,
Items,
Keywords: () => import('../components/Keywords.vue'),
Links: () => import('../components/Links.vue'),
@@ -439,6 +442,10 @@ export default {
}
}
+ .obj-actions + .assets, .obj-actions + .providers, .obj-actions + .metadata {
+ margin-top: 1rem;
+ }
+
.metadata .card-columns {
column-count: 1;
diff --git a/src/views/Item.vue b/src/views/Item.vue
index 478d6b310..bec1366c6 100644
--- a/src/views/Item.vue
+++ b/src/views/Item.vue
@@ -14,6 +14,7 @@
+
@@ -38,6 +39,7 @@