@bildvitta/quasar-ui-asteroid 3.17.0-beta.25 → 3.17.0-beta.26-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bildvitta/quasar-ui-asteroid",
3
3
  "description": "Asteroid",
4
- "version": "3.17.0-beta.25",
4
+ "version": "3.17.0-beta.26-alpha.0",
5
5
  "author": "Bild & Vitta <systemteam@bild.com.br>",
6
6
  "license": "MIT",
7
7
  "main": "dist/asteroid.cjs.min.js",
@@ -50,6 +50,7 @@
50
50
  "date-fns": "^2.30.0",
51
51
  "debug": "^4.3.4",
52
52
  "fuse.js": "^6.6.2",
53
+ "gleap": "^14.2.5",
53
54
  "humps": "^2.0.1",
54
55
  "lodash-es": "^4.17.21",
55
56
  "pica": "^9.0.1",
@@ -79,8 +79,8 @@
79
79
 
80
80
  <div v-if="showAppUser">
81
81
  <!-- Chat Ajuda -->
82
- <q-list v-if="helpChatLink" class="q-mt-xl">
83
- <q-item class="q-mb-md text-primary" clickable>
82
+ <q-list v-if="useChat" class="q-mt-xl">
83
+ <q-item class="q-mb-md text-primary" clickable @click="toggleChat">
84
84
  <q-item-section avatar>
85
85
  <q-icon name="sym_r_chat" />
86
86
  </q-item-section>
@@ -92,8 +92,6 @@
92
92
  </div>
93
93
  </q-item-label>
94
94
  </q-item-section>
95
-
96
- <pv-app-menu-help-chat :link="props.helpChatLink" :mini-brand="props.miniBrand" @update:model-value="setHasOpenedHelpChat" />
97
95
  </q-item>
98
96
  </q-list>
99
97
 
@@ -108,7 +106,6 @@
108
106
  </template>
109
107
 
110
108
  <script setup>
111
- import PvAppMenuHelpChat from './private/PvAppMenuHelpChat.vue'
112
109
  import PvAppMenuDropdown from './private/PvAppMenuDropdown.vue'
113
110
  import QasAppUser from '../app-user/QasAppUser.vue'
114
111
 
@@ -116,8 +113,12 @@ import useAppMenuDropdown from './composables/use-app-menu-dropdown'
116
113
  import useAppUser from './composables/use-app-user'
117
114
  import useDevelopmentBadge from './composables/use-development-badge'
118
115
  import { useScreen } from '../../composables'
116
+ import useAuthUser from '../../composables/private/use-auth-user'
117
+
118
+ import { handleProcess } from '../../helpers'
119
119
 
120
- import { ref, computed, watch } from 'vue'
120
+ import Gleap from 'gleap'
121
+ import { ref, computed, watch, onMounted } from 'vue'
121
122
  import { useRouter } from 'vue-router'
122
123
 
