mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
Manage domain and account resources.
This commit is contained in:
@@ -133,6 +133,18 @@
|
||||
<domain-transport-form ref="transportForm" :domain="editedDomain" />
|
||||
</v-expansion-panel-content>
|
||||
</v-expansion-panel>
|
||||
<v-expansion-panel v-if="limitsConfig.enable_domain_limits && (authUser.role === 'SuperAdmins' || authUser.role === 'Resellers')">
|
||||
<v-expansion-panel-header>
|
||||
<v-row no-gutters>
|
||||
<v-col cols="4">
|
||||
<translate>Resources</translate>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-expansion-panel-header>
|
||||
<v-expansion-panel-content>
|
||||
<resources-form ref="resourcesForm" :resources="domain.resources" />
|
||||
</v-expansion-panel-content>
|
||||
</v-expansion-panel>
|
||||
</v-expansion-panels>
|
||||
<div class="mt-4 d-flex justify-end">
|
||||
<v-btn color="grey lighten-1" @click="$router.go(-1)">
|
||||
@@ -151,18 +163,28 @@ import DomainDNSForm from './DomainDNSForm'
|
||||
import DomainGeneralForm from './DomainGeneralForm'
|
||||
import DomainLimitationsForm from './DomainLimitationsForm'
|
||||
import DomainTransportForm from './DomainTransportForm'
|
||||
import { mapGetters } from 'vuex'
|
||||
import parameters from '@/api/parameters'
|
||||
import ResourcesForm from '@/components/tools/ResourcesForm'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
'domain-dns-form': DomainDNSForm,
|
||||
DomainGeneralForm,
|
||||
DomainLimitationsForm,
|
||||
DomainTransportForm
|
||||
DomainTransportForm,
|
||||
ResourcesForm
|
||||
},
|
||||
props: ['domain'],
|
||||
computed: {
|
||||
...mapGetters({
|
||||
authUser: 'auth/authUser'
|
||||
})
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
editedDomain: {},
|
||||
limitsConfig: {},
|
||||
panel: 0
|
||||
}
|
||||
},
|
||||
@@ -174,14 +196,29 @@ export default {
|
||||
return
|
||||
}
|
||||
}
|
||||
if (this.editedDomain.type === 'relaydomain') {
|
||||
this.$refs.transportForm.checkSettingTypes(this.editedDomain)
|
||||
if (this.$refs.resourcesForm !== undefined) {
|
||||
const valid = await this.$refs.resourcesForm.validateForm()
|
||||
if (!valid) {
|
||||
return
|
||||
}
|
||||
}
|
||||
this.$store.dispatch('domains/updateDomain', this.editedDomain).then(resp => {
|
||||
const data = { ...this.editedDomain }
|
||||
if (data.transport === null) {
|
||||
delete data.transport
|
||||
}
|
||||
if (data.type === 'relaydomain') {
|
||||
this.$refs.transportForm.checkSettingTypes(data)
|
||||
}
|
||||
this.$store.dispatch('domains/updateDomain', data).then(resp => {
|
||||
bus.$emit('notification', { msg: this.$gettext('Domain updated') })
|
||||
})
|
||||
}
|
||||
},
|
||||
created () {
|
||||
parameters.getApplication('limits').then(resp => {
|
||||
this.limitsConfig = resp.data
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
domain: {
|
||||
handler: function (val) {
|
||||
|
||||
@@ -98,16 +98,16 @@
|
||||
<account-mailbox-form ref="mailboxForm" :account="editedAccount" />
|
||||
</v-expansion-panel-content>
|
||||
</v-expansion-panel>
|
||||
<v-expansion-panel v-if="account.role !== 'SimpleUsers'">
|
||||
<v-expansion-panel v-if="limitsConfig.enable_admin_limits && account.role !== 'SimpleUsers'">
|
||||
<v-expansion-panel-header>
|
||||
<v-row no-gutters>
|
||||
<v-col cols="4">
|
||||
<translate>Limits</translate>
|
||||
<translate>Resources</translate>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-expansion-panel-header>
|
||||
<v-expansion-panel-content>
|
||||
<account-resources-form ref="resourcesForm" :account="editedAccount" />
|
||||
<resources-form ref="resourcesForm" :resources="editedAccount.resources" />
|
||||
</v-expansion-panel-content>
|
||||
</v-expansion-panel>
|
||||
</v-expansion-panels>
|
||||
@@ -128,15 +128,16 @@ import { bus } from '@/main'
|
||||
import accounts from '@/api/accounts'
|
||||
import AccountGeneralForm from './AccountGeneralForm'
|
||||
import AccountMailboxForm from './AccountMailboxForm'
|
||||
import AccountResourcesForm from './AccountResourcesForm'
|
||||
import AccountRoleForm from './AccountRoleForm'
|
||||
import ResourcesForm from '@/components/tools/ResourcesForm'
|
||||
import parameters from '@/api/parameters'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AccountGeneralForm,
|
||||
AccountMailboxForm,
|
||||
AccountResourcesForm,
|
||||
AccountRoleForm
|
||||
AccountRoleForm,
|
||||
ResourcesForm
|
||||
},
|
||||
props: ['account'],
|
||||
computed: {
|
||||
@@ -147,6 +148,7 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
editedAccount: {},
|
||||
limitsConfig: {},
|
||||
panel: 0
|
||||
}
|
||||
},
|
||||
@@ -197,6 +199,11 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
parameters.getApplication('limits').then(resp => {
|
||||
this.limitsConfig = resp.data
|
||||
})
|
||||
},
|
||||
mounted () {
|
||||
this.$store.dispatch('identities/fetchDomains')
|
||||
},
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<div
|
||||
v-for="resource in account.resources"
|
||||
v-for="resource in resources"
|
||||
:key="resource.name"
|
||||
class="mt-4"
|
||||
>
|
||||
@@ -22,7 +22,7 @@
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
account: Object
|
||||
resources: Array
|
||||
},
|
||||
methods: {
|
||||
getProgressColor (value) {
|
||||
@@ -0,0 +1,37 @@
|
||||
<template>
|
||||
<validation-observer ref="observer">
|
||||
<validation-provider
|
||||
v-for="resource in resources"
|
||||
:key="resource.name"
|
||||
v-slot="{ errors }"
|
||||
rules="required"
|
||||
>
|
||||
<label class="m-label">{{ resource.label }}</label>
|
||||
<v-text-field
|
||||
v-model="resource.max_value"
|
||||
type="number"
|
||||
outlined
|
||||
dense
|
||||
:error-messages="errors"
|
||||
/>
|
||||
</validation-provider>
|
||||
</validation-observer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
resources: Array
|
||||
},
|
||||
methods: {
|
||||
async validateForm () {
|
||||
return await this.$refs.observer.validate()
|
||||
},
|
||||
getPayload () {
|
||||
return this.resources.map(r => {
|
||||
return { name: r.name, max_value: r.max_value }
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -17,6 +17,8 @@
|
||||
</v-col>
|
||||
<v-col cols="6">
|
||||
<dns-detail :domain="domain" />
|
||||
<div class="mt-4" />
|
||||
<resources v-if="limitsConfig.enable_domain_limits && domain.resources && domain.resources.length" :resources="domain.resources" />
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-layout>
|
||||
@@ -45,6 +47,8 @@ import AdministratorList from '@/components/domains/AdministratorList'
|
||||
import DNSDetail from '@/components/domains/DNSDetail'
|
||||
import DomainForm from '@/components/domains/DomainForm'
|
||||
import DomainSummary from '@/components/domains/DomainSummary'
|
||||
import parameters from '@/api/parameters'
|
||||
import Resources from '@/components/tools/Resources'
|
||||
import TimeSerieChart from '@/components/tools/TimeSerieChart'
|
||||
|
||||
export default {
|
||||
@@ -53,11 +57,13 @@ export default {
|
||||
'dns-detail': DNSDetail,
|
||||
DomainForm,
|
||||
DomainSummary,
|
||||
Resources,
|
||||
TimeSerieChart
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
domain: { pk: this.$route.params.id },
|
||||
limitsConfig: {},
|
||||
showEditForm: false,
|
||||
showAdminList: false
|
||||
}
|
||||
@@ -65,6 +71,9 @@ export default {
|
||||
methods: {
|
||||
},
|
||||
mounted () {
|
||||
parameters.getApplication('limits').then(resp => {
|
||||
this.limitsConfig = resp.data
|
||||
})
|
||||
domains.getDomain(this.$route.params.id).then(resp => {
|
||||
this.domain = resp.data
|
||||
})
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
<account-summary :account="account" />
|
||||
</v-col>
|
||||
<v-col cols="6">
|
||||
<account-resources
|
||||
v-if="account.resources && account.resources.length"
|
||||
:account="account"
|
||||
<resources
|
||||
v-if="limitsConfig.enable_admin_limits && account.resources && account.resources.length"
|
||||
:resources="account.resources"
|
||||
/>
|
||||
<account-aliases v-if="account.aliases" class="mt-2" :account="account" />
|
||||
</v-col>
|
||||
@@ -29,26 +29,31 @@
|
||||
<script>
|
||||
import accounts from '@/api/accounts'
|
||||
import AccountAliases from '@/components/identities/AccountAliases'
|
||||
import AccountResources from '@/components/identities/AccountResources'
|
||||
import AccountSummary from '@/components/identities/AccountSummary'
|
||||
import DomainAdminDomains from '@/components/identities/DomainAdminDomains'
|
||||
import parameters from '@/api/parameters'
|
||||
import Resources from '@/components/tools/Resources'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AccountAliases,
|
||||
AccountResources,
|
||||
AccountSummary,
|
||||
DomainAdminDomains
|
||||
DomainAdminDomains,
|
||||
Resources
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
account: { pk: this.$route.params.id }
|
||||
account: { pk: this.$route.params.id },
|
||||
limitsConfig: {}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
accounts.get(this.$route.params.id).then(resp => {
|
||||
this.account = resp.data
|
||||
})
|
||||
parameters.getApplication('limits').then(resp => {
|
||||
this.limitsConfig = resp.data
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -35,15 +35,24 @@ class CreateDomainAdminSerializer(serializers.Serializer):
|
||||
with_aliases = serializers.BooleanField(default=False)
|
||||
|
||||
|
||||
class DomainResourceSerializer(serializers.ModelSerializer):
|
||||
"""Serializer for domain resource."""
|
||||
|
||||
class Meta:
|
||||
fields = ("name", "label", "max_value", "current_value", "usage")
|
||||
model = limits_models.DomainObjectLimit
|
||||
|
||||
|
||||
class DomainSerializer(v1_serializers.DomainSerializer):
|
||||
"""Domain serializer for v2 API."""
|
||||
|
||||
domain_admin = CreateDomainAdminSerializer(required=False, write_only=True)
|
||||
resources = DomainResourceSerializer(many=True, source="domainobjectlimit_set")
|
||||
transport = transport_serializers.TransportSerializer(required=False)
|
||||
|
||||
class Meta(v1_serializers.DomainSerializer.Meta):
|
||||
fields = v1_serializers.DomainSerializer.Meta.fields + (
|
||||
"domain_admin", "transport"
|
||||
"domain_admin", "resources", "transport"
|
||||
)
|
||||
|
||||
def validate(self, data):
|
||||
@@ -122,6 +131,7 @@ class DomainSerializer(v1_serializers.DomainSerializer):
|
||||
def update(self, instance, validated_data):
|
||||
"""Update domain and create/update transport."""
|
||||
transport_def = validated_data.pop("transport", None)
|
||||
resources = validated_data.pop("domainobjectlimit_set", None)
|
||||
super().update(instance, validated_data)
|
||||
if transport_def and instance.type == "relaydomain":
|
||||
transport = getattr(instance, "transport", None)
|
||||
@@ -138,6 +148,11 @@ class DomainSerializer(v1_serializers.DomainSerializer):
|
||||
if created:
|
||||
instance.transport = transport
|
||||
instance.save()
|
||||
if resources:
|
||||
for resource in resources:
|
||||
instance.domainobjectlimit_set.filter(
|
||||
name=resource["name"]
|
||||
).update(max_value=resource["max_value"])
|
||||
return instance
|
||||
|
||||
|
||||
@@ -253,7 +268,7 @@ class IdentitySerializer(serializers.Serializer):
|
||||
tags = TagSerializer(many=True)
|
||||
|
||||
|
||||
class ResourceSerializer(serializers.ModelSerializer):
|
||||
class AccountResourceSerializer(serializers.ModelSerializer):
|
||||
"""Serializer for user resource."""
|
||||
|
||||
class Meta:
|
||||
@@ -277,6 +292,8 @@ class AccountSerializer(v1_serializers.AccountSerializer):
|
||||
)
|
||||
|
||||
def get_resources(self, account):
|
||||
if account.role == 'SimpleUsers':
|
||||
return []
|
||||
resources = []
|
||||
for limit in account.userobjectlimit_set.all():
|
||||
tpl = limits_constants.DEFAULT_USER_LIMITS[limit.name]
|
||||
@@ -284,7 +301,7 @@ class AccountSerializer(v1_serializers.AccountSerializer):
|
||||
if account.role != tpl["required_role"]:
|
||||
continue
|
||||
resources.append(limit)
|
||||
return ResourceSerializer(resources, many=True).data
|
||||
return AccountResourceSerializer(resources, many=True).data
|
||||
|
||||
|
||||
class MailboxSerializer(serializers.ModelSerializer):
|
||||
|
||||
Reference in New Issue
Block a user