valtech-components 4.0.228 → 4.0.229

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.
Files changed (27) hide show
  1. package/esm2022/lib/components/molecules/chat-composer/chat-composer.component.mjs +410 -0
  2. package/esm2022/lib/components/molecules/chat-input/chat-input.component.mjs +1 -9
  3. package/esm2022/lib/components/molecules/conversation-list-item/conversation-list-item.component.mjs +108 -0
  4. package/esm2022/lib/components/molecules/message-bubble/message-bubble.component.mjs +274 -191
  5. package/esm2022/lib/components/molecules/typing-indicator/typing-indicator.component.mjs +11 -12
  6. package/esm2022/lib/components/organisms/chat-window/chat-window.component.mjs +216 -203
  7. package/esm2022/lib/components/organisms/thread-panel/thread-panel.component.mjs +10 -10
  8. package/esm2022/lib/services/chat/conversation.service.mjs +37 -14
  9. package/esm2022/lib/services/chat/types.mjs +1 -1
  10. package/esm2022/lib/services/i18n/default-content.mjs +5 -1
  11. package/esm2022/lib/shared/utils/datetime.mjs +54 -1
  12. package/esm2022/lib/version.mjs +2 -2
  13. package/esm2022/public-api.mjs +4 -2
  14. package/fesm2022/valtech-components.mjs +1099 -428
  15. package/fesm2022/valtech-components.mjs.map +1 -1
  16. package/lib/components/molecules/chat-composer/chat-composer.component.d.ts +69 -0
  17. package/lib/components/molecules/conversation-list-item/conversation-list-item.component.d.ts +30 -0
  18. package/lib/components/molecules/message-bubble/message-bubble.component.d.ts +34 -32
  19. package/lib/components/molecules/typing-indicator/typing-indicator.component.d.ts +5 -4
  20. package/lib/components/organisms/chat-window/chat-window.component.d.ts +52 -56
  21. package/lib/services/chat/conversation.service.d.ts +12 -5
  22. package/lib/services/chat/types.d.ts +86 -52
  23. package/lib/shared/utils/datetime.d.ts +19 -0
  24. package/lib/version.d.ts +1 -1
  25. package/package.json +1 -1
  26. package/public-api.d.ts +3 -1
  27. package/src/lib/services/firebase/firebase-messaging-sw.js +70 -125
@@ -1,145 +1,90 @@
1
1
  /**
2
- * Firebase Messaging Service Worker
2
+ * firebase-messaging-sw.js Service Worker estatico de valtech-components.
3
3
  *
4
- * Service Worker estático para Firebase Cloud Messaging.
5
- * Carga la configuración dinámicamente desde /firebase-config.js.
4
+ * NO EDITAR en el consumer. Este archivo se publica con la libreria y se copia a
5
+ * la raiz del sitio via el glob de angular.json:
6
6
  *
7
- * CONFIGURACIÓN:
8
- * 1. Crea firebase.config.json con tu configuración de Firebase
9
- * 2. Ejecuta: npm run generate:firebase-config
10
- * Esto genera /firebase-config.js con: self.FIREBASE_CONFIG = {...}
11
- * 3. Agrega este SW y firebase-config.js a los assets de angular.json
7
+ * { "glob": "firebase-messaging-sw.js",
8
+ * "input": "node_modules/valtech-components/src/lib/services/firebase",
9
+ * "output": "/" }
12
10
  *
13
- * Ver README.md para documentación completa.
11
+ * Lee la config de Firebase desde /firebase-config.js (self.FIREBASE_CONFIG),
12
+ * generado en build-time por `npx valtech-firebase-config`. Maneja:
13
+ * - mensajes en background (FCM) → muestra la notificacion del sistema.
14
+ * - click en la notificacion → enfoca/abre la app y postMessage NOTIFICATION_CLICK
15
+ * al cliente (lo consume MessagingService.onNotificationClick()).
14
16
  */
15
17
 
16
- // Importar Firebase scripts
17
- importScripts('https://www.gstatic.com/firebasejs/10.7.0/firebase-app-compat.js');
18
- importScripts('https://www.gstatic.com/firebasejs/10.7.0/firebase-messaging-compat.js');
18
+ /* eslint-disable no-undef */
19
19
 
20
- // Importar configuración desde archivo externo (generado en build)
21
- // Este archivo define: self.FIREBASE_CONFIG = { ... }
20
+ // SDK compat de Firebase (debe coincidir con la major del peer dep firebase ^10).
21
+ importScripts(
22
+ 'https://www.gstatic.com/firebasejs/10.14.1/firebase-app-compat.js'
23
+ );
24
+ importScripts(
25
+ 'https://www.gstatic.com/firebasejs/10.14.1/firebase-messaging-compat.js'
26
+ );
27
+
28
+ // Config inyectada en build-time (self.FIREBASE_CONFIG).
22
29
  try {
23
30
  importScripts('/firebase-config.js');
24
- } catch (e) {
25
- console.error('[SW] No se pudo cargar firebase-config.js:', e);
31
+ } catch (err) {
32
+ // Sin config no se puede inicializar; los push no funcionaran pero el SW
33
+ // no debe romper el registro de la app.
34
+ console.error('[firebase-messaging-sw] no se pudo cargar /firebase-config.js', err);
26
35
  }
27
36
 
