2025-03-11 12:38:54 +01:00
|
|
|
<script setup>
|
|
|
|
|
|
|
|
|
|
import { ref, onMounted, computed } from 'vue';
|
|
|
|
|
import { MultiSelect, InputGroup, Button, FormGroup } from 'pankow';
|
|
|
|
|
import SettingsItem from './SettingsItem.vue';
|
|
|
|
|
import DomainsModel from '../models/DomainsModel.js';
|
|
|
|
|
import MailModel from '../models/MailModel.js';
|
2025-03-14 21:51:26 +01:00
|
|
|
import MailboxesModel from '../models/MailboxesModel.js';
|
2025-03-11 12:38:54 +01:00
|
|
|
|
2025-05-13 18:11:10 +02:00
|
|
|
const props = defineProps([ 'domainConfig', 'disabled' ]);
|
2025-03-11 12:38:54 +01:00
|
|
|
|
|
|
|
|
const domainsModel = DomainsModel.create();
|
|
|
|
|
const mailModel = MailModel.create();
|
2025-03-14 21:51:26 +01:00
|
|
|
const mailboxesModel = MailboxesModel.create();
|
2025-03-11 12:38:54 +01:00
|
|
|
|
|
|
|
|
const busy = ref(true);
|
|
|
|
|
const addresses = ref([]);
|
|
|
|
|
const currentAddresses = ref([]);
|
|
|
|
|
const allAddresses = ref([]);
|
|
|
|
|
|
|
|
|
|
async function onSubmit() {
|
|
|
|
|
busy.value = true;
|
|
|
|
|
|
|
|
|
|
const [error] = await mailModel.setCatchallAddresses(props.domainConfig.domain, addresses.value);
|
|
|
|
|
if (error) return console.error(error);
|
|
|
|
|
|
|
|
|
|
currentAddresses.value = addresses.value.slice();
|
|
|
|
|
busy.value = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const hasChanged = computed(() => {
|
|
|
|
|
if (currentAddresses.value.length !== addresses.value.length) return true;
|
|
|
|
|
|
|
|
|
|
const currentSorted = currentAddresses.value.toSorted();
|
|
|
|
|
const selectedSorted = addresses.value.toSorted();
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < currentSorted.length; i++) {
|
|
|
|
|
if (currentSorted[i] !== selectedSorted[i]) return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
onMounted(async () => {
|
|
|
|
|
const [error, result] = await domainsModel.list();
|
|
|
|
|
if (error) return console.error(error);
|
|
|
|
|
|
|
|
|
|
// only for inbound enabled but then we have extra rest calls
|
|
|
|
|
|
|
|
|
|
for (const domain of result) {
|
2025-03-14 21:51:26 +01:00
|
|
|
const [error, result] = await mailboxesModel.list(domain.domain);
|
2025-03-11 12:38:54 +01:00
|
|
|
if (error) return console.error(error);
|
|
|
|
|
|
|
|
|
|
allAddresses.value = allAddresses.value.concat(result.map(mailbox => {
|
|
|
|
|
return {
|
|
|
|
|
id: `${mailbox.name}@${mailbox.domain}`,
|
|
|
|
|
label: `${mailbox.name}@${mailbox.domain}`,
|
|
|
|
|
};
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-08 17:06:10 +02:00
|
|
|
addresses.value = props.domainConfig.catchAll ? props.domainConfig.catchAll.slice() : [];
|
|
|
|
|
currentAddresses.value = props.domainConfig.catchAll ? props.domainConfig.catchAll.slice() : [];
|
2025-03-11 12:38:54 +01:00
|
|
|
|
|
|
|
|
busy.value = false;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<template>
|
2025-05-03 11:00:21 +02:00
|
|
|
<SettingsItem wrap>
|
2025-03-11 12:38:54 +01:00
|
|
|
<FormGroup>
|
|
|
|
|
<label>{{ $t('email.incoming.catchall.title') }}</label>
|
|
|
|
|
<div v-html="$t('email.incoming.catchall.description')"></div>
|
|
|
|
|
</FormGroup>
|
|
|
|
|
<div style="display: flex; gap: 6px; align-items: center;">
|
|
|
|
|
<InputGroup>
|
2025-05-13 18:11:10 +02:00
|
|
|
<MultiSelect v-model="addresses" :options="allAddresses" option-label="label" option-key="id" :disabled="disabled"/>
|
|
|
|
|
<Button @click="onSubmit()" tool :disabled="disabled || busy || !hasChanged" :loading="busy">{{ $t('email.incoming.catchall.saveAction') }}</Button>
|
2025-03-11 12:38:54 +01:00
|
|
|
</InputGroup>
|
|
|
|
|
</div>
|
|
|
|
|
</SettingsItem>
|
|
|
|
|
</template>
|