Bring back the postinstall dialog
This commit is contained in:
@@ -99,10 +99,11 @@ async function submit() {
|
||||
|
||||
if (manifest.value.id === PROXY_APP_ID) config.upstreamUri = upstreamUri.value;
|
||||
|
||||
const [error] = await appsModel.install(manifest.value, config);
|
||||
const [error, result] = await appsModel.install(manifest.value, config);
|
||||
|
||||
if (!error) {
|
||||
dialog.value.close();
|
||||
localStorage['confirmPostInstall_' + result.id] = true;
|
||||
return window.location.href = '#/apps';
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
<script setup>
|
||||
|
||||
import { ref, useTemplateRef } from 'vue';
|
||||
import { marked } from 'marked';
|
||||
import { Dialog } from 'pankow';
|
||||
|
||||
const dialog = useTemplateRef('dialog');
|
||||
const app = ref(null);
|
||||
const hasPendingCheclistItems = ref(false);
|
||||
const acknowledge = ref(false);
|
||||
|
||||
function onConfirm() {
|
||||
delete localStorage['confirmPostInstall_' + app.value.id];
|
||||
dialog.value.close();
|
||||
window.open('https://' + app.value.fqdn);
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
async open(a, ack = false) {
|
||||
app.value = a;
|
||||
acknowledge.value = ack;
|
||||
hasPendingCheclistItems.value = !Object.keys(a.checklist).find((i) => a.checklist[i].acknowledged);
|
||||
dialog.value.open();
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Dialog ref="dialog"
|
||||
:confirm-label="acknowledge ? $t('app.appInfo.openAction', { app: app.manifest.title }) : null"
|
||||
:reject-label="$t('main.dialog.close')"
|
||||
:reject-style="acknowledge ? 'secondary' : ''"
|
||||
@confirm="onConfirm"
|
||||
>
|
||||
<div v-if="app">
|
||||
<div class="app-info-header">
|
||||
<img :src="app.iconUrl" onerror="this.onerror=null;this.src='img/appicon_fallback.png'" class="app-info-icon"/>
|
||||
<div class="app-info-title">
|
||||
{{ app.manifest.title }}<br/>
|
||||
<span class="text-muted text-small">{{ $t('app.appInfo.package') }} <a :href="`/#/appstore/${app.manifest.id}?version=${app.manifest.version}`">v{{ app.manifest.version }}</a> </span>
|
||||
<br/>
|
||||
<span v-if="app.manifest.documentationUrl" class="text-small"><a target="_blank" :href="app.manifest.documentationUrl">{{ $t('app.docsAction') }}</a> </span>
|
||||
<br/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-html="marked.parse(app.manifest.postInstallMessage)"></div>
|
||||
<div v-if="app.manifest.documentationUrl" v-html="$t('app.appInfo.appDocsUrl', { docsUrl: app.manifest.documentationUrl, title: app.manifest.title, forumUrl: (app.manifest.forumUrl || 'https://forum.cloudron.io') })"></div>
|
||||
|
||||
<div class="app-info-checklist" v-show="hasPendingCheclistItems">
|
||||
<label class="control-label">{{ $t('app.appInfo.checklist') }}</label>
|
||||
<div v-for="(item, key) in app.checklist" :key="key">
|
||||
<div class="checklist-item" v-show="!item.acknowledged">
|
||||
<span v-html="marked.parse(item.message)"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.app-info-header {
|
||||
display: flex;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.app-info-title {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.app-info-icon {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
.app-info-checklist {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.checklist-item {
|
||||
padding: 8px;
|
||||
border: none;
|
||||
border-left: 2px solid rgb(255, 76, 76);
|
||||
background-color: #ff000014;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.checklist-item > span > * {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -184,7 +184,7 @@ function create() {
|
||||
|
||||
if (result.status !== 202) return [result];
|
||||
|
||||
return [null];
|
||||
return [null, result.body];
|
||||
},
|
||||
async list() {
|
||||
let error, result;
|
||||
|
||||
@@ -4,8 +4,9 @@ import { useI18n } from 'vue-i18n';
|
||||
const i18n = useI18n();
|
||||
const t = i18n.t;
|
||||
|
||||
import { ref, onMounted, onBeforeUnmount, computed } from 'vue';
|
||||
import { ref, onMounted, onBeforeUnmount, computed, useTemplateRef } from 'vue';
|
||||
import { Button, ButtonGroup } from 'pankow';
|
||||
import PostInstallDialog from '../components/PostInstallDialog.vue';
|
||||
import Access from '../components/app/Access.vue';
|
||||
import Backups from '../components/app/Backups.vue';
|
||||
import Cron from '../components/app/Cron.vue';
|
||||
@@ -41,6 +42,7 @@ const hasLocalStorage = ref(false);
|
||||
const hasOptionalServices = ref(false);
|
||||
const hasEmail = ref(false);
|
||||
const busyStopTask = ref(false);
|
||||
const postInstallDialog = useTemplateRef('postInstallDialog');
|
||||
|
||||
const isAppStopped = computed(() => {
|
||||
return appsModel.isStopped(app.value);
|
||||
@@ -91,7 +93,7 @@ async function refresh() {
|
||||
if (result.manifest?.postInstallMessage) {
|
||||
infoMenu.value.push({
|
||||
label: t('app.firstTimeSetupAction'),
|
||||
// TODO action
|
||||
action: () => postInstallDialog.value.open(app.value),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -165,6 +167,8 @@ onBeforeUnmount(() => {
|
||||
|
||||
<template>
|
||||
<div class="configure-outer">
|
||||
<PostInstallDialog ref="postInstallDialog"/>
|
||||
|
||||
<div class="configure-inner" v-if="!busy">
|
||||
<div class="titlebar">
|
||||
<div style="display: flex; flex-grow: 1;">
|
||||
|
||||
@@ -9,6 +9,7 @@ import DomainsModel from '../models/DomainsModel.js';
|
||||
import ProfileModel from '../models/ProfileModel.js';
|
||||
import UpdaterModel from '../models/UpdaterModel.js';
|
||||
import ApplinkDialog from '../components/ApplinkDialog.vue';
|
||||
import PostInstallDialog from '../components/PostInstallDialog.vue';
|
||||
|
||||
const appsModel = AppsModel.create();
|
||||
const domainsModel = DomainsModel.create();
|
||||
@@ -126,6 +127,7 @@ const appProgressMessage = AppsModel.appProgressMessage;
|
||||
const updateInfo = ref({});
|
||||
|
||||
const applinkDialog = useTemplateRef('applinkDialog');
|
||||
const postInstallDialog = useTemplateRef('postInstallDialog');
|
||||
|
||||
// hook for applinks otherwise it is a link
|
||||
function openAppEdit(app, event) {
|
||||
@@ -157,11 +159,10 @@ function onOpenApp(app, event) {
|
||||
return stopEvent();
|
||||
}
|
||||
|
||||
// TODO
|
||||
// if (app.pendingPostInstallConfirmation && $scope.appPostInstallConfirm) {
|
||||
// $scope.appPostInstallConfirm.show(app);
|
||||
// return stopEvent();
|
||||
// }
|
||||
if (localStorage['confirmPostInstall_' + app.id]) {
|
||||
postInstallDialog.value.open(app, true);
|
||||
return stopEvent();
|
||||
}
|
||||
}
|
||||
|
||||
function isOperator(app) {
|
||||
@@ -242,6 +243,7 @@ onUnmounted(() => {
|
||||
<template>
|
||||
<div class="content">
|
||||
<ApplinkDialog ref="applinkDialog" @success="refreshApps()"/>
|
||||
<PostInstallDialog ref="postInstallDialog"/>
|
||||
|
||||
<h1 class="view-header">
|
||||
{{ $t('apps.title') }}
|
||||
|
||||
Reference in New Issue
Block a user