mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
WIP: frontend module federation setup.
Initial work to accept future user related apps.
This commit is contained in:
@@ -114,4 +114,7 @@ export default {
|
||||
`${resource}/filtersets/${filterSetName}/filters/${filter}/`
|
||||
)
|
||||
},
|
||||
getAvailableApplications() {
|
||||
return repository.get(`${resource}/available_applications/`)
|
||||
},
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<v-btn icon="mdi-apps" flat> </v-btn>
|
||||
</template>
|
||||
@@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<div class="top-menu">
|
||||
<v-menu activator="parent" location="bottom">
|
||||
<template #activator="{ props }">
|
||||
<v-btn icon="mdi-apps" flat class="mr-4" v-bind="props"></v-btn>
|
||||
</template>
|
||||
<v-card min-width="350" max-width="400" class="pa-4">
|
||||
<v-row class="justify-center">
|
||||
<v-col
|
||||
v-for="application in applications"
|
||||
:key="application.name"
|
||||
cols="6"
|
||||
>
|
||||
<v-sheet
|
||||
rounded
|
||||
class="application text-center pa-4 text-body-2"
|
||||
@click="$router.push(application.url)"
|
||||
>
|
||||
<v-icon color="primary" :icon="application.icon" size="x-large" />
|
||||
<div class="mt-2">{{ application.label }}</div>
|
||||
</v-sheet>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card>
|
||||
</v-menu>
|
||||
|
||||
<v-btn icon flat color="primary">
|
||||
{{ userInitials }}
|
||||
<v-menu activator="parent" location="bottom">
|
||||
<v-card min-width="300" max-width="350">
|
||||
<v-list>
|
||||
<div class="text-center">
|
||||
<v-avatar color="primary">
|
||||
<span class="text-h5">{{ userInitials }}</span>
|
||||
</v-avatar>
|
||||
<v-list-item :title="user.username" />
|
||||
</div>
|
||||
<v-divider></v-divider>
|
||||
<template v-if="remote">
|
||||
<v-list-item href="https://localhost:3000/account">
|
||||
<template #prepend>
|
||||
<v-icon icon="mdi-account-circle-outline"></v-icon>
|
||||
</template>
|
||||
<v-list-item-title>Account</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-list-item @click="logout">
|
||||
<template #prepend>
|
||||
<v-icon icon="mdi-logout"></v-icon>
|
||||
</template>
|
||||
<v-list-item-title>Logout</v-list-item-title>
|
||||
</v-list-item>
|
||||
</template>
|
||||
</v-list>
|
||||
</v-card>
|
||||
</v-menu>
|
||||
</v-btn>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { getActivePinia } from 'pinia'
|
||||
import accountApi from '@/api/account'
|
||||
|
||||
const props = defineProps({
|
||||
user: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
remote: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
|
||||
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()
|
||||
})
|
||||
|
||||
async function logout() {
|
||||
getActivePinia()._s.forEach(async (store) => await store.$reset())
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
accountApi.getAvailableApplications().then((resp) => {
|
||||
applications.value = resp.data
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.top-menu {
|
||||
position: fixed;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
.application {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.application:hover {
|
||||
background-color: rgb(var(--v-theme-surface));
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<v-fab app icon flat location="top right" color="primary">
|
||||
<v-btn icon flat color="primary">
|
||||
{{ userInitials }}
|
||||
<v-menu activator="parent" location="bottom">
|
||||
<v-card min-width="300" max-width="350">
|
||||
@@ -28,7 +28,7 @@
|
||||
</v-list>
|
||||
</v-card>
|
||||
</v-menu>
|
||||
</v-fab>
|
||||
</v-btn>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
src="@/assets/Modoboa_RVB-BLANC-SANS.png"
|
||||
max-width="190"
|
||||
class="logo"
|
||||
@click="router.push({ name: 'Dashboard' })"
|
||||
@click="router.push(props.logoRoute)"
|
||||
/>
|
||||
<v-btn
|
||||
:icon="rail ? 'mdi-chevron-right' : 'mdi-chevron-left'"
|
||||
@@ -24,8 +24,20 @@
|
||||
<v-list nav>
|
||||
<template v-for="item in menuItems" :key="item.text">
|
||||
<template v-if="displayMenuItem(item)">
|
||||
<v-list-subheader v-if="item.subheader">
|
||||
{{ item.text.toUpperCase() }}
|
||||
</v-list-subheader>
|
||||
<v-list-item
|
||||
v-if="!item.children"
|
||||
v-else-if="item.action"
|
||||
:value="item"
|
||||
:exact="item.exact"
|
||||
:title="item.text"
|
||||
:prepend-icon="item.icon"
|
||||
@click="item.action"
|
||||
>
|
||||
</v-list-item>
|
||||
<v-list-item
|
||||
v-else-if="!item.children"
|
||||
:value="item"
|
||||
:to="item.to"
|
||||
link
|
||||
@@ -124,6 +136,10 @@ const props = defineProps({
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
logoRoute: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
})
|
||||
|
||||
const globalStore = useGlobalStore()
|
||||
@@ -358,6 +374,12 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
.v-list-subheader {
|
||||
&__text {
|
||||
color: white !important;
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -37,10 +37,13 @@ export default defineConfig({
|
||||
name: 'coretools',
|
||||
filename: 'remoteEntry.js',
|
||||
exposes: {
|
||||
'./api-repository': './src/api/repository.js',
|
||||
'./auth-store': './src/stores/auth.store.js',
|
||||
'./auth-callback': './src/views/login/LoginCallbackView.vue',
|
||||
'./navbar': './src/layouts/dashboard/NavBar.vue',
|
||||
'./user-menu': './src/components/shared/UserMenu.vue',
|
||||
'./top-menu': './src/components/shared/TopMenu.vue',
|
||||
'./menu-items': './src/components/tools/MenuItems.vue',
|
||||
'./form-rules': './src/plugins/rules.js',
|
||||
},
|
||||
shared: ['vue', 'pinia', 'vue-router', 'vue3-gettext'],
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user