diff --git a/dashboard/src/models/AppsModel.js b/dashboard/src/models/AppsModel.js
index 817cf006a..6293392f1 100644
--- a/dashboard/src/models/AppsModel.js
+++ b/dashboard/src/models/AppsModel.js
@@ -87,6 +87,13 @@ function create() {
return {
name: 'AppsModel',
getTask,
+ isStopped(app) {
+ if (app.installationState === ISTATES.PENDING_START || app.installationState === ISTATES.PENDING_STOP) {
+ return app.installationState === ISTATES.PENDING_START;
+ } else {
+ return app.runState === RSTATES.STOPPED;
+ }
+ },
async install(manifest, config) {
const data = {
appStoreId: manifest.id + '@' + manifest.version,
@@ -224,6 +231,17 @@ function create() {
if (result.status !== 200 && result.status !== 202) return [result];
return [null];
},
+ async uninstall(id) {
+ let result;
+ try {
+ result = await fetcher.post(`${origin}/api/v1/apps/${id}/uninstall`, {}, { access_token: accessToken });
+ } catch (e) {
+ return [e];
+ }
+
+ if (result.status !== 202) return [result];
+ return [null];
+ },
};
}
diff --git a/dashboard/src/views/AppConfigureView.vue b/dashboard/src/views/AppConfigureView.vue
index 2d5cc26a8..472eb6002 100644
--- a/dashboard/src/views/AppConfigureView.vue
+++ b/dashboard/src/views/AppConfigureView.vue
@@ -6,7 +6,7 @@ import { useI18n } from 'vue-i18n';
const i18n = useI18n();
const t = i18n.t;
-import { ref, onMounted, onUnmounted, useTemplateRef } from 'vue';
+import { ref, onMounted, onUnmounted, useTemplateRef, computed } from 'vue';
import { Button, ButtonGroup, TabView } from 'pankow';
import Info from '../components/app/Info.vue';
import Uninstall from '../components/app/Uninstall.vue';
@@ -41,12 +41,25 @@ const link = ref('');
const infoMenu = ref([]);
const hasLocalStorage = ref(false);
-let refreshTimer = null;
+const isAppStopped = computed(() => {
+ return appsModel.isStopped(app.value);
+});
function onTabChanged(tab) {
window.location.hash = `/app/${id.value}/${tab}`;
}
+async function onToggleRunState() {
+ if (isAppStopped.value) {
+ const [error] = await appsModel.start(app.value.id);
+ if (error) return console.error(error);
+ } else {
+ const [error] = await appsModel.stop(app.value.id);
+ if (error) return console.error(error);
+ }
+}
+
+let refreshTimer = null;
async function refresh() {
const [error, result] = await appsModel.get(id.value);
if (error) return console.error(error);
@@ -57,6 +70,7 @@ async function refresh() {
link.value = result.fqdn.indexOf('http') !== 0 ? 'https://' + result.fqdn : result.fqdn;
hasLocalStorage.value = result.manifest && result.manifest.addons && result.manifest.addons.localstorage;
+ // TODO info menu will likely not change during polling
infoMenu.value = [];
infoMenu.value.push({
label: t('app.docsAction'),
@@ -129,7 +143,7 @@ onUnmounted(() => {
-
![]()
+
{{ app.label || app.fqdn }}
@@ -137,9 +151,9 @@ onUnmounted(() => {