123
124
  defineOptions({
@@ -138,11 +139,6 @@ const props = defineProps({
138
139
  type: String
139
140
  },
140
141
 
141
- helpChatLink: {
142
- type: String,
143
- default: ''
144
- },
145
-
146
142
  items: {
147
143
  default: () => [],
148
144
  type: Array
@@ -172,6 +168,11 @@ const props = defineProps({
172
168
  title: {
173
169
  default: '',
174
170
  type: String
171
+ },
172
+
173
+ useChat: {
174
+ default: true,
175
+ type: Boolean
175
176
  }
176
177
  })
177
178
 
@@ -179,6 +180,9 @@ const emit = defineEmits(['sign-out', 'update:modelValue', 'toggle-notifications
179
180
 
180
181
  const screen = useScreen()
181
182
  const router = useRouter()
183
+ const { initializeChat, toggleChat } = useChatMenu()
184
+
185
+ onMounted(initializeChat)
182
186
 
183
187
  const rootRoute = router.hasRoute('Root') ? { name: 'Root' } : { path: '/' }
184
188
 
@@ -216,7 +220,7 @@ const isMiniMode = computed(() => {
216
220
  return screen.isLarge && isMini.value && !hasOpenedMenu.value && !hasOpenedHelpChat.value
217
221
  })
218
222
 
219
- const menuClasses = computed(() => ({ 'qas-app-menu__menu--spaced': !props.helpChatLink }))
223
+ const menuClasses = computed(() => ({ 'qas-app-menu__menu--spaced': !props.useChat }))
220
224
 
221
225
  const classes = computed(() => {
222
226
  return {
@@ -301,8 +305,53 @@ function setHasOpenedMenu (value) {
301
305
  hasOpenedMenu.value = value
302
306
  }
303
307
 
304
- function setHasOpenedHelpChat (value) {
305
- hasOpenedHelpChat.value = value
308
+ // composables definition
309
+ function useChatMenu () {
310
+ const { user } = useAuthUser()
311
+
312
+ const isMeVersionTwo = process.env.ME_VERSION === 2
313
+
314
+ function initializeChat () {
315
+ Gleap.initialize(handleProcess(() => process.env.GLEAP))
316
+
317
+ Gleap.setLanguage('pt-BR')
318
+
319
+ const {
320
+ uuid,
321
+ name,
322
+ email,
323
+ callingCode,
324
+ phone,
325
+ companyLink,
326
+ companyLinksOptions,
327
+ mainCompanyOptions, // somente na v2
328
+ currentMainCompany // somente na v2
329
+ } = user.value
330
+
331
+ const companyId = isMeVersionTwo ? currentMainCompany : companyLink
332
+ const companyNameList = isMeVersionTwo ? mainCompanyOptions : companyLinksOptions
333
+
334
+ const companyName = companyNameList?.find(({ value }) => value === companyId)?.label
335
+
336
+ Gleap.identify(uuid, {
337
+ name,
338
+ email,
339
+ phone: `+${callingCode || '55'}${phone}`,
340
+ companyId,
341
+ companyName
342
+ })
343
+ }
344
+
345
+ function toggleChat () {
346
+ if (Gleap.isOpened()) return Gleap.close()
347
+
348
+ Gleap.open()
349
+ }
350
+
351
+ return {
352
+ initializeChat,
353
+ toggleChat
354
+ }
306
355
  }
307
356
  </script>
308
357
 
@@ -15,11 +15,6 @@ props:
15
15
  type: String
16
16
  required: true
17
17
 
18
- help-chat-link:
19
- desc: Link para ser usado no iframe do chat, caso não passe nada, o chat não será exibido.
20
- type: String
21
- default: ''
22
-
23
18
  items:
24
19
  desc: Itens do menu.
25
20
  type: Array
@@ -49,6 +44,11 @@ props:
49
44
  desc: Título que vai ficar no label do select de módulos.
50
45
  type: String
51
46
 
47
+ use-chat:
48
+ desc: Componente para controlar se vai ter ou não o chat.
49
+ type: Boolean
50
+ default: true
51
+
52
52
  slots:
53
53
  user:
54
54
  desc: Slot para acessar o menu de usuário.
@@ -234,6 +234,12 @@ function setShowContent () {
234
234
  transform: rotate(180deg);
235
235
  }
236
236
  }
237
+
238
+ &--collapsed {
239
+ #{$root}__dropdown {
240
+ transform: none;
241
+ }
242
+ }
237
243
  }
238
244
 
239
245
  .q-item {
@@ -0,0 +1,17 @@
1
+ import { LocalStorage } from 'quasar'
2
+
3
+ import { ref } from 'vue'
4
+
5
+ const user = ref(LocalStorage.getItem('user'))
6
+
7
+ export default function useAuthUser () {
8
+ window.addEventListener('message', ({ data }) => {
9
+ if (data.type !== 'updateUser') return
10
+
11
+ user.value = data.user
12
+ })
13
+
14
+ return {
15
+ user
16
+ }
17
+ }
@@ -1,222 +0,0 @@
1
- <!-- O chat em si é renderizado em um iframe, o que QMenu, toda vez que fecha se auto destroy, então não podemos usar o
2
- iframe dentro do QMenu, pois toda vez que um iframe é destruído ele perde o seu estado, e teria que iniciar um novo chat,
3
- pra isto é criado um iframe no body, e posicionado com JS + CSS para ficar sobre o QMenu. -->
4
-
5
- <template>
6
- <q-menu class="pv-app-menu-help-chat shadow-2" v-bind="menuProps">
7
- <header class="q-pa-md">
8
- <q-img class="q-mb-md" :src="props.miniBrand" width="36px" />
9
-
10
- <h3 class="text-h3">
11
- Bem-vindo!
12
- </h3>
13
-
14
- <div class="text-body1">
15
- Deixe a sua mensagem para o suporte técnico da Nave.
16
- </div>
17
- </header>
18
-
19
- <qas-box class="full-width pv-app-menu-help-chat__content relative-position" :class="boxClasses">
20
- <div v-if="showIframe" ref="chatContent" class="full-width" />
21
-
22
- <div v-else class="full-width self-end">
23
- <div class="q-mb-sm text-subtitle2">
24
- Estamos conectados
25
- </div>
26
-
27
- <div class="text-body2">
28
- Normalmente responde em alguns minutos
29
- </div>
30
-
31
- <qas-btn class="full-width q-mt-lg" label="Iniciar conversa" variant="primary" @click="initializeChat" />
32
- </div>
33
-
34
- <q-inner-loading :showing="showInnerLoading">
35
- <q-spinner color="grey" size="2rem" />
36
- </q-inner-loading>
37
- </qas-box>
38
- </q-menu>
39
- </template>
40
-
41
- <script setup>
42
- import { useScreen } from '../../../composables'
43
-
44
- import { onMounted, onUnmounted, ref, nextTick, computed } from 'vue'
45
-
46
- defineOptions({ name: 'PvAppMenuHelpChat' })
47
-
48
- const props = defineProps({
49
- link: {
50
- type: String,
51
- default: ''
52
- },
53
-
54
- miniBrand: {
55
- type: String,
56
- default: ''
57
- }
58
- })
59
-
60
- const screen = useScreen()
61
-
62
- // refs
63
- const chatContent = ref(null)
64
- const isOpened = ref(false)
65
- const showIframe = ref(false)
66
- const showInnerLoading = ref(false)
67
-
68
- // computed
69
- const boxClasses = computed(() => {
70
- return {
71
- flex: !showIframe.value,
72
- 'pv-app-menu-help-chat__content--is-opened': showIframe.value
73
- }
74
- })
75
-
76
- const menuProps = computed(() => {
77
- return {
78
- anchor: screen.isSmall ? 'top middle' : 'top right',
79
- maxWidth: screen.isSmall ? '300px' : '400px',
80
- self: screen.isSmall ? 'bottom middle' : 'top left',
81
- touchPosition: !screen.isSmall,
82
-
83
- onBeforeHide: hideIframe,
84
- onShow
85
- }
86
- })
87
-
88
- // hooks
89
-
90
- /**
91
- * Toda vez que a prop "behavior" do componente "QasAppMenu" é alterada, este componente
92
- * é renderizado novamente, então é necessário esconder o iframe caso ele ja esteja aberto.
93
- */
94
- onMounted(hideIframe)
95
-
96
- onUnmounted(() => {
97
- if (showIframe.value) {
98
- window.removeEventListener('scroll', onScroll)
99
- window.removeEventListener('resize', onScroll)
100
- }
101
- })
102
-
103
- // functions
104
-
105
- /**
106
- * Define o estilo do iframe de acordo com a posição do "chatContent" dentro
107
- * do QMenu.
108
- */
109
- async function setIframeStyle () {
110
- await nextTick()
111
-
112
- const iframe = getIframe()
113
-
114
- if (!iframe || !chatContent.value) return
115
-
116
- const { bottom, left, top } = chatContent.value.getBoundingClientRect()
117
-
118
- const width = chatContent.value.offsetWidth
119
-
120
- const styles = {
121
- display: 'block',
122
- top: `${bottom + window.scrollY}px`,
123
- left: `${left + window.scrollX}px`,
124
- bottom: `${top}px`,
125
- width: `${width}px`
126
- }
127
-
128
- Object.assign(iframe.style, styles)
129
- }
130
-
131
- function onShow () {
132
- isOpened.value = true
133
-
134
- if (showIframe.value) setIframeStyle()
135
- }
136
-
137
- function hideIframe () {
138
- isOpened.value = false
139
-
140
- const iframe = getIframe()
141
-
142
- if (!iframe) return
143
-
144
- iframe.style.display = 'none'
145
- }
146
-
147
- function onScroll () {
148
- if (isOpened.value) setIframeStyle()
149
- }
150
-
151
- function createIframe () {
152
- const iframe = document.createElement('iframe')
153
-
154
- iframe.id = 'chat-iframe'
155
- iframe.className = 'pv-app-menu-help-chat__iframe'
156
- iframe.style.display = 'none'
157
- iframe.src = props.link
158
-
159
- document.body.appendChild(iframe)
160
- }
161
-
162
- function getIframe () {
163
- return document.getElementById('chat-iframe')
164
- }
165
-
166
- function initializeChat () {
167
- createIframe()
168
-
169
- window.addEventListener('scroll', onScroll)
170
- window.addEventListener('resize', onScroll)
171
-
172
- toggleIframe()
173
- }
174
-
175
- function toggleIframe () {
176
- showIframe.value = !showIframe.value
177
-
178
- showInnerLoading.value = true
179
-
180
- /**
181
- * É adicionado um loading por 3 motivos:
182
- * - o iframe demora um pouco para ser carregado
183
- * - o loading é um feedback visual para o usuário enquanto o iframe é carregado
184
- * - não é possível adicionar uma animação aparecendo o iframe, então desta
185
- * forma fica suavizado
186
- */
187
- setTimeout(async () => {
188
- showInnerLoading.value = false
189
-
190
- await nextTick()
191
-
192
- onShow()
193
- }, 2000)
194
- }
195
- </script>
196
-
197
- <style lang="scss">
198
- .pv-app-menu-help-chat {
199
- overflow-y: hidden;
200
-
201
- &__content {
202
- height: 260px;
203
- background-color: var(--qas-background-color) !important;
204
- }
205
-
206
- &__iframe {
207
- border: 0;
208
- border-radius: var(--qas-generic-border-radius);
209
- outline: none;
210
- position: absolute;
211
- height: calc(260px - calc(var(--qas-spacing-md) * 2));
212
- z-index: 9999;
213
- }
214
-
215
- // Media: isSmall
216
- @media (max-width: $breakpoint-sm-min) {
217
- &__content--is-opened {
218
- padding: var(--qas-spacing-sm) !important;
219
- }
220
- }
221
- }
222
- </style>