diff --git a/src/components/ASF/Plugins.vue b/src/components/ASF/Plugins.vue
index a21988dc9..69201a838 100644
--- a/src/components/ASF/Plugins.vue
+++ b/src/components/ASF/Plugins.vue
@@ -13,6 +13,7 @@
{{ plugin.Name }}
{{ plugin.Version }}
{{ $t('official') }}
+ {{ $t('plugin-web-interface') }}
@@ -64,6 +65,17 @@
this.loading = false;
}
},
+ methods: {
+ webInterfaceUrl(plugin) {
+ // Plugins implementing IWebInterface report the WebPath their files are served under, e.g. "/MyPlugin"
+ // A WebPath of "/" replaces ASF-ui itself, so there is nothing to link to
+ const webPath = (plugin.WebPath ?? '').replace(/^\/+|\/+$/g, '');
+ if (!webPath) return null;
+
+ // The trailing slash matters, otherwise ASF-ui's router handles the address instead of the plugin
+ return `${window.__BASE_PATH__ ?? '/'}${webPath}/`;
+ },
+ },
};
@@ -109,6 +121,19 @@
}
}
+ .plugin__link {
+ color: var(--color-theme);
+ font-weight: 600;
+ margin-left: auto;
+ padding-left: 0.8em;
+ text-decoration: none;
+
+ @media screen and (max-width: 400px) {
+ margin-left: 0;
+ padding-left: 0;
+ }
+ }
+
.plugin__label {
color: #00a65a;
background-color: var(--color-background-light);
diff --git a/src/i18n/locale/default.json b/src/i18n/locale/default.json
index de851e855..d25fe5775 100644
--- a/src/i18n/locale/default.json
+++ b/src/i18n/locale/default.json
@@ -204,6 +204,7 @@
"performance": "Performance",
"plugin-unknown-name": "Unknown plugin #{number}",
"plugin-unknown-version": "Unknown version",
+ "plugin-web-interface": "Open web interface",
"plugins": "Plugins",
"plugins-not-loaded": "No plugins loaded",
"pre-release": "Pre-Release",