Remove the app repair dialog in favor of just a simple button to trigger repair
This commit is contained in:
@@ -1,187 +0,0 @@
|
||||
<script setup>
|
||||
|
||||
import { ref, useTemplateRef } from 'vue';
|
||||
import { Dialog, FormGroup, SingleSelect } from '@cloudron/pankow';
|
||||
import { prettyDate } from '@cloudron/pankow/utils';
|
||||
import { ISTATES } from '../constants.js';
|
||||
import { taskNameFromInstallationState } from '../utils.js';
|
||||
import AppsModel from '../models/AppsModel.js';
|
||||
|
||||
const appsModel = AppsModel.create();
|
||||
|
||||
const emit = defineEmits([ 'success' ]);
|
||||
|
||||
const dialog = useTemplateRef('dialog');
|
||||
|
||||
const busy = ref(false);
|
||||
const formError = ref('');
|
||||
const id = ref('');
|
||||
const fqdn = ref('');
|
||||
const appError = ref(null);
|
||||
const backups = ref([]);
|
||||
const backupId = ref('');
|
||||
|
||||
async function onSubmit() {
|
||||
busy.value = true;
|
||||
formError.value = '';
|
||||
|
||||
const errorState = (appError.value && appError.value.details.installationState) || ISTATES.PENDING_CONFIGURE;
|
||||
const data = {};
|
||||
|
||||
let repairFunc;
|
||||
switch (errorState) {
|
||||
case ISTATES.PENDING_INSTALL:
|
||||
case ISTATES.PENDING_CLONE: // if manifest or bad image, use CLI to provide new manifest
|
||||
repairFunc = appsModel.repair.bind(null, id.value, {}); // this will trigger a re-install
|
||||
break;
|
||||
|
||||
// case ISTATES.PENDING_LOCATION_CHANGE:
|
||||
// data.subdomain = $scope.repair.subdomain;
|
||||
// data.domain = $scope.repair.domain.domain;
|
||||
// data.aliasDomains = $scope.repair.aliasDomains.filter(function (a) { return a.enabled; })
|
||||
// .map(function (d) { return { subdomain: d.subdomain, domain: d.domain.domain }; });
|
||||
// data.redirectDomains = $scope.repair.redirectDomains.filter(function (a) { return a.enabled; })
|
||||
// .map(function (d) { return { subdomain: d.subdomain, domain: d.domain.domain }; });
|
||||
// data.overwriteDns = true; // always overwriteDns. user can anyway check and uncheck above
|
||||
// repairFunc = Client.configureApp.bind(null, $scope.app.id, 'location', data);
|
||||
// break;
|
||||
|
||||
case ISTATES.PENDING_DATA_DIR_MIGRATION:
|
||||
repairFunc = appsModel.configure.bind(null, id.value, 'storage', { storageVolumeId: null, storageVolumePrefix: null });
|
||||
break;
|
||||
|
||||
// this also happens for import faliures. this UI can only show backup listing. use CLI for arbit id/config
|
||||
case ISTATES.PENDING_RESTORE:
|
||||
case ISTATES.PENDING_IMPORT:
|
||||
if (backups.value.length === 0) { // this can happen when you give some invalid backup via CLI and restore via UI
|
||||
repairFunc = appsModel.repair.bind(null, id.value, {}); // this will trigger a re-install
|
||||
} else {
|
||||
repairFunc = appsModel.restore.bind(null, id.value, backupId.value);
|
||||
}
|
||||
break;
|
||||
|
||||
case ISTATES.PENDING_UNINSTALL:
|
||||
repairFunc = appsModel.uninstall.bind(null, id.value);
|
||||
break;
|
||||
|
||||
case ISTATES.PENDING_START:
|
||||
case ISTATES.PENDING_STOP:
|
||||
case ISTATES.PENDING_RESTART:
|
||||
case ISTATES.PENDING_RESIZE:
|
||||
case ISTATES.PENDING_DEBUG:
|
||||
case ISTATES.PENDING_RECREATE_CONTAINER:
|
||||
case ISTATES.PENDING_CONFIGURE:
|
||||
case ISTATES.PENDING_BACKUP: // can happen if the backup task was killed/rebooted
|
||||
case ISTATES.PENDING_UPDATE: // when update failed, just bring it back to current state and user can click update again
|
||||
default:
|
||||
repairFunc = appsModel.repair.bind(null, id.value, {});
|
||||
break;
|
||||
}
|
||||
|
||||
const [error] = await repairFunc();
|
||||
if (error) {
|
||||
busy.value = false;
|
||||
return console.error(error);
|
||||
}
|
||||
|
||||
emit('success');
|
||||
dialog.value.close();
|
||||
busy.value = false;
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
async open(app) {
|
||||
id.value = app.id;
|
||||
fqdn.value = app.fqdn;
|
||||
appError.value = app.error || null;
|
||||
|
||||
const errorState = (app.error && app.error.details.installationState) || ISTATES.PENDING_CONFIGURE;
|
||||
|
||||
if (errorState === ISTATES.PENDING_RESTORE || errorState === ISTATES.PENDING_IMPORT) {
|
||||
const [error, result] = await appsModel.backups(app.id);
|
||||
if (error) return console.error(error);
|
||||
|
||||
result.forEach(b => {
|
||||
b.label = prettyDate(b.creationTime) + ` - v${b.packageVersion}`;
|
||||
});
|
||||
backups.value = result;
|
||||
backupId.value = '';
|
||||
}
|
||||
|
||||
dialog.value.open();
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Dialog ref="dialog" :title="$t('app.repairDialog.title', { app: fqdn })"
|
||||
:confirm-label="$t('app.repairDialog.retryAction', { task: taskNameFromInstallationState(appError ? appError.installationState : '') })"
|
||||
:confirm-active="!busy"
|
||||
:confirm-busy="busy"
|
||||
:reject-label="busy ? '' : $t('main.dialog.cancel')"
|
||||
reject-style="secondary"
|
||||
@confirm="onSubmit()"
|
||||
>
|
||||
<div>
|
||||
<div class="text-danger" v-if="formError">{{ formError }}</div>
|
||||
|
||||
<div v-if="appError">
|
||||
<p v-html="$t('app.repairDialog.taskError', { task: taskNameFromInstallationState(appError ? appError.installationState : '') })"></p>
|
||||
<p class="text-danger">{{ appError.reason + ': ' + appError.message }}</p>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p>{{ $t('app.repairDialog.description') }}</p>
|
||||
</div>
|
||||
|
||||
<form @submit.prevent="onSubmit()" autocomplete="off">
|
||||
<fieldset :disabled="busy">
|
||||
<FormGroup v-if="backups.length">
|
||||
<label for="backupInput">{{ $t('app.repairDialog.fromBackup') }}</label>
|
||||
<SingleSelect :options="backups" v-model="backupId" option-key="id" option-label="label"/>
|
||||
</FormGroup>
|
||||
<!--
|
||||
<div class="form-group" ng-show="repair.subdomain && repair.domain">
|
||||
<p>{{ 'app.repairDialog.domainDescription' | tr }}</p>
|
||||
<label class="control-label">{{ 'app.repairDialog.location' | tr }}</label>
|
||||
<div class="input-group form-inline">
|
||||
<input type="text" class="form-control" ng-model="repair.subdomain" name="location" placeholder="{{ 'Leave empty to use bare domain' }}">
|
||||
|
||||
<div class="input-group-btn">
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
<span>{{ '.' + repair.domain.domain }}</span>
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-right" role="menu">
|
||||
<li ng-repeat="domain in domains">
|
||||
<a href="" ng-click="repair.domain = domain">{{ domain.domain }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-show="repair.aliasDomains.length">
|
||||
<p ng-repeat="aliasDomain in repair.aliasDomains">
|
||||
<label class="control-label"><input type="checkbox" ng-model="aliasDomain.enabled">
|
||||
{{ aliasDomain.subdomain + (!aliasDomain.subdomain ? '' : '.') + aliasDomain.domain.domain }}
|
||||
</label>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div ng-show="repair.redirectDomains.length">
|
||||
<p ng-repeat="redirectDomain in repair.redirectDomains">
|
||||
<label class="control-label"><input type="checkbox" ng-model="redirectDomain.enabled">
|
||||
{{ redirectDomain.subdomain + (!redirectDomain.subdomain ? '' : '.') + redirectDomain.domain.domain }}
|
||||
</label>
|
||||
</p>
|
||||
</div>
|
||||
-->
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</Dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<script setup>
|
||||
|
||||
import { ref, onMounted, useTemplateRef } from 'vue';
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { Button, Switch } from '@cloudron/pankow';
|
||||
import { taskNameFromInstallationState } from '../../utils.js';
|
||||
import { ISTATES } from '../../constants.js';
|
||||
import AppRepairDialog from '../AppRepairDialog.vue';
|
||||
import AppsModel from '../../models/AppsModel.js';
|
||||
|
||||
const props = defineProps([ 'app' ]);
|
||||
|
||||
const appsModel = AppsModel.create();
|
||||
const busyRepair = ref(false);
|
||||
const busyRestart = ref(false);
|
||||
const debugMode = ref(false);
|
||||
const debugModeBusy = ref(false);
|
||||
@@ -30,12 +30,20 @@ async function onDebugMode(newValue) {
|
||||
}
|
||||
|
||||
// let the task start
|
||||
setTimeout(() => { debugModeBusy.value = false; }, 2000);
|
||||
setTimeout(() => { debugModeBusy.value = false; }, 4000);
|
||||
}
|
||||
|
||||
const repairDialog = useTemplateRef('repairDialog');
|
||||
async function onRepair() {
|
||||
repairDialog.value.open(props.app);
|
||||
busyRepair.value = true;
|
||||
|
||||
const [error] = await appsModel.repair(props.app.id, {});
|
||||
if (error) {
|
||||
console.error(error);
|
||||
busyRepair.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
setTimeout(() => { busyRepair.value = false; }, 4000);
|
||||
}
|
||||
|
||||
async function onRestart() {
|
||||
@@ -55,8 +63,6 @@ onMounted(() => {
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<AppRepairDialog ref="repairDialog" />
|
||||
|
||||
<label>{{ $t('app.repair.recovery.title') }}</label>
|
||||
<p v-html="$t('app.repair.recovery.description', { docsLink: 'https://docs.cloudron.io/troubleshooting/#unresponsive-app' })"></p>
|
||||
|
||||
@@ -70,6 +76,6 @@ onMounted(() => {
|
||||
<label>{{ $t('app.repair.taskError.title') }}</label>
|
||||
<p>{{ $t('app.repair.taskError.description') }}</p>
|
||||
<p v-if="app.error">An error occurred during the <b>{{ taskNameFromInstallationState(app.error.details.installationState) }}</b> operation: <span class="text-danger"><b>{{ app.error.reason + ': ' + app.error.message }}</b></span></p>
|
||||
<Button @click="onRepair()" :disabled="app.taskId || !app.error" v-tooltip="app.taskId ? $t('app.repair.appIsBusyTooltip') : ''">{{ $t('app.repair.taskError.retryAction', { task: app.error ? taskNameFromInstallationState(app.error.details.installationState) : '' }) }}</Button>
|
||||
<Button @click="onRepair()" :disabled="busyRepair || app.taskId || !app.error" :loading="busyRepair">{{ $t('app.repair.taskError.retryAction', { task: app.error ? taskNameFromInstallationState(app.error.details.installationState) : '' }) }}</Button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user