vue-wiguet-chatweb 0.1.34 → 0.1.35

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. package/README.md +68 -68
  2. package/dist/App.vue.d.ts +2 -0
  3. package/dist/components/Chat.vue.d.ts +5 -2
  4. package/dist/components/ChatMessage.vue.d.ts +12 -0
  5. package/dist/components/DangerIcon.vue.d.ts +1 -1
  6. package/dist/components/IconAttach.vue.d.ts +1 -1
  7. package/dist/components/IconChat.vue.d.ts +1 -1
  8. package/dist/components/IconClose.vue.d.ts +1 -1
  9. package/dist/components/IconSend.vue.d.ts +1 -1
  10. package/dist/components/IconTelegram.vue.d.ts +1 -1
  11. package/dist/components/IconWhatsApp.vue.d.ts +1 -1
  12. package/dist/components/Loader.vue.d.ts +1 -1
  13. package/dist/components/MessageList.vue.d.ts +3 -2
  14. package/dist/components/ODialog/IPropsDialog.d.ts +0 -1
  15. package/dist/components/ODialog/ODialog.vue.d.ts +13 -15
  16. package/dist/components/Widget.vue.d.ts +1 -2
  17. package/dist/dto/app.dto.d.ts +0 -1
  18. package/dist/index.d.ts +0 -1
  19. package/dist/main.d.ts +0 -1
  20. package/dist/store/config.d.ts +0 -1
  21. package/dist/store/index.d.ts +0 -1
  22. package/dist/style.css +1 -1
  23. package/dist/vue-wiguet-chatweb.js +791 -754
  24. package/dist/vue-wiguet-chatweb.umd.cjs +26 -26
  25. package/package.json +66 -66
  26. package/src/assets/emojis/AngryIcon.svg +4 -4
  27. package/src/assets/emojis/HappiestIcon.svg +4 -4
  28. package/src/assets/emojis/HappyIcon.svg +4 -4
  29. package/src/assets/emojis/NeutralIcon.svg +4 -4
  30. package/src/assets/emojis/SadIcon.svg +4 -4
  31. package/src/components/Chat.vue +716 -696
  32. package/src/components/ChatMessage.vue +102 -102
  33. package/src/components/DangerIcon.vue +12 -12
  34. package/src/components/IconAttach.vue +24 -24
  35. package/src/components/IconChat.vue +23 -23
  36. package/src/components/IconClose.vue +5 -5
  37. package/src/components/IconSend.vue +8 -8
  38. package/src/components/IconTelegram.vue +28 -28
  39. package/src/components/IconWhatsApp.vue +39 -39
  40. package/src/components/IconWidget.vue +45 -45
  41. package/src/components/Loader.vue +31 -31
  42. package/src/components/LoadingComponent.vue +111 -111
  43. package/src/components/MessageList.vue +357 -357
  44. package/src/components/ODialog/IPropsDialog.ts +4 -4
  45. package/src/components/ODialog/IPropsSidebar.ts +13 -13
  46. package/src/components/ODialog/ODialog.vue +107 -107
  47. package/src/components/Widget.vue +196 -196
  48. package/src/components/__tests__/Chat.spec.ts +5 -5
  49. package/src/components/__tests__/ChatMessage.spec.ts +5 -5
  50. package/src/components/__tests__/MessageList.spec.ts +47 -47
