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 @@ + + + + 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 @@