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, ref} from "@vue/reactivity";
  59. import {useDisplay} from "vuetify";
  60. import {ComputedRef} from "vue";
  61. import {usePageStore} from "~/stores/page";
  62. const { mdAndDown: asIcon } = useDisplay()
  63. // Set to true to show the Create dialog
  64. const showCreateDialog: Ref<boolean> = ref(false);
  65. // The succession of menus the user has been through; used to keep track of the navigation
  66. const path: Ref<Array<string>> = ref(['home'])
  67. // The current menu
  68. const location: ComputedRef<string> = computed(() => {
  69. return path.value.at(-1) ?? 'home'
  70. })
  71. // The current target URL (@see onUrlUpdate())
  72. const targetUrl: Ref<string | null> = ref(null)
  73. // Already redirecting (to avoid the display of the 'validate' button when page has already been redirected and is loading)
  74. const directRedirectionOngoing: Ref<boolean> = ref(false)
  75. /**
  76. * Return to the home menu
  77. */
  78. const reset = () => {
  79. path.value = ['home']
  80. }
  81. /**
  82. * Go back to the previous step
  83. */
  84. const goToPrevious = () => {
  85. if (path.value.length === 1) {
  86. return
  87. }
  88. path.value.pop()
  89. }
  90. /**
  91. * Display the create dialog
  92. */
  93. const show = () => {
  94. reset()
  95. showCreateDialog.value = true
  96. }
  97. const pageStore = usePageStore()
  98. /**
  99. * Redirect the user to the given url
  100. * @param url
  101. */
  102. const redirect = (url: string) => {
  103. pageStore.loading = true
  104. window.location.href = url
  105. }
  106. /**
  107. * Go to the current targetUrl
  108. */
  109. const validate = () => {
  110. if (targetUrl.value === null) {
  111. console.warn('No url defined')
  112. return
  113. }
  114. redirect(targetUrl.value)
  115. }
  116. /**
  117. * Close the Create dialog
  118. */
  119. const close = () => {
  120. showCreateDialog.value = false
  121. }
  122. /**
  123. * A cart has been clicked. The reaction depends on the card's properties.
  124. *
  125. * @param to Target location in the wizard
  126. * @param href Target absolute url
  127. */
  128. const onCardClick = (to: string | null, href: string | null) => {
  129. console.log(to, href)
  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>