mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
Fixed various frontend issues
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<router-view />
|
||||
<Suspense>
|
||||
<router-view />
|
||||
</Suspense>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
</script>
|
||||
<script setup></script>
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer />
|
||||
<v-btn @click="close">{{ $gettext('Close') }}</v-btn>
|
||||
<v-btn color="primary" type="submit">
|
||||
<v-btn :loading="working" @click="close">{{ $gettext('Close') }}</v-btn>
|
||||
<v-btn color="primary" type="submit" :loading="working">
|
||||
{{ submitLabel }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
@@ -64,14 +64,17 @@ const { $gettext } = useGettext()
|
||||
const busStore = useBusStore()
|
||||
|
||||
onMounted(() => {
|
||||
calendar.value = { ...props.initialCalendar }
|
||||
shared.value = props.initialCalendar.domain !== undefined
|
||||
if (props.initialCalendar) {
|
||||
calendar.value = { ...props.initialCalendar }
|
||||
shared.value = props.initialCalendar.domain !== undefined
|
||||
}
|
||||
})
|
||||
|
||||
const calendar = ref({})
|
||||
const shared = ref(false)
|
||||
const formErrors = ref({})
|
||||
const formRef = ref()
|
||||
const working = ref(false)
|
||||
|
||||
const submitLabel = computed(() => {
|
||||
if (calendar.value.pk) {
|
||||
@@ -93,19 +96,27 @@ async function submit() {
|
||||
return
|
||||
}
|
||||
let msg
|
||||
if (calendar.value.pk) {
|
||||
await calendarsApi.updateUserCalendar(calendar.value.pk, calendar.value)
|
||||
msg = $gettext('Calendar updated')
|
||||
} else {
|
||||
await calendarsApi.createUserCalendar(calendar.value)
|
||||
msg = $gettext('Calendar created')
|
||||
working.value = true
|
||||
try {
|
||||
if (calendar.value.pk) {
|
||||
await calendarsApi.updateUserCalendar(calendar.value.pk, calendar.value)
|
||||
msg = $gettext('Calendar updated')
|
||||
} else {
|
||||
await calendarsApi.createUserCalendar(calendar.value)
|
||||
msg = $gettext('Calendar created')
|
||||
}
|
||||
if (
|
||||
props.initialCalendar &&
|
||||
props.initialCalendar.color !== calendar.value.color
|
||||
) {
|
||||
emit('colorChanged', calendar.value)
|
||||
}
|
||||
close()
|
||||
busStore.displayNotification({
|
||||
msg,
|
||||
})
|
||||
} finally {
|
||||
working.value = false
|
||||
}
|
||||
if (props.initialCalendar.color !== calendar.value.color) {
|
||||
emit('colorChanged', calendar.value)
|
||||
}
|
||||
close()
|
||||
busStore.displayNotification({
|
||||
msg,
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -82,8 +82,8 @@
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer />
|
||||
<v-btn @click="close">{{ $gettext('Close') }}</v-btn>
|
||||
<v-btn color="primary" type="submit">
|
||||
<v-btn :loading="working" @click="close">{{ $gettext('Close') }}</v-btn>
|
||||
<v-btn color="primary" type="submit" :loading="working">
|
||||
{{ $gettext('Save') }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
@@ -119,6 +119,7 @@ const userCalendars = ref([])
|
||||
const form = ref({})
|
||||
const formErrors = ref({})
|
||||
const formRef = ref()
|
||||
const working = ref(false)
|
||||
|
||||
const title = computed(() => {
|
||||
return props.event ? $gettext('Edit event') : $gettext('New event')
|
||||
@@ -148,7 +149,6 @@ watch(
|
||||
'yyyy-MM-dd HH:mm'
|
||||
)
|
||||
form.value.end = DateTime.fromISO(value.end).toFormat('yyyy-MM-dd HH:mm')
|
||||
console.log(form.value)
|
||||
api.getAttendees().then((resp) => {
|
||||
attendees.value = resp.data
|
||||
})
|
||||
@@ -166,17 +166,22 @@ async function saveEvent() {
|
||||
if (!valid) {
|
||||
return
|
||||
}
|
||||
var data = JSON.parse(JSON.stringify(form.value))
|
||||
if (!props.event) {
|
||||
api.createUserEvent(form.value.calendar, data).then(() => {
|
||||
busStore.displayNotification({ msg: $gettext('Event added') })
|
||||
close()
|
||||
})
|
||||
} else {
|
||||
api.patchUserEvent(form.value.calendar, props.event.id, data).then(() => {
|
||||
busStore.displayNotification({ msg: $gettext('Event updated') })
|
||||
close()
|
||||
})
|
||||
working.value = true
|
||||
try {
|
||||
var data = JSON.parse(JSON.stringify(form.value))
|
||||
if (!props.event) {
|
||||
api.createUserEvent(form.value.calendar, data).then(() => {
|
||||
busStore.displayNotification({ msg: $gettext('Event added') })
|
||||
close()
|
||||
})
|
||||
} else {
|
||||
api.patchUserEvent(form.value.calendar, props.event.id, data).then(() => {
|
||||
busStore.displayNotification({ msg: $gettext('Event updated') })
|
||||
close()
|
||||
})
|
||||
}
|
||||
} finally {
|
||||
working.value = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -78,9 +78,13 @@ const { $gettext } = useGettext()
|
||||
const applications = ref([])
|
||||
|
||||
const userInitials = computed(() => {
|
||||
return props.user.first_name && props.user.last_name
|
||||
? `${props.user.first_name[0].toUpperCase()}${props.user.last_name[0].toUpperCase()}`
|
||||
: props.user.username.slice(0, 2).toUpperCase()
|
||||
if (props.user.first_name && props.user.last_name) {
|
||||
return `${props.user.first_name[0].toUpperCase()}${props.user.last_name[0].toUpperCase()}`
|
||||
}
|
||||
if (props.user.username) {
|
||||
props.user.username.slice(0, 2).toUpperCase()
|
||||
}
|
||||
return ''
|
||||
})
|
||||
|
||||
const userMenuItems = computed(() => {
|
||||
|
||||
@@ -5,14 +5,12 @@
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useGettext } from 'vue3-gettext'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useAuthStore, useParametersStore } from '@/stores'
|
||||
import parametersApi from '@/api/parameters'
|
||||
import capabilitiesApi from '@/api/capabilities'
|
||||
import ConnectedLayout from '@/layouts/connected/ConnectedLayout.vue'
|
||||
|
||||
const { $gettext } = useGettext()
|
||||
const router = useRouter()
|
||||
const authStore = useAuthStore()
|
||||
const parametersStore = useParametersStore()
|
||||
|
||||
|
||||
@@ -149,11 +149,10 @@ function openMailbox(mailbox) {
|
||||
})
|
||||
}
|
||||
|
||||
const fetchUserMailboxes = () => {
|
||||
api.getUserMailboxes().then((resp) => {
|
||||
userMailboxes.value = resp.data.mailboxes
|
||||
hdelimiter.value = resp.data.hdelimiter
|
||||
})
|
||||
const fetchUserMailboxes = async () => {
|
||||
const resp = await api.getUserMailboxes()
|
||||
userMailboxes.value = resp.data.mailboxes
|
||||
hdelimiter.value = resp.data.hdelimiter
|
||||
}
|
||||
|
||||
const openComposeForm = () => {
|
||||
@@ -213,8 +212,7 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
fetchUserMailboxes()
|
||||
api.getUserMailboxQuota(route.query.mailbox || 'INBOX').then((resp) => {
|
||||
mailboxQuota.value = resp.data
|
||||
})
|
||||
await fetchUserMailboxes()
|
||||
const resp = await api.getUserMailboxQuota(route.query.mailbox || 'INBOX')
|
||||
mailboxQuota.value = resp.data
|
||||
</script>
|
||||
|
||||
@@ -25,6 +25,9 @@ const routes = [
|
||||
{
|
||||
path: '/admin',
|
||||
component: () => import('@/layouts/admin/AdminLayout.vue'),
|
||||
meta: {
|
||||
allowedRoles: ['DomainAdmins', 'Resellers', 'SuperAdmins'],
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
@@ -287,6 +290,7 @@ const routes = [
|
||||
component: () => import('@/layouts/user/UserLayout.vue'),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
requiresMailbox: true,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@@ -304,6 +308,7 @@ const routes = [
|
||||
component: () => import('@/layouts/user/UserLayout.vue'),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
requiresMailbox: true,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@@ -312,6 +317,7 @@ const routes = [
|
||||
component: () => import('@/views/calendars/CalendarView.vue'),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
requiresMailbox: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -321,6 +327,7 @@ const routes = [
|
||||
component: () => import('@/layouts/webmail/WebmailLayout.vue'),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
requiresMailbox: true,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@@ -329,6 +336,7 @@ const routes = [
|
||||
component: () => import('@/views/webmail/MailboxView.vue'),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
requiresMailbox: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -337,6 +345,7 @@ const routes = [
|
||||
component: () => import('@/views/webmail/EmailView.vue'),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
requiresMailbox: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -345,6 +354,7 @@ const routes = [
|
||||
component: () => import('@/views/webmail/ComposeEmailView.vue'),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
requiresMailbox: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -353,6 +363,7 @@ const routes = [
|
||||
component: () => import('@/views/webmail/ReplyEmailView.vue'),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
requiresMailbox: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -361,6 +372,7 @@ const routes = [
|
||||
component: () => import('@/views/webmail/ForwardEmailView.vue'),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
requiresMailbox: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -391,7 +403,7 @@ router.beforeEach(async (to, from, next) => {
|
||||
if (isAuth) {
|
||||
if (to.meta.allowedRoles !== undefined) {
|
||||
if (to.meta.allowedRoles.indexOf(authStore.authUser.role) === -1) {
|
||||
next({ name: 'Dashboard' })
|
||||
next({ name: 'AccountSettings' })
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import domainApi from '@/api/domains'
|
||||
|
||||
export const useDomainsStore = defineStore('domains', () => {
|
||||
const domainsLoaded = ref(false)
|
||||
const domains = ref({})
|
||||
const domains = ref([])
|
||||
|
||||
async function $reset() {
|
||||
domainsLoaded.value = false
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, ref } from 'vue'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { useGettext } from 'vue3-gettext'
|
||||
import { useRoute } from 'vue-router'
|
||||
import ParametersForm from '@/components/tools/ParametersForm'
|
||||
@@ -39,6 +39,10 @@ function loadParams(app) {
|
||||
})
|
||||
}
|
||||
|
||||
watch(route, (toRoute) => {
|
||||
loadParams(toRoute.params.app)
|
||||
})
|
||||
|
||||
loadParams(route.params.app)
|
||||
</script>
|
||||
|
||||
|
||||
@@ -11,12 +11,15 @@ import DomainEditForm from '@/components/admin/domains/DomainEditForm'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { ref } from 'vue'
|
||||
import domainsApi from '@/api/domains'
|
||||
import { useDomainsStore } from '@/stores'
|
||||
|
||||
const { $gettext } = useGettext()
|
||||
const route = useRoute()
|
||||
const domainsStore = useDomainsStore()
|
||||
|
||||
const domain = ref({})
|
||||
|
||||
domainsStore.getDomains()
|
||||
domainsApi.getDomain(route.params.id).then((resp) => {
|
||||
domain.value = resp.data
|
||||
})
|
||||
|
||||
@@ -252,8 +252,9 @@ async function deleteCalendar(calendarPk) {
|
||||
}
|
||||
await api.deleteUserCalendar(calendarPk)
|
||||
const fullc = calendarRef.value.getApi()
|
||||
const evtSource = fullc.getEventSourceById(`user-${calendar.pk}`)
|
||||
const evtSource = fullc.getEventSourceById(`user-${calendarPk}`)
|
||||
evtSource.remove()
|
||||
fetchUserCalendars()
|
||||
busStore.displayNotification({ msg: $gettext('Calendar deleted') })
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ def cleanup_and_rename(apps, schema_editor):
|
||||
# Rename parameters
|
||||
LocalConfig = apps.get_model("core", "LocalConfig")
|
||||
cfg = LocalConfig.objects.first()
|
||||
if not cfg:
|
||||
if not cfg or "postfix_autoreply" not in cfg._parameters:
|
||||
return
|
||||
cfg._parameters["autoreply"] = copy.deepcopy(cfg._parameters["postfix_autoreply"])
|
||||
del cfg._parameters["postfix_autoreply"]
|
||||
|
||||
Reference in New Issue
Block a user