CreateButton.vue 4.6 KB

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