28
- // Verificar que la configuración existe
29
- if (!self.FIREBASE_CONFIG) {
30
- console.error('[SW] FIREBASE_CONFIG no está definido.');
31
- console.error('[SW] Ejecuta: npm run generate:firebase-config');
32
- } else {
33
- // Inicializar Firebase
37
+ if (self.FIREBASE_CONFIG) {
34
38
  firebase.initializeApp(self.FIREBASE_CONFIG);
35
-
36
- // Obtener instancia de messaging
37
39
  const messaging = firebase.messaging();
38
40
 
39
- /**
40
- * Handler para mensajes en background.
41
- */
41
+ // Mensaje recibido con la app en background o cerrada.
42
42
  messaging.onBackgroundMessage((payload) => {
43
- console.log('[SW] Mensaje recibido en background:', payload);
44
-
45
- // Web push usa mensajes data-only (sin bloque `notification`) para que el
46
- // navegador NO auto-muestre una notificación duplicada — el SW es el único
47
- // que la pinta. Title/body/icon llegan dentro de `data`. Se mantiene el
48
- // fallback a `payload.notification` por compatibilidad con mensajes
49
- // legacy o nativos que sí traen el bloque.
43
+ const notification = payload.notification || {};
50
44
  const data = payload.data || {};
51
- const notificationTitle =
52
- payload.notification?.title || data.title || 'Nueva notificación';
53
- const notificationBody = payload.notification?.body || data.body || '';
54
- const notificationIcon =
55
- payload.notification?.icon || data.icon || '/assets/icon/favicon.ico';
56
-
57
- const notificationOptions = {
58
- body: notificationBody,
59
- icon: notificationIcon,
60
- image: payload.notification?.image,
61
- badge: '/assets/icon/badge.png',
62
- tag: payload.messageId || data.messageId || 'default',
63
- data: {
64
- ...data,
65
- messageId: payload.messageId || data.messageId,
66
- title: notificationTitle,
67
- body: notificationBody,
68
- },
69
- vibrate: [200, 100, 200],
70
- requireInteraction: data.require_interaction === 'true',
45
+ const title = notification.title || data.title || 'Notificacion';
46
+ const options = {
47
+ body: notification.body || data.body || '',
48
+ icon: notification.icon || data.icon || '/assets/icons/icon-192.png',
49
+ badge: '/assets/icons/icon-96.png',
50
+ data,
71
51
  };
72
-
73
- return self.registration.showNotification(notificationTitle, notificationOptions);
52
+ self.registration.showNotification(title, options);
74
53
  });
54
+ }
75
55
 
76
- /**
77
- * Handler para clicks en notificaciones.
78
- */
79
- self.addEventListener('notificationclick', (event) => {
80
- console.log('[SW] Click en notificación:', event);
81
- event.notification.close();
82
-
83
- const data = event.notification.data || {};
84
- let targetUrl = '/';
85
-
86
- if (data.route) {
87
- targetUrl = data.route;
88
- } else if (data.url) {
89
- targetUrl = data.url;
90
- }
91
-
92
- if (data.query_params) {
93
- const separator = targetUrl.includes('?') ? '&' : '?';
94
- targetUrl += separator + data.query_params;
95
- }
96
-
97
- const notificationPayload = {
98
- type: 'NOTIFICATION_CLICK',
99
- notification: {
100
- title: data.title,
101
- body: data.body,
102
- data: data,
103
- messageId: data.messageId,
104
- },
105
- };
106
-
107
- event.waitUntil(
108
- clients
109
- .matchAll({ type: 'window', includeUncontrolled: true })
110
- .then((clientList) => {
111
- // Siempre enviar postMessage para que la app pueda reaccionar
112
- for (const client of clientList) {
113
- client.postMessage(notificationPayload);
114
- }
115
-
116
- // Navegar si hay route o url
117
- if (targetUrl !== '/') {
118
- for (const client of clientList) {
119
- if ('navigate' in client) {
120
- return client.navigate(targetUrl).then((c) => c?.focus());
121
- }
122
- }
123
- // Si no hay cliente abierto, abrir nueva ventana
124
- if (clients.openWindow) {
125
- return clients.openWindow(targetUrl);
126
- }
127
- }
128
-
129
- // Solo hacer focus si no hay navegación
130
- for (const client of clientList) {
131
- if ('focus' in client) {
132
- return client.focus();
133
- }
56
+ // Click en la notificacion: enfocar un cliente existente (o abrir uno nuevo) y
57
+ // avisarle para que navegue. El cliente resuelve la ruta desde data.route.
58
+ self.addEventListener('notificationclick', (event) => {
59
+ event.notification.close();
60
+
61
+ const data = event.notification.data || {};
62
+ const route = data.route || data.actionRoute || '/';
63
+
64
+ event.waitUntil(
65
+ self.clients
66
+ .matchAll({ type: 'window', includeUncontrolled: true })
67
+ .then((clientList) => {
68
+ const message = {
69
+ type: 'NOTIFICATION_CLICK',
70
+ notification: {
71
+ title: event.notification.title,
72
+ body: event.notification.body,
73
+ data,
74
+ },
75
+ };
76
+
77
+ for (const client of clientList) {
78
+ if ('focus' in client) {
79
+ client.postMessage(message);
80
+ return client.focus();
134
81
  }
135
- if (clients.openWindow) {
136
- return clients.openWindow('/');
137
- }
138
- })
139
- );
140
- });
141
-
142
- self.addEventListener('notificationclose', (event) => {
143
- console.log('[SW] Notificación cerrada:', event.notification.tag);
144
- });
145
- }
82
+ }
83
+
84
+ if (self.clients.openWindow) {
85
+ return self.clients.openWindow(route);
86
+ }
87
+ return undefined;
88
+ })
89
+ );
90
+ });