diff --git a/dashboard/src/components/MailboxDialog.vue b/dashboard/src/components/MailboxDialog.vue
index a09479701..c718fe976 100644
--- a/dashboard/src/components/MailboxDialog.vue
+++ b/dashboard/src/components/MailboxDialog.vue
@@ -88,7 +88,7 @@ async function onSubmit() {
}
}
- emit('success');
+ emit('success', { domain: domain.value, name: name.value, fullName: name.value + '@' + domain.value });
dialog.value.close();
busy.value = false;
}
diff --git a/dashboard/src/views/EmailMailboxesView.vue b/dashboard/src/views/EmailMailboxesView.vue
index 89a08f3c6..0b45c850e 100644
--- a/dashboard/src/views/EmailMailboxesView.vue
+++ b/dashboard/src/views/EmailMailboxesView.vue
@@ -108,7 +108,7 @@ const filteredMailboxes = computed(() => {
});
const filteredMailboxesUsage = computed(() => {
- return filteredMailboxes.value.reduce((acc, m) => acc + (m.usage && m.usage.diskSize), 0);
+ return filteredMailboxes.value.reduce((acc, m) => acc + (cachedMailboxUsage.value[m.fullName] && cachedMailboxUsage.value[m.fullName].diskSize), 0);
});
const mailboxDialog = useTemplateRef('mailboxDialog');
@@ -144,59 +144,68 @@ async function onSubmitRemove() {
return console.error(error);
}
- await refresh();
+ const idx = mailboxes.value.findIndex(mbox => mbox.fullName === removeMailbox.value.fullName);
+ if (idx !== -1) mailboxes.value.splice(idx, 1);
+
removeDialog.value.close();
removeBusy.value = false;
}
+const cachedMailboxUsage = ref({});
+
+async function refreshDomainUsage(domain) {
+ const [error, usage] = await mailModel.usage(domain);
+ // retry if mail addon cannot be reached during restarts
+ if (error && error.status === 424) return setTimeout(refresh, 2000);
+ else if (error) return console.error(error);
+
+ mailboxes.value.forEach((m) => {
+ if (usage[m.fullName]) cachedMailboxUsage.value[m.fullName] = usage[m.fullName];
+ });
+
+ mailboxesUsage.value = mailboxes.value.reduce((acc, m) => acc + (cachedMailboxUsage.value[m.fullName] && cachedMailboxUsage.value[m.fullName].diskSize), 0);
+}
+
async function refreshUsage() {
- async function refreshForDomain(domain) {
- const [error, usage] = await mailModel.usage(domain);
- // retry if mail addon cannot be reached during restarts
- if (error && error.status === 424) return setTimeout(refresh, 2000);
- else if (error) return console.error(error);
-
- mailboxes.value.forEach((m) => {
- m.usage = usage[m.fullName] ?? { diskSize: 0}; // can be missing from response if no email has been received by dovecot
- });
- }
-
try {
- await eachLimit(domains.value.map(d => d.domain), 10, refreshForDomain);
+ await eachLimit(domains.value.map(d => d.domain), 10, refreshDomainUsage);
} catch (error) {
return console.error(error);
}
+}
- mailboxesUsage.value = mailboxes.value.reduce((acc, m) => acc + (m.usage && m.usage.diskSize), 0);
+async function refreshDomain(domain) {
+ const [error, result] = await mailboxesModel.list(domain);
+ if (error) throw error;
+
+ result.forEach((m) => {
+ m.fullName = m.name + '@' + m.domain;
+
+ m.owner = users.value.find(u => u.id === m.ownerId) || null;
+ if (!m.owner) m.owner = groups.value.find(g => g.id === m.ownerId) || null;
+
+ m.ownerDisplayName = m.owner ? (m.owner.username || m.owner.name) : '';
+ cachedMailboxUsage.value[m.fullName] = cachedMailboxUsage.value[m.fullName] || { diskSize: 0 };
+
+ // update in-place or add
+ const idx = mailboxes.value.findIndex(mbox => mbox.fullName === m.fullName);
+ if (idx !== -1) mailboxes.value[idx] = m;
+ else mailboxes.value.push(m);
+ });
}
async function refresh() {
- let tmp = [];
- async function refreshForDomain(domain) {
- const [error, result] = await mailboxesModel.list(domain);
- if (error) throw error;
-
- result.forEach((m) => {
- m.fullName = m.name + '@' + m.domain;
-
- m.owner = users.value.find(u => u.id === m.ownerId) || null;
- if (!m.owner) m.owner = groups.value.find(g => g.id === m.ownerId) || null;
-
- m.ownerDisplayName = m.owner ? (m.owner.username || m.owner.name) : '';
- m.usage = -1;
- });
-
- tmp = tmp.concat(result);
- }
-
try {
- await eachLimit(domains.value.map(d => d.domain), 10, refreshForDomain);
+ await eachLimit(domains.value.map(d => d.domain), 10, refreshDomain);
} catch (error) {
return console.error(error);
}
+}
- mailboxes.value = tmp;
+async function onMailboxDialogSuccess(mailbox) {
+ await refreshDomain(mailbox.domain);
+ await refreshDomainUsage(mailbox.domain);
}
onMounted(async () => {
@@ -250,7 +259,7 @@ onMounted(async () => {
-
+
@@ -264,11 +273,11 @@ onMounted(async () => {
{{ mailbox.aliases.length }}
- {{ prettyDecimalSize(mailbox.usage.diskSize) }}
+ {{ prettyDecimalSize(cachedMailboxUsage[mailbox.fullName].diskSize) }}
{{ $t('main.loadingPlaceholder') }} ...
- {{ prettyDecimalSize(mailbox.usage.quotaLimit) }}
+ {{ prettyDecimalSize(cachedMailboxUsage[mailbox.fullName].quotaLimit) }}
-