Add error state for SaveIndicator and put it in more places

This commit is contained in:
Johannes Zellner
2026-02-09 20:25:09 +01:00
parent d84037a0dd
commit 55bc26bd09
3 changed files with 42 additions and 5 deletions
+21 -2
View File
@@ -4,17 +4,29 @@ import { ref } from 'vue';
import { Icon } from '@cloudron/pankow';
const visible = ref(false);
const success = ref(false);
let timeoutId;
defineExpose({
success() {
clearTimeout(timeoutId);
success.value = true;
visible.value = true;
timeoutId = setTimeout(() => {
visible.value = false;
}, 3000);
}, 2000);
},
error() {
clearTimeout(timeoutId);
success.value = false;
visible.value = true;
timeoutId = setTimeout(() => {
visible.value = false;
}, 2000);
}
});
@@ -22,7 +34,7 @@ defineExpose({
<template>
<Transition name="bounce">
<div class="save-indicator" v-if="visible"><Icon icon="fa-solid fa-check"/></div>
<div class="save-indicator" v-if="visible" :class="{ success: success, error: !success }"><Icon :icon="success ? 'fa-solid fa-check' : 'fa-solid fa-xmark'"/></div>
</Transition>
</template>
@@ -31,9 +43,16 @@ defineExpose({
.save-indicator {
position: absolute;
right: -10px;
}
.save-indicator.success {
color: var(--pankow-color-success);
}
.save-indicator.error {
color: var(--pankow-color-danger);
}
.bounce-enter-active {
animation: bounce-in 0.5s;
}
+13 -1
View File
@@ -4,6 +4,7 @@
import { ref, onMounted, useTemplateRef, computed } from 'vue';
import { Button, InputDialog, Dialog, FormGroup, Switch } from '@cloudron/pankow';
import { prettyDecimalSize } from '@cloudron/pankow/utils';
import SaveIndicator from '../components/SaveIndicator.vue';
import Section from '../components/Section.vue';
import SettingsItem from '../components/SettingsItem.vue';
import MailServerLocation from '../components/MailServerLocation.vue';
@@ -68,38 +69,46 @@ async function onSubmitAcl() {
dnsblZonesBusy.value = false;
}
const mailboxSharingEnabled = ref(false);
const mailboxSharingSaveIndicator = useTemplateRef('mailboxSharingSaveIndicator');
async function onChangeMailboxSharing(value) {
const [error] = await mailModel.setMailboxSharing(value);
if (error) {
mailboxSharingEnabled.value = !value;
mailboxSharingSaveIndicator.value.error();
return console.error(error);
}
mailboxSharingSaveIndicator.value.success();
}
const virtualAllMailEnabled = ref(false);
const virtualAllMailSaveIndicator = useTemplateRef('virtualAllMailSaveIndicator');
async function onChangeVirtualAllMail(value) {
const [error] = await mailModel.setVirtualAllMail(value);
if (error) {
virtualAllMailEnabled.value = !value;
virtualAllMailSaveIndicator.value.error();
return console.error(error);
}
virtualAllMailSaveIndicator.value.success();
}
const ftsEnabled = ref(false);
const hasMailServiceSufficientMemory = ref(false);
const ftsSaveIndicator = useTemplateRef('ftsSaveIndicator');
async function onChangeFts(value) {
const [error] = await mailModel.setFtsConfig(value);
if (error) {
ftsEnabled.value = !value;
ftsSaveIndicator.value.error();
return console.error(error);
}
ftsSaveIndicator.value.success();
}
@@ -260,6 +269,7 @@ onMounted(async () => {
<div>{{ $t('emails.mailboxSharing.description') }}</div>
</FormGroup>
<Switch v-model="mailboxSharingEnabled" @change="onChangeMailboxSharing"/>
<SaveIndicator ref="mailboxSharingSaveIndicator"/>
</SettingsItem>
<SettingsItem>
@@ -268,6 +278,7 @@ onMounted(async () => {
<div v-html="$t('emails.changeVirtualAllMailDialog.description')"></div>
</FormGroup>
<Switch v-model="virtualAllMailEnabled" @change="onChangeVirtualAllMail"/>
<SaveIndicator ref="virtualAllMailSaveIndicator"/>
</SettingsItem>
<SettingsItem wrap>
@@ -288,6 +299,7 @@ onMounted(async () => {
<div v-html="$t('emails.solrConfig.description')"></div>
</FormGroup>
<Switch v-model="ftsEnabled" @change="onChangeFts" :disabled="!ftsEnabled && !hasMailServiceSufficientMemory"/>
<SaveIndicator ref="ftsSaveIndicator"/>
</SettingsItem>
<SettingsItem>
+8 -2
View File
@@ -26,7 +26,10 @@ const timezoneSaveIndicator = useTemplateRef('timezoneSaveIndicator');
async function onTimeZoneChange(value) {
const [error] = await cloudronModel.setTimeZone(value);
if (error) return console.error(error);
if (error) {
timezoneSaveIndicator.value.error();
return console.error(error);
}
currentTimeZone.value = value;
@@ -41,7 +44,10 @@ const languageSaveIndicator = useTemplateRef('languageSaveIndicator');
async function onLanguageChange(value) {
const [error] = await cloudronModel.setLanguage(value);
if (error) return console.error(error);
if (error) {
languageSaveIndicator.value.error();
return console.error(error);
}
currentLanguage.value = value;