mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-19 05:58:34 +02:00
Revert to old navbar layout, Improved provider creation
This commit is contained in:
@@ -23,5 +23,8 @@ export default {
|
||||
},
|
||||
checkProvider (params) {
|
||||
return repository.post(`/${resource}/check_connection/`, params)
|
||||
},
|
||||
checkAssociatedDomain (params) {
|
||||
return repository.post(`/${resource}/check_associated_domain/`, params)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<validation-provider
|
||||
v-slot="{ errors }"
|
||||
rules="required"
|
||||
vid="newd_omain"
|
||||
vid="new_domain"
|
||||
>
|
||||
<v-text-field
|
||||
ref="newdomainField"
|
||||
@@ -58,6 +58,8 @@
|
||||
|
||||
<script>
|
||||
|
||||
import providerApi from '@/api/imap_migration/providers'
|
||||
|
||||
export default {
|
||||
props: ['value'],
|
||||
data () {
|
||||
@@ -70,6 +72,13 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
reset () {
|
||||
this.domains = []
|
||||
this.domain = {
|
||||
initialdomain: '',
|
||||
new_domain: ''
|
||||
}
|
||||
},
|
||||
async validateForm () {
|
||||
return await this.$refs.observer.validate()
|
||||
},
|
||||
@@ -78,13 +87,19 @@ export default {
|
||||
},
|
||||
async addDomain () {
|
||||
if (await this.validateForm()) {
|
||||
this.domains.push({
|
||||
name: this.domain.initialdomain,
|
||||
new_domain: this.domain.new_domain
|
||||
providerApi.checkAssociatedDomain(this.domain).then(response => {
|
||||
if (response.status === 200) {
|
||||
this.domains.push({
|
||||
name: this.domain.initialdomain,
|
||||
new_domain: this.domain.new_domain
|
||||
})
|
||||
this.$emit('input', this.domains)
|
||||
this.$refs.initialdomainField.reset()
|
||||
this.$refs.newdomainField.reset()
|
||||
}
|
||||
}).catch(error => {
|
||||
this.$refs.observer.setErrors(error.response.data)
|
||||
})
|
||||
this.$emit('input', this.domains)
|
||||
this.$refs.initialdomainField.reset()
|
||||
this.$refs.newdomainField.reset()
|
||||
}
|
||||
},
|
||||
removeDomain (index) {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
<template>
|
||||
<creation-form
|
||||
ref="form"
|
||||
:title="'New provider'|translate"
|
||||
:steps="steps"
|
||||
:form-observer-getter="getObserver"
|
||||
:form-getter="getForm"
|
||||
:validate-object="validateProvider"
|
||||
:summary-sections="summarySections"
|
||||
@close="close"
|
||||
@@ -88,16 +90,17 @@ export default {
|
||||
},
|
||||
close () {
|
||||
this.initProvider()
|
||||
this.$refs.form.resetForm()
|
||||
this.$emit('close')
|
||||
},
|
||||
getForm (step) {
|
||||
return this.$refs[`form_${step}`]
|
||||
},
|
||||
getObserver (step) {
|
||||
return this.$refs[`form_${step}`].$refs.observer
|
||||
},
|
||||
validateProvider () {
|
||||
|
||||
},
|
||||
performConnectionCheck () {
|
||||
|
||||
},
|
||||
submit () {
|
||||
const data = JSON.parse(JSON.stringify(this.provider))
|
||||
|
||||
@@ -93,6 +93,9 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
reset () {
|
||||
this.form = {}
|
||||
},
|
||||
async checkConnection () {
|
||||
if (await this.validateForm()) {
|
||||
this.loading = true
|
||||
@@ -123,6 +126,7 @@ export default {
|
||||
},
|
||||
mounted () {
|
||||
this.form = { ...this.value }
|
||||
console.error(this.value)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,149 +0,0 @@
|
||||
<template>
|
||||
<v-list>
|
||||
<template v-for="item in mainMenuItems">
|
||||
<template v-if="displayMenuItem(item)">
|
||||
<v-list-item
|
||||
v-if="!item.children"
|
||||
class="menu-item"
|
||||
:to="item.to"
|
||||
link
|
||||
:key="item.title"
|
||||
:exact="item.exact"
|
||||
>
|
||||
<v-list-item-icon v-if="item.icon">
|
||||
<v-icon>{{ item.icon }}</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{ item.text }}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<v-list-group v-else
|
||||
color="white"
|
||||
:key="item.text"
|
||||
:prepend-icon="item.icon"
|
||||
no-action>
|
||||
<template v-slot:activator>
|
||||
<v-list-item-title>{{ item.text }}</v-list-item-title>
|
||||
</template>
|
||||
|
||||
<template v-for="subitem in item.children">
|
||||
<v-list-item v-if="!subitem.children"
|
||||
:key="subitem.text"
|
||||
:to="subitem.to"
|
||||
link>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{ subitem.text }}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<v-list-group v-else
|
||||
:key="subitem.text"
|
||||
:value="true"
|
||||
no-action
|
||||
sub-group>
|
||||
<template v-slot:activator>
|
||||
<v-list-item-title>{{ subitem.text }}</v-list-item-title>
|
||||
</template>
|
||||
<v-list-item v-for="subsubitem in subitem.children"
|
||||
:key="subsubitem.text"
|
||||
:to="subsubitem.to"
|
||||
link>
|
||||
<v-list-item-title>{{ subsubitem.text }}</v-list-item-title>
|
||||
</v-list-item>
|
||||
</v-list-group>
|
||||
</template>
|
||||
</v-list-group>
|
||||
</template>
|
||||
</template>
|
||||
<settings-drawer
|
||||
:parametersList="parametersList"
|
||||
:extension="false"
|
||||
/>
|
||||
</v-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import SettingsDrawer from './SettingsDrawer.vue'
|
||||
|
||||
export default {
|
||||
props: ['parametersList'],
|
||||
components: {
|
||||
SettingsDrawer
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
authUser: 'auth/authUser'
|
||||
})
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
mainMenuItems: [
|
||||
{
|
||||
text: this.$gettext('Dashboard'),
|
||||
to: { name: 'Dashboard' },
|
||||
icon: 'mdi-view-dashboard-outline',
|
||||
exact: true
|
||||
},
|
||||
{
|
||||
text: this.$gettext('Domains'),
|
||||
to: { name: 'DomainList' },
|
||||
icon: 'mdi-domain',
|
||||
roles: ['DomainAdmins', 'Resellers', 'SuperAdmins']
|
||||
},
|
||||
{
|
||||
text: this.$gettext('Identities'),
|
||||
to: { name: 'Identities' },
|
||||
icon: 'mdi-account',
|
||||
roles: ['DomainAdmins', 'Resellers', 'SuperAdmins']
|
||||
},
|
||||
{
|
||||
text: this.$gettext('Alarms'),
|
||||
to: { name: 'Alarms' },
|
||||
icon: 'mdi-bell'
|
||||
},
|
||||
{
|
||||
icon: 'mdi-history',
|
||||
text: this.$gettext('Logs'),
|
||||
roles: ['SuperAdmins', 'Resellers', 'DomainAdmins'],
|
||||
children: [
|
||||
{
|
||||
text: this.$gettext('Audit trail'),
|
||||
to: { name: 'AuditTrail' },
|
||||
roles: ['SuperAdmins']
|
||||
},
|
||||
{
|
||||
text: this.$gettext('Messages'),
|
||||
to: { name: 'MessageLog' },
|
||||
roles: ['DomainAdmins', 'Resellers', 'SuperAdmins']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
icon: 'mdi-information',
|
||||
text: this.$gettext('Information'),
|
||||
roles: ['SuperAdmins'],
|
||||
to: { name: 'Information' }
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
displayMenuItem (item) {
|
||||
return (item.roles === undefined || item.roles.indexOf(this.authUser.role) !== -1) && (item.condition === undefined || item.condition())
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.v-list-item {
|
||||
&--active {
|
||||
&::before {
|
||||
opacity: 0;
|
||||
}
|
||||
background-color: #034bad;
|
||||
color: white;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,154 +0,0 @@
|
||||
<template>
|
||||
<v-list>
|
||||
<template v-for="item in extensionItems">
|
||||
<template v-if="!(item.activated)">
|
||||
<v-list-item
|
||||
class="menu-item unselectable"
|
||||
:key="item.title"
|
||||
:exact="item.exact"
|
||||
color="blue-grey lighten-3"
|
||||
@click="unselectable()"
|
||||
>
|
||||
<v-list-item-icon v-if="item.icon">
|
||||
<v-icon color="#D3D3D3">{{ item.icon }}</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{ item.text }}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</template>
|
||||
<template v-else-if="displayMenuItem(item)">
|
||||
<v-list-item
|
||||
v-if="!item.children"
|
||||
class="menu-item"
|
||||
:to="item.to"
|
||||
link
|
||||
:key="item.title"
|
||||
:exact="item.exact"
|
||||
>
|
||||
<v-list-item-icon v-if="item.icon">
|
||||
<v-icon>{{ item.icon }}</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{ item.text }}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<v-list-group v-else
|
||||
color="white"
|
||||
:key="item.text"
|
||||
:prepend-icon="item.icon"
|
||||
no-action>
|
||||
<template v-slot:activator>
|
||||
<v-list-item-title>{{ item.text }}</v-list-item-title>
|
||||
</template>
|
||||
|
||||
<template v-for="subitem in item.children">
|
||||
<v-list-item v-if="!subitem.children"
|
||||
:key="subitem.text"
|
||||
:to="subitem.to"
|
||||
link>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{ subitem.text }}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<v-list-group v-else
|
||||
:key="subitem.text"
|
||||
:value="true"
|
||||
no-action
|
||||
sub-group>
|
||||
<template v-slot:activator>
|
||||
<v-list-item-title>{{ subitem.text }}</v-list-item-title>
|
||||
</template>
|
||||
<v-list-item v-for="subsubitem in subitem.children"
|
||||
:key="subsubitem.text"
|
||||
:to="subsubitem.to"
|
||||
link>
|
||||
<v-list-item-title>{{ subsubitem.text }}</v-list-item-title>
|
||||
</v-list-item>
|
||||
</v-list-group>
|
||||
</template>
|
||||
</v-list-group>
|
||||
</template>
|
||||
</template>
|
||||
<settings-drawer
|
||||
:parametersList="parametersList"
|
||||
:extension="true"
|
||||
/>
|
||||
</v-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import { bus } from '@/main'
|
||||
import SettingsDrawer from './SettingsDrawer.vue'
|
||||
|
||||
export default {
|
||||
props: ['imap', 'parametersList'],
|
||||
components: {
|
||||
SettingsDrawer
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
authUser: 'auth/authUser'
|
||||
}),
|
||||
extensionItems () {
|
||||
return [
|
||||
{
|
||||
activated: this.imapMigration,
|
||||
icon: 'mdi-email-sync-outline',
|
||||
text: this.$gettext('IMAP Migration'),
|
||||
roles: ['SuperAdmins', 'Resellers'],
|
||||
children: [
|
||||
{
|
||||
text: this.$gettext('Email providers'),
|
||||
to: { name: 'ProvdiersList' },
|
||||
roles: ['SuperAdmins', 'Resellers']
|
||||
},
|
||||
{
|
||||
text: this.$gettext('Migrations'),
|
||||
to: { name: 'MigrationsList' },
|
||||
roles: ['Resellers', 'SuperAdmins']
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.imapMigration = this.imap
|
||||
bus.$on('imapSettingsChanged', this.imapMigrationStatus)
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
imapMigration: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
displayMenuItem (item) {
|
||||
return (item.roles === undefined || item.roles.indexOf(this.authUser.role) !== -1) && (item.condition === undefined || item.condition())
|
||||
},
|
||||
unselectable () {
|
||||
bus.$emit('notification', { msg: this.$gettext('Activate the extension in the settings'), type: 'warning' })
|
||||
},
|
||||
imapMigrationStatus (status) {
|
||||
this.imapMigration = status
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.v-list-item {
|
||||
&--active {
|
||||
&::before {
|
||||
opacity: 0;
|
||||
}
|
||||
background-color: #034bad;
|
||||
color: white;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.unselectable {
|
||||
color: lightgrey !important;
|
||||
}
|
||||
</style>
|
||||
@@ -21,33 +21,64 @@
|
||||
<v-icon>mdi-chevron-left</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
<v-layout
|
||||
justify-center>
|
||||
<v-chip v-if="page === 1" color="blue lighten-3" large>
|
||||
<translate>Core</translate>
|
||||
</v-chip>
|
||||
<v-chip v-else-if="page === 2" color="blue lighten-3" large>
|
||||
<translate>Extensions</translate>
|
||||
</v-chip>
|
||||
</v-layout>
|
||||
<base-nav-bar
|
||||
v-if="page === 1"
|
||||
:parametersList="parametersList"
|
||||
/>
|
||||
<extension-nav-bar
|
||||
v-else-if="page === 2"
|
||||
:imap="imapMigration"
|
||||
:parametersList="parametersList"
|
||||
/>
|
||||
|
||||
<v-list>
|
||||
<template v-for="item in menuItems">
|
||||
<template v-if="displayMenuItem(item)">
|
||||
<v-list-item
|
||||
v-if="!item.children"
|
||||
class="menu-item"
|
||||
:to="item.to"
|
||||
link
|
||||
:key="item.title"
|
||||
:exact="item.exact"
|
||||
>
|
||||
<v-list-item-icon v-if="item.icon">
|
||||
<v-icon>{{ item.icon }}</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{ item.text }}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<v-list-group v-else
|
||||
color="white"
|
||||
:key="item.text"
|
||||
:prepend-icon="item.icon"
|
||||
no-action>
|
||||
<template v-slot:activator>
|
||||
<v-list-item-title>{{ item.text }}</v-list-item-title>
|
||||
</template>
|
||||
|
||||
<template v-for="subitem in item.children">
|
||||
<v-list-item v-if="!subitem.children"
|
||||
:key="subitem.text"
|
||||
:to="subitem.to"
|
||||
link>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{ subitem.text }}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<v-list-group v-else
|
||||
:key="subitem.text"
|
||||
:value="true"
|
||||
no-action
|
||||
sub-group>
|
||||
<template v-slot:activator>
|
||||
<v-list-item-title>{{ subitem.text }}</v-list-item-title>
|
||||
</template>
|
||||
<v-list-item v-for="subsubitem in subitem.children"
|
||||
:key="subsubitem.text"
|
||||
:to="subsubitem.to"
|
||||
link>
|
||||
<v-list-item-title>{{ subsubitem.text }}</v-list-item-title>
|
||||
</v-list-item>
|
||||
</v-list-group>
|
||||
</template>
|
||||
</v-list-group>
|
||||
</template>
|
||||
</template>
|
||||
</v-list>
|
||||
<template v-slot:append>
|
||||
<v-pagination
|
||||
v-if="!mini"
|
||||
v-model="page"
|
||||
:length="2"
|
||||
circle
|
||||
color="blue lighten-3"
|
||||
>
|
||||
</v-pagination>
|
||||
<v-menu rounded="lg" offset-y top>
|
||||
<template v-slot:activator="{ attrs, on }">
|
||||
<div class="d-flex user-box justify-center align-center white--text py-2" v-bind="attrs" v-on="on">
|
||||
@@ -82,16 +113,11 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import BaseNavBar from './BaseNavBar.vue'
|
||||
import ExtensionNavBar from './ExtensionNavBar.vue'
|
||||
import parameters from '@/api/parameters'
|
||||
import { bus } from '@/main'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
BaseNavBar,
|
||||
ExtensionNavBar
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
authUser: 'auth/authUser'
|
||||
@@ -114,6 +140,12 @@ export default {
|
||||
? `${this.authUser.first_name} ${this.authUser.last_name}`
|
||||
: this.authUser.username
|
||||
},
|
||||
menuItems () {
|
||||
if (this.$route.meta.layout === 'user') {
|
||||
return this.userSettingsMenuItems
|
||||
}
|
||||
return this.mainMenuItems
|
||||
},
|
||||
mainColor () {
|
||||
if (this.$route.meta.layout === 'user') {
|
||||
return 'grey'
|
||||
@@ -121,20 +153,81 @@ export default {
|
||||
return 'primary'
|
||||
}
|
||||
},
|
||||
created () {
|
||||
parameters.getApplications().then(response => {
|
||||
this.parametersList = response.data
|
||||
})
|
||||
parameters.getApplication('imap_migration').then(response => {
|
||||
this.imapMigration = response.data.params.enabled_imapmigration
|
||||
})
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
parametersList: [],
|
||||
imapMigration: false,
|
||||
page: 1,
|
||||
drawer: true,
|
||||
mainMenuItems: [
|
||||
{
|
||||
text: this.$gettext('Dashboard'),
|
||||
to: { name: 'Dashboard' },
|
||||
icon: 'mdi-view-dashboard-outline',
|
||||
exact: true
|
||||
},
|
||||
{
|
||||
text: this.$gettext('Domains'),
|
||||
to: { name: 'DomainList' },
|
||||
icon: 'mdi-domain',
|
||||
roles: ['DomainAdmins', 'Resellers', 'SuperAdmins']
|
||||
},
|
||||
{
|
||||
text: this.$gettext('Identities'),
|
||||
to: { name: 'Identities' },
|
||||
icon: 'mdi-account',
|
||||
roles: ['DomainAdmins', 'Resellers', 'SuperAdmins']
|
||||
},
|
||||
{
|
||||
text: this.$gettext('Alarms'),
|
||||
to: { name: 'Alarms' },
|
||||
icon: 'mdi-bell'
|
||||
},
|
||||
{
|
||||
icon: 'mdi-history',
|
||||
text: this.$gettext('Logs'),
|
||||
roles: ['SuperAdmins', 'Resellers', 'DomainAdmins'],
|
||||
children: [
|
||||
{
|
||||
text: this.$gettext('Audit trail'),
|
||||
to: { name: 'AuditTrail' },
|
||||
roles: ['SuperAdmins']
|
||||
},
|
||||
{
|
||||
text: this.$gettext('Messages'),
|
||||
to: { name: 'MessageLog' },
|
||||
roles: ['DomainAdmins', 'Resellers', 'SuperAdmins']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
icon: 'mdi-email-sync-outline',
|
||||
text: this.$gettext('IMAP Migration'),
|
||||
roles: ['SuperAdmins', 'Resellers'],
|
||||
children: [
|
||||
{
|
||||
text: this.$gettext('Email providers'),
|
||||
to: { name: 'ProvdiersList' },
|
||||
roles: ['SuperAdmins', 'Resellers']
|
||||
},
|
||||
{
|
||||
text: this.$gettext('Migrations'),
|
||||
to: { name: 'MigrationsList' },
|
||||
roles: ['Resellers', 'SuperAdmins']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
icon: 'mdi-cog',
|
||||
text: this.$gettext('Settings'),
|
||||
children: [],
|
||||
roles: ['SuperAdmins']
|
||||
},
|
||||
{
|
||||
icon: 'mdi-information',
|
||||
text: this.$gettext('Information'),
|
||||
roles: ['SuperAdmins'],
|
||||
to: { name: 'Information' }
|
||||
}
|
||||
],
|
||||
userSettingsMenuItems: [
|
||||
{
|
||||
text: this.$gettext('API'),
|
||||
@@ -184,7 +277,29 @@ export default {
|
||||
]
|
||||
}
|
||||
},
|
||||
created () {
|
||||
parameters.getApplications().then(response => {
|
||||
response.data.forEach(item => {
|
||||
this.mainMenuItems[6].children.push({
|
||||
text: item.label,
|
||||
to: { name: 'ParametersEdit', params: { app: item.name } }
|
||||
})
|
||||
})
|
||||
})
|
||||
parameters.getApplication('imap_migration').then(response => {
|
||||
this.imapMigration = response.data.params.enabled_imapmigration
|
||||
})
|
||||
bus.$on('imapSettingsChanged', (status) => { this.imapMigration = status })
|
||||
},
|
||||
methods: {
|
||||
displayMenuItem (item) {
|
||||
const condition = (item.roles === undefined || item.roles.indexOf(this.authUser.role) !== -1) && (item.condition === undefined || item.condition()) && (item.activated !== false)
|
||||
if (item.icon === 'mdi-email-sync-outline') {
|
||||
// For imapMigration
|
||||
return condition && this.imapMigration
|
||||
}
|
||||
return condition
|
||||
},
|
||||
logout () {
|
||||
this.$store.dispatch('auth/logout').then(() => {
|
||||
this.$router.push({ name: 'Login' })
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
<template>
|
||||
<v-list-group
|
||||
color="white"
|
||||
:key="settings.text"
|
||||
:prepend-icon="settings.icon"
|
||||
no-action>
|
||||
<template v-slot:activator>
|
||||
<v-list-item-title>{{ settings.title }}</v-list-item-title>
|
||||
</template>
|
||||
|
||||
<template v-for="subitem in settings.children">
|
||||
<v-list-item v-if="!subitem.children"
|
||||
:key="subitem.text"
|
||||
:to="subitem.to"
|
||||
link>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{ subitem.text }}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<v-list-group v-else
|
||||
:key="subitem.text"
|
||||
:value="true"
|
||||
no-action
|
||||
sub-group>
|
||||
<template v-slot:activator>
|
||||
<v-list-item-title>{{ subitem.text }}</v-list-item-title>
|
||||
</template>
|
||||
<v-list-item v-for="subsubitem in subitem.children"
|
||||
:key="subsubitem.text"
|
||||
:to="subsubitem.to"
|
||||
link>
|
||||
<v-list-item-title>{{ subsubitem.text }}</v-list-item-title>
|
||||
</v-list-item>
|
||||
</v-list-group>
|
||||
</template>
|
||||
</v-list-group>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
props: ['parametersList', 'extension'],
|
||||
computed: {
|
||||
...mapGetters({
|
||||
authUser: 'auth/authUser'
|
||||
}),
|
||||
settings () {
|
||||
const menu = this.settingMenu
|
||||
this.parametersList.forEach(item => {
|
||||
if (item.is_extension === this.extension) {
|
||||
menu.children.push({
|
||||
text: item.label,
|
||||
to: { name: 'ParametersEdit', params: { app: item.name } }
|
||||
})
|
||||
}
|
||||
})
|
||||
return menu
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
settingMenu:
|
||||
{
|
||||
title: this.$gettext('Settings'),
|
||||
icon: 'mdi-cog',
|
||||
children: [],
|
||||
roles: ['SuperAdmins']
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.v-list-item {
|
||||
&--active {
|
||||
&::before {
|
||||
opacity: 0;
|
||||
}
|
||||
background-color: #034bad;
|
||||
color: white;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,9 @@
|
||||
"""APIv2 serializers."""
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from modoboa.admin.models.domain import Domain
|
||||
|
||||
|
||||
class IMAPMigrationSettingsSerializer(serializers.Serializer):
|
||||
@@ -28,3 +31,19 @@ class CheckProviderSerializer(serializers.Serializer):
|
||||
address = serializers.CharField()
|
||||
port = serializers.IntegerField(min_value=0, max_value=65535)
|
||||
secured = serializers.BooleanField()
|
||||
|
||||
|
||||
class CheckAssociatedDomainSerializer(serializers.Serializer):
|
||||
"""A serializer for checking associated domains."""
|
||||
|
||||
initialdomain = serializers.CharField()
|
||||
new_domain = serializers.CharField()
|
||||
|
||||
def validate(self, data):
|
||||
if data["initialdomain"] != data["new_domain"]:
|
||||
if not Domain.objects.filter(name=data["initialdomain"]):
|
||||
raise ValidationError({"new_domain": [
|
||||
_("You must create the local domain first.")]
|
||||
})
|
||||
return data
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ from rest_framework import serializers, response
|
||||
from rest_framework.decorators import action
|
||||
|
||||
from modoboa.imap_migration.api.v1 import viewsets as v1_viewsets
|
||||
from .serializers import CheckProviderSerializer
|
||||
from .serializers import CheckProviderSerializer, CheckAssociatedDomainSerializer
|
||||
|
||||
|
||||
class EmailProviderViewSet(v1_viewsets.EmailProviderViewSet):
|
||||
@@ -33,3 +33,12 @@ class EmailProviderViewSet(v1_viewsets.EmailProviderViewSet):
|
||||
print(error)
|
||||
return response.Response({'status': 'failed'}, 400)
|
||||
return response.Response(status=200)
|
||||
|
||||
@action(methods=["post"], detail=False)
|
||||
def check_associated_domain(self, request, **kwargs):
|
||||
"""check that the associated domain is either the same as the provider,
|
||||
or if a local domain already exists.
|
||||
This is to prevent errros on setup."""
|
||||
serializer = CheckAssociatedDomainSerializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
return response.Response(status=200)
|
||||
|
||||
Reference in New Issue
Block a user