Menu.vue 3.4 KB

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