Only refresh changed email domains when mailboxes change
This commit is contained in:
@@ -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 () => {
|
||||
</div>
|
||||
</Dialog>
|
||||
|
||||
<MailboxDialog ref="mailboxDialog" :apps="apps" :users="users" :groups="groups" :domains="domains" @success="refresh()"/>
|
||||
<MailboxDialog ref="mailboxDialog" :apps="apps" :users="users" :groups="groups" :domains="domains" @success="onMailboxDialogSuccess"/>
|
||||
|
||||
<Section :title="$t('email.incoming.mailboxes.title')">
|
||||
<template #header-title-extra>
|
||||
@@ -264,11 +273,11 @@ onMounted(async () => {
|
||||
<TableView :columns="columns" :model="filteredMailboxes" :busy="busy" :fixed-layout="true" :placeholder="$t(searchFilter ? 'email.incoming.mailboxes.noMatchesPlaceholder' : 'email.incoming.mailboxes.emptyPlaceholder')">
|
||||
<template #aliases="mailbox">{{ mailbox.aliases.length }}</template>
|
||||
<template #usage="mailbox">
|
||||
<span v-if="mailbox.usage !== -1">{{ prettyDecimalSize(mailbox.usage.diskSize) }}</span>
|
||||
<span v-if="cachedMailboxUsage[mailbox.fullName]">{{ prettyDecimalSize(cachedMailboxUsage[mailbox.fullName].diskSize) }}</span>
|
||||
<span v-else>{{ $t('main.loadingPlaceholder') }} ...</span>
|
||||
</template>
|
||||
<template #storageQuota="mailbox">
|
||||
<span v-if="mailbox.usage && mailbox.usage.quotaLimit">{{ prettyDecimalSize(mailbox.usage.quotaLimit) }}</span>
|
||||
<span v-if="cachedMailboxUsage[mailbox.fullName] && typeof cachedMailboxUsage[mailbox.fullName].quotaLimit !== 'undefined'">{{ prettyDecimalSize(cachedMailboxUsage[mailbox.fullName].quotaLimit) }}</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
<template #actions="mailbox">
|
||||
|
||||
Reference in New Issue
Block a user