Handle errors in app installation form

This commit is contained in:
Johannes Zellner
2025-01-07 12:49:19 +01:00
parent ee263914aa
commit 58bb2d5f93
3 changed files with 16 additions and 6 deletions

View File

@@ -21,7 +21,7 @@
<script setup>
import { ref, onMounted, defineModel, watch } from 'vue';
import { ref, onMounted, watch } from 'vue';
import { FormGroup, Radiobutton, MultiSelect } from 'pankow';
import UsersModel from '../models/UsersModel.js';
import GroupsModel from '../models/GroupsModel.js';

View File

@@ -19,11 +19,11 @@
<div class="description" v-html="description"></div>
</div>
<div v-else-if="step === STEP.INSTALL">
<form @submit="submit()" autocomplete="off">
<form @submit.prevent="submit()" autocomplete="off">
<fieldset :disabled="busy">
<input style="display: none;" type="submit" :disabled="!formValid" />
<FormGroup>
<FormGroup :class="{ 'has-error': formError.location }">
<label for="location">{{ $t('appstore.installDialog.location') }}</label>
<div>
<TextInput id="location" v-model="location" />
@@ -44,7 +44,7 @@
<!-- TODO upstreamUri for proxyapp -->
<PortBindings v-model:tcp-ports="tcpPorts" v-model:udp-ports="udpPorts" />
<PortBindings v-model:tcp-ports="tcpPorts" v-model:udp-ports="udpPorts" :error="formError"/>
<AccessControl v-model="accessRestriction"/>
<Button @click="submit" icon="fa-solid fa-circle-down" :disabled="!formValid" :loading="busy">Install {{ manifest.title }}</Button>
@@ -81,6 +81,7 @@ const dashboardModel = DashboardModel.create(API_ORIGIN, localStorage.token);
// reactive
const busy = ref(false);
const formError = ref({});
const app = ref({});
const manifest = ref({});
const step = ref(STEP.DETAILS);
@@ -138,7 +139,15 @@ async function submit() {
return window.location.href = '#/apps';
}
console.error('Failed to install:', error);
formError.value = {};
if (error.status === 'Conflict' && error.message.indexOf('port') !== -1) {
const match = error.message.match(/.*port.(.*)/);
formError.value.port = match ? parseInt(match[1]) : null;
} else if (error.status === 'Conflict' && error.message.indexOf('primary location') !== -1) {
formError.value.location = true;
} else {
console.error('Failed to install:', error);
}
}
onMounted(async () => {

View File

@@ -4,6 +4,7 @@
<Checkbox :label="port.title" v-model="port.enabled" />
<small>{{ port.description + '.' + (port.portCount >=1 ? (port.portCount + ' ports. ') : '') }}</small>
<small v-show="port.readOnly">{{ $t('appstore.installDialog.portReadOnly') }}</small>
<small class="has-error" v-show="error.port === port.value">Port already taken</small>
<NumberInput v-model="port.value" :disabled="!port.enabled" :min="1"/>
<!-- TODO <p class="text-small text-warning text-bold" ng-show="appInstall.domain.provider === 'cloudflare'">{{ 'appstore.installDialog.cloudflarePortWarning' | tr }} </p> -->
</FormGroup>
@@ -15,7 +16,7 @@
import { defineProps, defineEmits } from 'vue';
import { FormGroup, Checkbox, NumberInput } from 'pankow';
const props = defineProps([ 'tcpPorts', 'udpPorts' ]);
const props = defineProps([ 'tcpPorts', 'udpPorts', 'error' ]);
defineEmits([ 'update:tcpPorts', 'update:udpPorts' ]);
// copy value so we can use value as model value