Menu.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. <!--
  2. Menu déroulant générique pour l'affichage des menus du
  3. header principal (configuration, paramètres du compte...)
  4. -->
  5. <template>
  6. <div v-if="displayMenu">
  7. <v-btn
  8. ref="btn"
  9. icon
  10. width="48px"
  11. size="small"
  12. >
  13. <v-avatar v-if="menu.icon.avatarId || menu.icon.avatarByDefault" size="30">
  14. <UiImage :id="menu.icon.avatarId" :defaultImage="menu.icon.avatarByDefault" :width="30"></UiImage>
  15. </v-avatar>
  16. <v-icon v-else class="text-ot-white">
  17. {{ menu.icon.name }}
  18. </v-icon>
  19. </v-btn>
  20. <v-tooltip :activator="btn" :text="$t(menu.label)" location="bottom" />
  21. <v-menu
  22. :activator="btn"
  23. :model-value="isOpened()"
  24. @update:modelValue="onStateUpdated"
  25. >
  26. <v-card>
  27. <v-card-title class="ot-header-menu text-body-2 font-weight-bold">
  28. {{$t(menu.label)}}
  29. </v-card-title>
  30. <v-card-text class="ma-0 pa-0 header-menu">
  31. <v-list density="compact" :subheader="true">
  32. <template v-for="(child, index) in menu.children" :key="index">
  33. <v-list-item
  34. :id="child.label"
  35. :href="!isInternalLink(child) ? child.to : undefined"
  36. :to="isInternalLink(child) ? child.to : undefined"
  37. >
  38. <v-list-item-title>
  39. <span v-if="child.icon">
  40. <v-avatar v-if="menu.icon.avatarId || child.icon.avatarByDefault" size="30">
  41. <UiImage :id="child.icon.avatarId" :defaultImage="child.icon.avatarByDefault" :width="30"></UiImage>
  42. </v-avatar>
  43. <v-icon v-else class="text-ot-white" size="small">
  44. {{ child.icon.name }}
  45. </v-icon>
  46. </span>
  47. <span>{{$t(child.label)}}</span>
  48. </v-list-item-title>
  49. </v-list-item>
  50. </template>
  51. </v-list>
  52. </v-card-text>
  53. <v-card-actions v-if="menu.actions.length > 0" class="ma-0 pa-0 actions">
  54. <template v-for="(action, index) in menu.actions" :key="index">
  55. <v-list-item
  56. :id="action.label"
  57. :href="!isInternalLink(action) ? action.to : undefined"
  58. :to="isInternalLink(action) ? action.to : undefined"
  59. >
  60. <v-list-item-title class="text-body-2" v-text="$t(action.label)"/>
  61. </v-list-item>
  62. </template>
  63. </v-card-actions>
  64. </v-card>
  65. </v-menu>
  66. </div>
  67. </template>
  68. <script setup lang="ts">
  69. import {useMenu} from "~/composables/layout/useMenu";
  70. import {computed, ref} from "@vue/reactivity";
  71. const props = defineProps({
  72. name: {
  73. type: String,
  74. required: true
  75. }
  76. })
  77. const { buildMenu, isInternalLink, hasMenu, setMenuState, isMenuOpened } = useMenu()
  78. const menu = buildMenu(props.name)
  79. const displayMenu = computed(() => hasMenu(props.name))
  80. const isOpened = () => isMenuOpened(props.name)
  81. const onStateUpdated = (e: any) => {
  82. setMenuState(props.name, e)
  83. }
  84. const btn = ref(null)
  85. </script>
  86. <style scoped lang="scss">
  87. .actions {
  88. background: rgb(var(--v-theme-ot-green));
  89. color: white;
  90. }
  91. </style>