Manage domain and account resources.

This commit is contained in:
Antoine Nguyen
2022-04-07 12:00:44 +02:00
parent 45cce410c1
commit af044bd325
7 changed files with 134 additions and 22 deletions
+41 -4
View File
@@ -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')
},
@@ -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>
+9
View File
@@ -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
})
+12 -7
View File
@@ -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>
+20 -3
View File
@@ -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):