CreateButton.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. <!--
  2. Bouton Créer du header de l'application et boite de dialogue associée
  3. -->
  4. <template>
  5. <main>
  6. <v-btn
  7. v-if="asIcon"
  8. :elevation="0"
  9. class="theme-primary"
  10. :icon="true"
  11. size="small"
  12. @click="show"
  13. >
  14. <v-icon>fas fa-plus</v-icon>
  15. </v-btn>
  16. <v-btn
  17. v-else
  18. :elevation="2"
  19. height="30"
  20. class="theme-x-create-btn"
  21. @click="show"
  22. >
  23. <span>{{ $t('create') }}</span>
  24. </v-btn>
  25. <LayoutDialog :show="showCreateDialog" :max-width="850" >
  26. <template #dialogType>{{ $t('creative_assistant') }}</template>
  27. <template #dialogTitle>
  28. <span v-if="location === 'home'">{{ $t('what_do_you_want_to_create') }}</span>
  29. <span v-else-if="location === 'access'">{{ $t('what_type_of_contact_do_you_want_to_create') }}</span>
  30. <span v-else-if="location === 'event'">{{ $t('what_do_you_want_to_add_to_your_planning') }}</span>
  31. <span v-else-if="location === 'message'">{{ $t('what_do_you_want_to_send') }}</span>
  32. <span v-else-if="location === 'event-params'">{{ $t('which_date_and_which_hour') }}</span>
  33. </template>
  34. <template #dialogText>
  35. <LayoutHeaderUniversalCreationGenerateCardsSteps
  36. :path="path"
  37. @cardClick="onCardClick"
  38. @urlUpdate="onUrlUpdate"
  39. />
  40. </template>
  41. <template #dialogBtn>
  42. <div class="text-center">
  43. <v-btn class="theme-neutral-soft" @click="close" >
  44. {{ $t('cancel') }}
  45. </v-btn>
  46. <v-btn v-if="path.length > 1" class="theme-neutral-soft" @click="goToPrevious" >
  47. {{ $t('previous_step') }}
  48. </v-btn>
  49. <v-btn v-if="targetUrl !== null && !directRedirectionOngoing" class="theme-primary" @click="validate" >
  50. {{ $t('validate') }}
  51. </v-btn>
  52. </div>
  53. </template>
  54. </LayoutDialog>
  55. </main>
  56. </template>
  57. <script setup lang="ts">
  58. import {ref} from "@vue/reactivity";
  59. import type {Ref} from "@vue/reactivity";
  60. import {useDisplay} from "vuetify";
  61. import type {ComputedRef} from "vue";
  62. import {usePageStore} from "~/stores/page";
  63. const { mdAndDown: asIcon } = useDisplay()
  64. // Set to true to show the Create dialog
  65. const showCreateDialog: Ref<boolean> = ref(false);
  66. // The succession of menus the user has been through; used to keep track of the navigation
  67. const path: Ref<Array<string>> = ref(['home'])
  68. // The current menu
  69. const location: ComputedRef<string> = computed(() => {
  70. return path.value.at(-1) ?? 'home'
  71. })
  72. // The current target URL (@see onUrlUpdate())
  73. const targetUrl: Ref<string | null> = ref(null)
  74. // Already redirecting (to avoid the display of the 'validate' button when page has already been redirected and is loading)
  75. const directRedirectionOngoing: Ref<boolean> = ref(false)
  76. /**
  77. * Return to the home menu
  78. */
  79. const reset = () => {
  80. path.value = ['home']
  81. }
  82. /**
  83. * Go back to the previous step
  84. */
  85. const goToPrevious = () => {
  86. if (path.value.length === 1) {
  87. return
  88. }
  89. path.value.pop()
  90. }
  91. /**
  92. * Display the create dialog
  93. */
  94. const show = () => {
  95. reset()
  96. showCreateDialog.value = true
  97. }
  98. const pageStore = usePageStore()
  99. /**
  100. * Redirect the user to the given url
  101. * @param url
  102. */
  103. const redirect = (url: string) => {
  104. pageStore.loading = true
  105. window.location.href = url
  106. }
  107. /**
  108. * Go to the current targetUrl
  109. */
  110. const validate = () => {
  111. if (targetUrl.value === null) {
  112. console.warn('No url defined')
  113. return
  114. }
  115. redirect(targetUrl.value)
  116. }
  117. /**
  118. * Close the Create dialog
  119. */
  120. const close = () => {
  121. showCreateDialog.value = false
  122. }
  123. /**
  124. * A cart has been clicked. The reaction depends on the card's properties.
  125. *
  126. * @param to Target location in the wizard
  127. * @param href Target absolute url
  128. */
  129. const onCardClick = (to: string | null, href: string | null) => {
  130. if (to !== null) {
  131. // La carte définit une nouvelle destination : on se dirige vers elle.
  132. path.value.push(to)
  133. } else if (href !== null) {
  134. // La carte définit une url avec href, et pas de nouvelle destination : on suit directement le lien pour éviter
  135. // l'étape de validation devenue inutile.
  136. directRedirectionOngoing.value = true
  137. redirect(href)
  138. } else {
  139. console.warn('Error: card has no `to` nor `href` defined')
  140. }
  141. }
  142. /**
  143. * The url has been updated in the GenerateCardsStep component
  144. * @param url
  145. */
  146. const onUrlUpdate = (url: string) => {
  147. targetUrl.value = url
  148. }
  149. </script>
  150. <style scoped lang="scss">
  151. :deep(.v-btn .v-icon) {
  152. font-size: 16px !important;
  153. }
  154. :deep(.v-btn) {
  155. text-transform: none !important;
  156. font-weight: 600;
  157. }
  158. </style>