Add . and @ for domain selection labels

This commit is contained in:
Johannes Zellner
2025-09-30 16:01:11 +02:00
parent 471dd08016
commit 74c1e71fe5
5 changed files with 35 additions and 14 deletions

View File

@@ -177,6 +177,10 @@ defineExpose({
domainProvider.value = '';
upstreamUri.value = '';
domainList.forEach(d => {
d.label = '@' + d.domain;
});
domains.value = domainList;
// preselect with dashboard domain
@@ -250,7 +254,7 @@ defineExpose({
<label for="location">{{ $t('appstore.installDialog.location') }}</label>
<InputGroup>
<TextInput id="location" ref="locationInput" v-model="location" style="flex-grow: 1"/>
<SingleSelect v-model="domain" :options="domains" option-label="domain" option-key="domain" @select="onDomainChange()" :search-threshold="10"/>
<SingleSelect v-model="domain" :options="domains" option-label="label" option-key="domain" @select="onDomainChange()" :search-threshold="10"/>
</InputGroup>
<div class="text-danger" v-if="formError.location">{{ formError.location }}</div>
</FormGroup>
@@ -262,7 +266,7 @@ defineExpose({
<small>{{ port.description }}</small>
<InputGroup>
<TextInput :id="'secondaryDomainInput' + key" v-model="port.value" :placeholder="$t('appstore.installDialog.locationPlaceholder')" style="flex-grow: 1"/>
<SingleSelect v-model="port.domain" :options="domains" option-label="domain" option-key="domain" />
<SingleSelect v-model="port.domain" :options="domains" option-label="label" option-key="domain" />
</InputGroup>
</FormGroup>

View File

@@ -24,11 +24,12 @@ const storageQuotaTicks = [ 500*1000*1000, 5*1000*1000*1000, 15*1000*1000*1000,
const storageQuota = ref(5*1000*1000*1000);
const active = ref(false);
const enablePop3 = ref(false);
const domainList = ref([]);
function onAddAlias() {
aliases.value.push({
name: '',
domain: props.domains[0].domain,
domain: '@' + props.domains[0].domain,
});
}
@@ -98,6 +99,13 @@ defineExpose({
u.name = u.name || u.username || u.label || u.fqdn;
});
domainList.value = props.domains.map(d => {
return {
domain: d.domain,
label: '@' + d.domain,
};
});
dialog.value.open();
}
});
@@ -125,8 +133,7 @@ defineExpose({
<label for="nameInput">{{ $t('email.addMailboxDialog.name') }}</label>
<InputGroup>
<TextInput id="nameInput" style="flex-grow: 1;" v-model="name"/>
<div class="input-group-label">@</div>
<SingleSelect v-model="domain" :options="domains" option-key="domain" option-label="domain" />
<SingleSelect v-model="domain" :options="domainList" option-key="domain" option-label="label" />
</InputGroup>
<div class="error-label" v-if="formError">{{ formError }}</div>
</FormGroup>
@@ -154,8 +161,7 @@ defineExpose({
<div v-for="(alias, index) in aliases" :key="alias" style="margin: 5px 0;">
<InputGroup>
<TextInput style="flex-grow: 1;" v-model="alias.name"/>
<div class="input-group-label">@</div>
<SingleSelect v-model="alias.domain" :options="domains" option-key="domain" option-label="domain" />
<SingleSelect v-model="alias.domain" :options="domainList" option-key="domain" option-label="label" />
<Button tool danger icon="fa-solid fa-trash-alt" @click="onRemoveAlias(index)"/>
</InputGroup>
</div>

View File

@@ -18,6 +18,7 @@ const mailinglist = ref(null);
const membersText = ref('');
const membersOnly = ref(false);
const active = ref(true);
const domainList = ref([]);
async function onSubmit() {
busy.value = true;
@@ -66,6 +67,13 @@ defineExpose({
membersOnly.value = m ? m.membersOnly : false;
active.value = m ? m.active : true;
domainList.value = props.domains.map(d => {
return {
domain: d.domain,
label: '@' + d.domain,
};
});
dialog.value.open();
}
});
@@ -94,8 +102,7 @@ defineExpose({
<label for="nameInput">{{ $t('email.addMailinglistDialog.name') }}</label>
<InputGroup>
<TextInput id="nameInput" style="flex-grow: 1;" v-model="name"/>
<div class="input-group-label">@</div>
<SingleSelect v-model="domain" :options="domains" option-key="domain" option-label="domain" />
<SingleSelect v-model="domain" :options="domainList" option-key="domain" option-label="label" />
</InputGroup>
<div class="error-label" v-if="formError.name">{{ formError.name }}</div>
</FormGroup>

View File

@@ -138,6 +138,10 @@ onMounted(async () => {
const [error, result] = await domainsModel.list();
if (error) return console.error(error);
result.forEach(d => {
d.label = '@' + d.domain;
});
domains.value = result;
subdomain.value = props.app.subdomain;
@@ -192,7 +196,7 @@ onMounted(async () => {
<InputGroup style="flex-grow: 1">
<TextInput style="flex-grow: 1" v-model="subdomain" :placeholder="$t('app.location.locationPlaceholder')"/>
<SingleSelect :disabled="busy" :options="domains" v-model="domain" option-key="domain" option-label="domain" :search-threshold="10"/>
<SingleSelect :disabled="busy" :options="domains" v-model="domain" option-key="domain" option-label="label" :search-threshold="10"/>
</InputGroup>
<div class="warning-label" v-if="isNoopOrManual(domain)" v-html="$t('appstore.installDialog.manualWarning', { location: ((subdomain ? subdomain + '.' : '') + domain) })"></div>
</FormGroup>
@@ -202,7 +206,7 @@ onMounted(async () => {
<small>{{ item.description }}</small>
<InputGroup style="flex-grow: 1">
<TextInput style="flex-grow: 1" :id="'secondaryDomainInput' + item.containerPort" v-model="item.subdomain" :placeholder="$t('appstore.installDialog.locationPlaceholder')"/>
<SingleSelect :disabled="busy" :options="domains" v-model="item.domain" option-key="domain" option-label="domain" :search-threshold="10"/>
<SingleSelect :disabled="busy" :options="domains" v-model="item.domain" option-key="domain" option-label="label" :search-threshold="10"/>
</InputGroup>
<div class="warning-label" v-if="isNoopOrManual(item.domain)" v-html="$t('appstore.installDialog.manualWarning', { location: ((item.subdomain ? item.subdomain + '.' : '') + item.domain) })"></div>
</FormGroup>
@@ -217,7 +221,7 @@ onMounted(async () => {
<div style="display: flex; gap: 10px;">
<InputGroup style="flex-grow: 1">
<TextInput style="flex-grow: 1" v-model="item.subdomain" :placeholder="$t('app.location.locationPlaceholder')"/>
<SingleSelect :disabled="busy" :options="domains" v-model="item.domain" option-key="domain" option-label="domain" :search-threshold="10"/>
<SingleSelect :disabled="busy" :options="domains" v-model="item.domain" option-key="domain" option-label="label" :search-threshold="10"/>
</InputGroup>
<Button danger tool :disabled="busy" icon="fa-solid fa-trash" @click="onRemoveAlias(index)"/>
</div>
@@ -235,7 +239,7 @@ onMounted(async () => {
<div style="display: flex; gap: 10px;">
<InputGroup style="flex-grow: 1">
<TextInput style="flex-grow: 1" v-model="item.subdomain" :placeholder="$t('app.location.locationPlaceholder')"/>
<SingleSelect :disabled="busy" :options="domains" v-model="item.domain" option-key="domain" option-label="domain" :search-threshold="10"/>
<SingleSelect :disabled="busy" :options="domains" v-model="item.domain" option-key="domain" option-label="label" :search-threshold="10"/>
</InputGroup>
<Button danger tool :disabled="busy" icon="fa-solid fa-trash" @click="onRemoveRedirect(index)"/>
</div>

View File

@@ -85,8 +85,8 @@ onMounted(() => {
<div>
<label>{{ $t('app.repair.taskError.title') }}</label>
<div>{{ $t('app.repair.taskError.description') }}</div>
<div v-if="app.error" style="margin-top: 10px;">An error occurred during the <b>{{ taskNameFromInstallationState(app.error.details.installationState) }}</b> operation: <span class="text-danger"><b>{{ app.error.reason + ': ' + app.error.message }}</b></span></div>
<br/>
<div v-if="app.error">An error occurred during the <b>{{ taskNameFromInstallationState(app.error.details.installationState) }}</b> operation: <span class="text-danger"><b>{{ app.error.reason + ': ' + app.error.message }}</b></span></div>
<Button @click="onRepair()" :disabled="busyRepair || app.taskId || !app.error" :loading="busyRepair">{{ $t('app.repair.taskError.retryAction', { task: app.error ? taskNameFromInstallationState(app.error.details.installationState) : '' }) }}</Button>
</div>
</div>