| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- <!--
- Menu déroulant générique pour l'affichage des menus du
- header principal (configuration, paramètres du compte...)
- -->
- <template>
- <div v-if="displayMenu">
- <v-btn ref="btn" icon size="small" class="ml-2">
- <v-avatar
- v-if="menu.icon.avatarId || menu.icon.avatarByDefault"
- size="30"
- >
- <UiImage
- :image-id="menu.icon.avatarId"
- :size="IMAGE_SIZE.SM"
- :default-image="menu.icon.avatarByDefault"
- :width="30"
- />
- </v-avatar>
- <v-icon v-else :icon="menu.icon.name" class="on-primary" />
- </v-btn>
- <v-tooltip :activator="btn" :text="$t(menu.label)" location="bottom" />
- <v-menu
- :activator="btn"
- :model-value="isOpened()"
- @update:model-value="onStateUpdated"
- >
- <v-card>
- <v-card-title class="theme-neutral text-body-2 font-weight-bold">
- {{ $t(menu.label) }}
- </v-card-title>
- <v-card-text class="ma-0 pa-0 header-menu">
- <v-list density="compact" :subheader="true">
- <template v-for="(child, index) in menu.children" :key="index">
- <v-list-item
- :id="child.label"
- :href="!isInternalLink(child) ? child.to : undefined"
- :to="isInternalLink(child) ? child.to : undefined"
- :class="{
- 'end-of-section':
- 'endOfSubsection' in child && child.endOfSubsection,
- }"
- >
- <span v-if="child.icon" class="pr-2 d-flex align-center">
- <v-avatar
- v-if="menu.icon.avatarId || child.icon.avatarByDefault"
- size="30"
- >
- <UiImage
- :image-id="child.icon.avatarId"
- :default-image="child.icon.avatarByDefault"
- :width="30"
- />
- </v-avatar>
- <v-icon v-else class="on-primary" size="small">
- {{ child.icon.name }}
- </v-icon>
- </span>
- <span>{{
- translateLabel ? $t(child.label) : child.label
- }}</span>
- </v-list-item>
- </template>
- </v-list>
- </v-card-text>
- <v-card-actions
- v-if="menu.actions.length > 0"
- class="ma-0 pa-0 theme-primary"
- >
- <template v-for="(action, index) in menu.actions" :key="index">
- <v-list-item
- :id="action.label"
- :href="!isInternalLink(action) ? action.to : undefined"
- :to="isInternalLink(action) ? action.to : undefined"
- >
- <v-list-item-title class="text-body-2">
- {{ $t(action.label) }}
- </v-list-item-title>
- </v-list-item>
- </template>
- </v-card-actions>
- </v-card>
- </v-menu>
- </div>
- </template>
- <script setup lang="ts">
- import { computed, ref } from 'vue'
- import { useMenu } from '~/composables/layout/useMenu'
- import { IMAGE_SIZE } from '~/types/enum/enums'
- const props = defineProps({
- name: {
- type: String,
- required: true,
- },
- translateLabel: {
- type: Boolean,
- required: false,
- default: true,
- },
- })
- const { getMenu, isInternalLink, hasMenu, setMenuState, isMenuOpened } =
- useMenu()
- const menu = getMenu(props.name)
- const displayMenu = computed(() => hasMenu(props.name))
- const isOpened = () => isMenuOpened(props.name)
- const onStateUpdated = (e: boolean) => {
- setMenuState(props.name, e)
- }
- const btn = ref(null)
- </script>
- <style scoped lang="scss">
- :deep(.v-btn .v-icon) {
- font-size: 1rem !important;
- }
- .v-list {
- padding: 0;
- }
- .v-list-item {
- width: 100%;
- }
- .header-menu .v-list .v-list-item:last-child {
- border-bottom: none;
- }
- </style>
|