@@ -1,4 +1,4 @@
1
- import { IPropsSidebar } from './IPropsSidebar';
2
-
3
-
4
- export interface IPropsDialog extends IPropsSidebar {}
1
+ import { IPropsSidebar } from './IPropsSidebar';
2
+
3
+
4
+ export interface IPropsDialog extends IPropsSidebar {}
@@ -1,13 +1,13 @@
1
- export interface IPropsSidebar {
2
- modelValue?: boolean;
3
- title?: string;
4
- // isLoading?: boolean;
5
- // hideActions?: boolean;
6
- // hideHeader?: boolean;
7
- // acceptFn?: () => Promise<boolean>;
8
- // beforeAcceptFn?: () => Promise<boolean>;
9
- // disable?: boolean;
10
-
11
- // solo para v-bind
12
- 'onUpdate:modelValue'?: (args: IPropsSidebar['modelValue'])=> void
13
- }
1
+ export interface IPropsSidebar {
2
+ modelValue?: boolean;
3
+ title?: string;
4
+ // isLoading?: boolean;
5
+ // hideActions?: boolean;
6
+ // hideHeader?: boolean;
7
+ // acceptFn?: () => Promise<boolean>;
8
+ // beforeAcceptFn?: () => Promise<boolean>;
9
+ // disable?: boolean;
10
+
11
+ // solo para v-bind
12
+ 'onUpdate:modelValue'?: (args: IPropsSidebar['modelValue'])=> void
13
+ }
@@ -1,108 +1,108 @@
1
- <template>
2
- <Teleport v-if="isReadyTeleport" to="#dialogs">
3
- <div v-if="props.modelValue" class="dialog-overlay">
4
- <div class="dialog-content" @click.stop>
5
- <div class="header-widget">
6
- <h4 class="title-chat">{{ title }}</h4>
7
- <button @click="() => closeDialog()" class="btn-close">
8
- <IconClose class="pointer" />
9
- </button>
10
- </div>
11
-
12
- <div>
13
- <slot></slot>
14
- </div>
15
- </div>
16
- </div>
17
- </Teleport>
18
- </template>
19
-
20
- <script lang="ts" setup>
21
- import { onMounted, ref } from 'vue';
22
- import IconClose from '../IconClose.vue'
23
- import { IPropsDialog } from './IPropsDialog';
24
-
25
- const props = defineProps<IPropsDialog>()
26
-
27
- const emit = defineEmits(['update:modelValue']);
28
-
29
- const isReadyTeleport = ref(false);
30
-
31
-
32
- const closeDialog = () => {
33
- emit("update:modelValue", false);
34
- };
35
-
36
- onMounted(() => {
37
- const app = document.getElementById("app")
38
-
39
- if(!app) throw new Error('app is required')
40
-
41
- let dialogContainer = document.getElementById("dialogs");
42
-
43
- if (!dialogContainer) {
44
- dialogContainer = document.createElement("div");
45
- dialogContainer.id = "dialogs";
46
- dialogContainer.classList.add('widget-component')
47
- app.appendChild(dialogContainer);
48
- isReadyTeleport.value = true
49
- }
50
- });
51
- </script>
52
-
53
- <style scoped>
54
- .dialog-overlay {
55
- z-index: 10001;
56
- position: fixed;
57
- top: 0;
58
- left: 0;
59
- width: 100%;
60
- height: 100%;
61
- background-color: rgba(0, 0, 0, 0.5);
62
- display: flex;
63
- justify-content: center;
64
- align-items: center;
65
- opacity: 0;
66
- animation: fadeIn 0.3s forwards;
67
- }
68
-
69
- .dialog-content {
70
- background-color: white;
71
- padding: 15px;
72
- border-radius: 8px;
73
- text-align: center;
74
- animation: slideIn 0.3s ease-out forwards;
75
- }
76
-
77
- @keyframes fadeIn {
78
- to {
79
- opacity: 1;
80
- }
81
- }
82
-
83
- @keyframes slideIn {
84
- from {
85
- transform: translateY(-50px);
86
- }
87
- to {
88
- transform: translateY(0);
89
- }
90
- }
91
-
92
- .dialog-overlay.v-enter-active,
93
- .dialog-overlay.v-leave-active {
94
- transition: opacity 0.3s;
95
- }
96
-
97
- .btn-close {
98
- padding: 0;
99
- background-color: transparent;
100
- border: none;
101
- display: flex;
102
- align-items: center;
103
- border-radius: 50%;
104
- &:hover {
105
- background-color: rgba(202, 202, 202, 0.534);
106
- }
107
- }
1
+ <template>
2
+ <Teleport v-if="isReadyTeleport" to="#dialogs">
3
+ <div v-if="props.modelValue" class="dialog-overlay">
4
+ <div class="dialog-content" @click.stop>
5
+ <div class="header-widget">
6
+ <h4 class="title-chat">{{ title }}</h4>
7
+ <button @click="() => closeDialog()" class="btn-close">
8
+ <IconClose class="pointer" />
9
+ </button>
10
+ </div>
11
+
12
+ <div>
13
+ <slot></slot>
14
+ </div>
15
+ </div>
16
+ </div>
17
+ </Teleport>
18
+ </template>
19
+
20
+ <script lang="ts" setup>
21
+ import { onMounted, ref } from 'vue';
22
+ import IconClose from '../IconClose.vue'
23
+ import { IPropsDialog } from './IPropsDialog';
24
+
25
+ const props = defineProps<IPropsDialog>()
26
+
27
+ const emit = defineEmits(['update:modelValue']);
28
+
29
+ const isReadyTeleport = ref(false);
30
+
31
+
32
+ const closeDialog = () => {
33
+ emit("update:modelValue", false);
34
+ };
35
+
36
+ onMounted(() => {
37
+ const app = document.getElementById("app")
38
+
39
+ if(!app) throw new Error('app is required')
40
+
41
+ let dialogContainer = document.getElementById("dialogs");
42
+
43
+ if (!dialogContainer) {
44
+ dialogContainer = document.createElement("div");
45
+ dialogContainer.id = "dialogs";
46
+ dialogContainer.classList.add('widget-component')
47
+ app.appendChild(dialogContainer);
48
+ isReadyTeleport.value = true
49
+ }
50
+ });
51
+ </script>
52
+
53
+ <style scoped>
54
+ .dialog-overlay {
55
+ z-index: 10001;
56
+ position: fixed;
57
+ top: 0;
58
+ left: 0;
59
+ width: 100%;
60
+ height: 100%;
61
+ background-color: rgba(0, 0, 0, 0.5);
62
+ display: flex;
63
+ justify-content: center;
64
+ align-items: center;
65
+ opacity: 0;
66
+ animation: fadeIn 0.3s forwards;
67
+ }
68
+
69
+ .dialog-content {
70
+ background-color: white;
71
+ padding: 15px;
72
+ border-radius: 8px;
73
+ text-align: center;
74
+ animation: slideIn 0.3s ease-out forwards;
75
+ }
76
+
77
+ @keyframes fadeIn {
78
+ to {
79
+ opacity: 1;
80
+ }
81
+ }
82
+
83
+ @keyframes slideIn {
84
+ from {
85
+ transform: translateY(-50px);
86
+ }
87
+ to {
88
+ transform: translateY(0);
89
+ }
90
+ }
91
+
92
+ .dialog-overlay.v-enter-active,
93
+ .dialog-overlay.v-leave-active {
94
+ transition: opacity 0.3s;
95
+ }
96
+
97
+ .btn-close {
98
+ padding: 0;
99
+ background-color: transparent;
100
+ border: none;
101
+ display: flex;
102
+ align-items: center;
103
+ border-radius: 50%;
104
+ &:hover {
105
+ background-color: rgba(202, 202, 202, 0.534);
106
+ }
107
+ }
108
108
  </style>
@@ -1,196 +1,196 @@
1
- <template>
2
- <div
3
- class="widget-component widget-css-reset widget-container"
4
- :class="isDarkMode ? 'chat-dark-mode' : ''"
5
- >
6
- <div
7
- id="chat-circle"
8
- class="widget-container"
9
- v-if="props.tokenAuth.length > 10"
10
- v-show="!isChatBoxVisible"
11
- >
12
- <div class="container-buttons-chat" :class="{'active': toggleButtonsChats}">
13
- <a href="javascript:;" class="button whatsapp" @click="go(MeansCommunication.WHATSAPP)">
14
- <IconWhatsApp />
15
- </a>
16
-
17
- <a href="javascript:;" class="button telegram" @click="go(MeansCommunication.TELEGRAM)">
18
- <IconTelegram />
19
- </a>
20
-
21
- <a
22
- href="javascript:;"
23
- class="button webchat"
24
- title="Debe estar autenticado"
25
- :class="{'disabled': props.tokenAuth.length < 10 }"
26
- @click="toggleButtonsChats && props.tokenAuth.length > 10 && toggleChat()"
27
- >
28
- <IconChat />
29
- </a>
30
- </div>
31
-
32
- <div class="new-message-badge" v-if="newMessages" >
33
- {{ newMessages > 9 ? "9+" : newMessages }}
34
- </div>
35
- <a href="javascript:;" @click="props.tokenAuth.length > 10 && toggleChat()" class="btn-primary">
36
- <IconWidget />
37
- </a>
38
- </div>
39
-
40
- <div class="chat-box" v-show="isChatBoxVisible">
41
- <Chat
42
- v-if="tokenAuth"
43
- :visible="isChatBoxVisible"
44
- :titlePrincipal="titlePrincipal"
45
- :toggleChat="toggleChat"
46
- :tokenAuth="tokenAuth"
47
- :user="user"
48
- @show-toast="(data) => emit('show-toast', data)"
49
- @show-confirm="(data) => emit('show-confirm', data)"
50
- @clear-new-messages="newMessages = 0"
51
- @new-message="() => newMessages++"
52
- @not-viewed-total="(val) => (newMessages = val)"
53
- @on-qualifying="(args)=> emit('onQualifying', args)"
54
- />
55
- </div>
56
- </div>
57
- </template>
58
-
59
- <script setup lang="ts">
60
- import { PropType, ref } from "vue";
61
- import Chat from "./Chat.vue";
62
- import IconWidget from "./IconWidget.vue";
63
- import IconTelegram from "./IconTelegram.vue";
64
- import IconWhatsApp from "./IconWhatsApp.vue";
65
- import IconChat from "./IconChat.vue";
66
-
67
- const emit = defineEmits(["show-toast", "show-confirm", "onQualifying"]);
68
- const visible = ref(true);
69
- const enum MeansCommunication{
70
- WHATSAPP,
71
- TELEGRAM
72
- }
73
-
74
- function go(means: MeansCommunication) {
75
- const cellphoneNumbers = window.VITE_CELLPHONE_NUMBERS?.split(',') ?? [];
76
-
77
- if (cellphoneNumbers.length === 0) {
78
- console.warn('not found cellphone numbers')
79
- return
80
- }
81
-
82
- toggleButtonsChats.value = false;
83
-
84
- const index = Math.floor(Math.random() * cellphoneNumbers.length)
85
-
86
- if(MeansCommunication['WHATSAPP'] === means) {
87
- window.open('https://wa.me/'+ cellphoneNumbers[index], 'WhatsApp', 'noopener')
88
- return;
89
- }
90
-
91
- window.open('https://t.me/+' + cellphoneNumbers[index], 'Telegram', 'noopener')
92
- }
93
-
94
- const isChatBoxVisible = ref(false);
95
- const newMessages = ref(0);
96
- const toggleButtonsChats = ref(false);
97
-
98
- const toggleChat = () => {
99
- isChatBoxVisible.value = !isChatBoxVisible.value;
100
- };
101
-
102
- const props = defineProps({
103
- tokenAuth: { type: String, required: true },
104
- titlePrincipal: { type: String },
105
- user: {
106
- type: Object as PropType<{
107
- nombreCompleto: string;
108
- ci: string;
109
- msPersonaId: number;
110
- }>,
111
- required: true,
112
- },
113
- isDarkMode: {
114
- type: Boolean,
115
- default: false,
116
- },
117
- });
118
- </script>
119
- <style>
120
- @import url(../style.css);
121
- </style>
122
-
123
- <style scoped>
124
-
125
- .disabled {
126
- color: currentColor;
127
- cursor: not-allowed !important;
128
- opacity: 0.4 !important;
129
- text-decoration: none;
130
- }
131
-
132
- .container-buttons-chat {
133
- position: relative;
134
- right: -1.8rem;
135
- }
136
- .button {
137
- position: absolute;
138
- width: 2.5rem;
139
- height: 2.5rem;
140
-
141
- opacity: 0;
142
- box-shadow: 0px 1px 3px 1px #c0c0c0;
143
- border-radius: 100%;
144
- border: 1px solid white;
145
- background-color: white;
146
- overflow: hidden;
147
- cursor: pointer;
148
- transition: transform 0.5s ease, opacity 0.3s ease;
149
- z-index: -1;
150
- }
151
-
152
- .container-buttons-chat.active > a {
153
- z-index: 1;
154
- opacity: 1;
155
- }
156
-
157
- .container-buttons-chat.active .whatsapp {
158
- transform: translateY(-150px); /* Subir más arriba */
159
- }
160
-
161
- .container-buttons-chat.active .telegram {
162
- transform: translateY(-100px); /* Subir más arriba */
163
- }
164
-
165
- .container-buttons-chat.active .webchat {
166
- transform: translateY(-50px); /* Subir más arriba */
167
- }
168
-
169
- .widget-container {
170
- position: relative;
171
- }
172
- .new-message-badge {
173
- position: absolute;
174
- background-color: red;
175
- width: 30px;
176
- height: 30px;
177
- display: flex;
178
- font-family: "Roboto", sans-serif;
179
- align-items: center;
180
- font-weight: 500;
181
- justify-content: center;
182
- border-radius: 50%;
183
- right: -2px;
184
- top: -4px;
185
- z-index: 2;
186
- }
187
-
188
- .btn-primary {
189
- color: var(--primary-color);
190
- &:hover {
191
- opacity: .7;
192
- }
193
- }
194
-
195
-
196
- </style>
1
+ <template>
2
+ <div
3
+ class="widget-component widget-css-reset widget-container"
4
+ :class="isDarkMode ? 'chat-dark-mode' : ''"
5
+ >
6
+ <div
7
+ id="chat-circle"
8
+ class="widget-container"
9
+ v-if="props.tokenAuth.length > 10"
10
+ v-show="!isChatBoxVisible"
11
+ >
12
+ <div class="container-buttons-chat" :class="{'active': toggleButtonsChats}">
13
+ <a href="javascript:;" class="button whatsapp" @click="go(MeansCommunication.WHATSAPP)">
14
+ <IconWhatsApp />
15
+ </a>
16
+
17
+ <a href="javascript:;" class="button telegram" @click="go(MeansCommunication.TELEGRAM)">
18
+ <IconTelegram />
19
+ </a>
20
+
21
+ <a
22
+ href="javascript:;"
23
+ class="button webchat"
24
+ title="Debe estar autenticado"
25
+ :class="{'disabled': props.tokenAuth.length < 10 }"
26
+ @click="toggleButtonsChats && props.tokenAuth.length > 10 && toggleChat()"
27
+ >
28
+ <IconChat />
29
+ </a>
30
+ </div>
31
+
32
+ <div class="new-message-badge" v-if="newMessages" >
33
+ {{ newMessages > 9 ? "9+" : newMessages }}
34
+ </div>
35
+ <a href="javascript:;" @click="props.tokenAuth.length > 10 && toggleChat()" class="btn-primary">
36
+ <IconWidget />
37
+ </a>
38
+ </div>
39
+
40
+ <div class="chat-box" v-show="isChatBoxVisible">
41
+ <Chat
42
+ v-if="tokenAuth"
43
+ :visible="isChatBoxVisible"
44
+ :titlePrincipal="titlePrincipal"
45
+ :toggleChat="toggleChat"
46
+ :tokenAuth="tokenAuth"
47
+ :user="user"
48
+ @show-toast="(data) => emit('show-toast', data)"
49
+ @show-confirm="(data) => emit('show-confirm', data)"
50
+ @clear-new-messages="newMessages = 0"
51
+ @new-message="() => newMessages++"
52
+ @not-viewed-total="(val) => (newMessages = val)"
53
+ @on-qualifying="(args)=> emit('onQualifying', args)"
54
+ />
55
+ </div>
56
+ </div>
57
+ </template>
58
+
59
+ <script setup lang="ts">
60
+ import { PropType, ref } from "vue";
61
+ import Chat from "./Chat.vue";
62
+ import IconWidget from "./IconWidget.vue";
63
+ import IconTelegram from "./IconTelegram.vue";
64
+ import IconWhatsApp from "./IconWhatsApp.vue";
65
+ import IconChat from "./IconChat.vue";
66
+
67
+ const emit = defineEmits(["show-toast", "show-confirm", "onQualifying"]);
68
+ const visible = ref(true);
69
+ const enum MeansCommunication{
70
+ WHATSAPP,
71
+ TELEGRAM
72
+ }
73
+
74
+ function go(means: MeansCommunication) {
75
+ const cellphoneNumbers = window.VITE_CELLPHONE_NUMBERS?.split(',') ?? [];
76
+
77
+ if (cellphoneNumbers.length === 0) {
78
+ console.warn('not found cellphone numbers')
79
+ return
80
+ }
81
+
82
+ toggleButtonsChats.value = false;
83
+
84
+ const index = Math.floor(Math.random() * cellphoneNumbers.length)
85
+
86
+ if(MeansCommunication['WHATSAPP'] === means) {
87
+ window.open('https://wa.me/'+ cellphoneNumbers[index], 'WhatsApp', 'noopener')
88
+ return;
89
+ }
90
+
91
+ window.open('https://t.me/+' + cellphoneNumbers[index], 'Telegram', 'noopener')
92
+ }
93
+
94
+ const isChatBoxVisible = ref(false);
95
+ const newMessages = ref(0);
96
+ const toggleButtonsChats = ref(false);
97
+
98
+ const toggleChat = () => {
99
+ isChatBoxVisible.value = !isChatBoxVisible.value;
100
+ };
101
+
102
+ const props = defineProps({
103
+ tokenAuth: { type: String, required: true },
104
+ titlePrincipal: { type: String },
105
+ user: {
106
+ type: Object as PropType<{
107
+ nombreCompleto: string;
108
+ ci: string;
109
+ msPersonaId: number;
110
+ }>,
111
+ required: true,
112
+ },
113
+ isDarkMode: {
114
+ type: Boolean,
115
+ default: false,
116
+ },
117
+ });
118
+ </script>
119
+ <style>
120
+ @import url(../style.css);
121
+ </style>
122
+
123
+ <style scoped>
124
+
125
+ .disabled {
126
+ color: currentColor;
127
+ cursor: not-allowed !important;
128
+ opacity: 0.4 !important;
129
+ text-decoration: none;
130
+ }
131
+
132
+ .container-buttons-chat {
133
+ position: relative;
134
+ right: -1.8rem;
135
+ }
136
+ .button {
137
+ position: absolute;
138
+ width: 2.5rem;
139
+ height: 2.5rem;
140
+
141
+ opacity: 0;
142
+ box-shadow: 0px 1px 3px 1px #c0c0c0;
143
+ border-radius: 100%;
144
+ border: 1px solid white;
145
+ background-color: white;
146
+ overflow: hidden;
147
+ cursor: pointer;
148
+ transition: transform 0.5s ease, opacity 0.3s ease;
149
+ z-index: -1;
150
+ }
151
+
152
+ .container-buttons-chat.active > a {
153
+ z-index: 1;
154
+ opacity: 1;
155
+ }
156
+
157
+ .container-buttons-chat.active .whatsapp {
158
+ transform: translateY(-150px); /* Subir más arriba */
159
+ }
160
+
161
+ .container-buttons-chat.active .telegram {
162
+ transform: translateY(-100px); /* Subir más arriba */
163
+ }
164
+
165
+ .container-buttons-chat.active .webchat {
166
+ transform: translateY(-50px); /* Subir más arriba */
167
+ }
168
+
169
+ .widget-container {
170
+ position: relative;
171
+ }
172
+ .new-message-badge {
173
+ position: absolute;
174
+ background-color: red;
175
+ width: 30px;
176
+ height: 30px;
177
+ display: flex;
178
+ font-family: "Roboto", sans-serif;
179
+ align-items: center;
180
+ font-weight: 500;
181
+ justify-content: center;
182
+ border-radius: 50%;
183
+ right: -2px;
184
+ top: -4px;
185
+ z-index: 2;
186
+ }
187
+
188
+ .btn-primary {
189
+ color: var(--primary-color);
190
+ &:hover {
191
+ opacity: .7;
192
+ }
193
+ }
194
+
195
+
196
+ </style>
@@ -1,6 +1,6 @@
1
- import { expect, it } from 'vitest'
2
- import Chat from '../Chat.vue'
3
-
4
- it('definido', () => {
5
- expect(Chat).toBeDefined()
1
+ import { expect, it } from 'vitest'
2
+ import Chat from '../Chat.vue'
3
+
4
+ it('definido', () => {
5
+ expect(Chat).toBeDefined()
6
6
  })
@@ -1,6 +1,6 @@
1
- import { expect, it } from 'vitest'
2
- import ChatMessage from '../ChatMessage.vue'
3
-
4
- it('definido', () => {
5
- expect(ChatMessage).toBeDefined()
1
+ import { expect, it } from 'vitest'
2
+ import ChatMessage from '../ChatMessage.vue'
3
+
4
+ it('definido', () => {
5
+ expect(ChatMessage).toBeDefined()
6
6
  })