valtech-components 4.0.218 → 4.0.220
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/esm2022/lib/components/molecules/chat-input/chat-input.component.mjs +157 -0
- package/esm2022/lib/components/molecules/chat-input/types.mjs +2 -0
- package/esm2022/lib/components/molecules/message-bubble/message-bubble.component.mjs +244 -0
- package/esm2022/lib/components/molecules/message-bubble/types.mjs +2 -0
- package/esm2022/lib/components/molecules/typing-indicator/typing-indicator.component.mjs +76 -0
- package/esm2022/lib/components/organisms/account-view/account-view.component.mjs +2 -2
- package/esm2022/lib/components/organisms/chat-window/chat-window.component.mjs +246 -0
- package/esm2022/lib/components/organisms/chat-window/types.mjs +2 -0
- package/esm2022/lib/components/organisms/thread-panel/thread-panel.component.mjs +211 -0
- package/esm2022/lib/services/chat/config.mjs +35 -0
- package/esm2022/lib/services/chat/conversation.service.mjs +274 -0
- package/esm2022/lib/services/chat/types.mjs +10 -0
- package/esm2022/lib/services/entity-feed/entity-feed.service.mjs +103 -0
- package/esm2022/lib/services/entity-feed/index.mjs +2 -0
- package/esm2022/lib/services/entity-feed/types.mjs +2 -0
- package/esm2022/lib/services/i18n/default-content.mjs +65 -1
- package/esm2022/public-api.mjs +16 -1
- package/fesm2022/valtech-components.mjs +1370 -3
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/components/atoms/glow/glow.component.d.ts +1 -1
- package/lib/components/atoms/rights-footer/rights-footer.component.d.ts +2 -2
- package/lib/components/atoms/text/text.component.d.ts +1 -1
- package/lib/components/atoms/user-avatar/user-avatar.component.d.ts +2 -2
- package/lib/components/molecules/article-card/article-card.component.d.ts +1 -1
- package/lib/components/molecules/chat-input/chat-input.component.d.ts +38 -0
- package/lib/components/molecules/chat-input/types.d.ts +20 -0
- package/lib/components/molecules/content-reaction/content-reaction.component.d.ts +2 -2
- package/lib/components/molecules/cta-card/cta-card.component.d.ts +1 -1
- package/lib/components/molecules/features-list/features-list.component.d.ts +4 -4
- package/lib/components/molecules/load-more/load-more.component.d.ts +1 -1
- package/lib/components/molecules/media-object/media-object.component.d.ts +1 -1
- package/lib/components/molecules/message-bubble/message-bubble.component.d.ts +40 -0
- package/lib/components/molecules/message-bubble/types.d.ts +64 -0
- package/lib/components/molecules/metric-card/metric-card.component.d.ts +1 -1
- package/lib/components/molecules/typing-indicator/typing-indicator.component.d.ts +19 -0
- package/lib/components/organisms/account-view/account-view.component.d.ts +1 -1
- package/lib/components/organisms/article/article.component.d.ts +6 -6
- package/lib/components/organisms/auth-cta/auth-cta.component.d.ts +1 -1
- package/lib/components/organisms/bottom-nav/bottom-nav.component.d.ts +1 -1
- package/lib/components/organisms/chat-window/chat-window.component.d.ts +63 -0
- package/lib/components/organisms/chat-window/types.d.ts +36 -0
- package/lib/components/organisms/landing-steps/landing-steps.component.d.ts +1 -1
- package/lib/components/organisms/login/login.component.d.ts +1 -1
- package/lib/components/organisms/member-import-modal/member-import-modal.component.d.ts +1 -1
- package/lib/components/organisms/notification-preferences-view/notification-preferences-view.component.d.ts +1 -1
- package/lib/components/organisms/organization-view/organization-view.component.d.ts +1 -1
- package/lib/components/organisms/thread-panel/thread-panel.component.d.ts +55 -0
- package/lib/components/templates/page-wrapper/page-wrapper.component.d.ts +2 -2
- package/lib/services/chat/config.d.ts +37 -0
- package/lib/services/chat/conversation.service.d.ts +147 -0
- package/lib/services/chat/types.d.ts +145 -0
- package/lib/services/entity-feed/entity-feed.service.d.ts +71 -0
- package/lib/services/entity-feed/index.d.ts +2 -0
- package/lib/services/entity-feed/types.d.ts +26 -0
- package/package.json +1 -1
- package/public-api.d.ts +13 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { EnvironmentProviders, InjectionToken } from '@angular/core';
|
|
2
|
+
/**
|
|
3
|
+
* Configuracion del servicio de Chat.
|
|
4
|
+
*/
|
|
5
|
+
export interface ValtechChatConfig {
|
|
6
|
+
/** URL base de la API del backend (ej: 'https://api.myvaltech.com'). */
|
|
7
|
+
apiUrl: string;
|
|
8
|
+
/** ID de la aplicacion (ej: 'showcase'). */
|
|
9
|
+
appId: string;
|
|
10
|
+
/** Prefijo del endpoint de chat (default: '/v2/chat'). */
|
|
11
|
+
chatPrefix?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Token de inyeccion para la configuracion del Chat.
|
|
15
|
+
*/
|
|
16
|
+
export declare const VALTECH_CHAT_CONFIG: InjectionToken<ValtechChatConfig>;
|
|
17
|
+
/**
|
|
18
|
+
* Configuracion por defecto del Chat.
|
|
19
|
+
*/
|
|
20
|
+
export declare const DEFAULT_CHAT_CONFIG: Partial<ValtechChatConfig>;
|
|
21
|
+
/**
|
|
22
|
+
* Provee el servicio de Chat a la aplicacion Angular.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* // main.ts
|
|
26
|
+
* import { provideValtechChat } from 'valtech-components';
|
|
27
|
+
*
|
|
28
|
+
* bootstrapApplication(AppComponent, {
|
|
29
|
+
* providers: [
|
|
30
|
+
* provideValtechChat({
|
|
31
|
+
* apiUrl: environment.apiUrl,
|
|
32
|
+
* appId: 'showcase',
|
|
33
|
+
* }),
|
|
34
|
+
* ],
|
|
35
|
+
* });
|
|
36
|
+
*/
|
|
37
|
+
export declare function provideValtechChat(config: ValtechChatConfig): EnvironmentProviders;
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { Observable } from 'rxjs';
|
|
2
|
+
import { Conversation, ConversationType, CreateConversationRequest, ListConversationsResponse, Message, UpdateConversationRequest } from './types';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* ConversationService
|
|
6
|
+
*
|
|
7
|
+
* Gestiona conversaciones y mensajes del chat.
|
|
8
|
+
*
|
|
9
|
+
* Dos capas:
|
|
10
|
+
* - HTTP (via backend /v2/chat/*): operaciones de escritura y consulta.
|
|
11
|
+
* - Firestore real-time (directa): escucha mensajes y estado de escritura.
|
|
12
|
+
*
|
|
13
|
+
* Paths Firestore:
|
|
14
|
+
* /apps/{appId}/orgs/{orgId}/conversations/{convId}/messages/{msgId}
|
|
15
|
+
* /apps/{appId}/orgs/{orgId}/conversations/{convId}/typing/{userId}
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* // Enviar y escuchar mensajes
|
|
19
|
+
* const svc = inject(ConversationService);
|
|
20
|
+
*
|
|
21
|
+
* // Enviar (HTTP)
|
|
22
|
+
* svc.sendMessage(convId, 'Hola!').subscribe();
|
|
23
|
+
*
|
|
24
|
+
* // Escuchar en tiempo real (Firestore)
|
|
25
|
+
* svc.watchMessages(convId, orgId, appId).subscribe(msgs => this.messages.set(msgs));
|
|
26
|
+
*/
|
|
27
|
+
export declare class ConversationService {
|
|
28
|
+
private config;
|
|
29
|
+
private http;
|
|
30
|
+
private firestoreService;
|
|
31
|
+
private firestore;
|
|
32
|
+
constructor();
|
|
33
|
+
private get baseUrl();
|
|
34
|
+
/**
|
|
35
|
+
* Crea una nueva conversacion.
|
|
36
|
+
*/
|
|
37
|
+
createConversation(req: CreateConversationRequest): Observable<Conversation>;
|
|
38
|
+
/**
|
|
39
|
+
* Obtiene o crea una conversacion asociada a una entidad (post, request, etc.).
|
|
40
|
+
* Usa el patron upsert del backend: si ya existe una conversacion para esa entidad,
|
|
41
|
+
* la devuelve; si no, la crea.
|
|
42
|
+
*/
|
|
43
|
+
getOrCreateForEntity(entityType: string, entityId: string, type?: ConversationType): Observable<Conversation>;
|
|
44
|
+
/**
|
|
45
|
+
* Lista las conversaciones del usuario autenticado.
|
|
46
|
+
*/
|
|
47
|
+
listConversations(cursor?: string): Observable<ListConversationsResponse>;
|
|
48
|
+
/**
|
|
49
|
+
* Obtiene una conversacion por ID.
|
|
50
|
+
*/
|
|
51
|
+
getConversation(convId: string): Observable<Conversation>;
|
|
52
|
+
/**
|
|
53
|
+
* Actualiza el titulo o estado de una conversacion.
|
|
54
|
+
*/
|
|
55
|
+
updateConversation(convId: string, req: UpdateConversationRequest): Observable<Conversation>;
|
|
56
|
+
/**
|
|
57
|
+
* Abre una conversacion cerrada.
|
|
58
|
+
*/
|
|
59
|
+
openConversation(convId: string): Observable<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Cierra una conversacion.
|
|
62
|
+
*/
|
|
63
|
+
closeConversation(convId: string): Observable<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Agrega un participante a la conversacion.
|
|
66
|
+
*/
|
|
67
|
+
addParticipant(convId: string, userId: string): Observable<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Elimina un participante de la conversacion.
|
|
70
|
+
*/
|
|
71
|
+
removeParticipant(convId: string, userId: string): Observable<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Envia un mensaje a una conversacion.
|
|
74
|
+
*/
|
|
75
|
+
sendMessage(convId: string, body: string): Observable<Message>;
|
|
76
|
+
/**
|
|
77
|
+
* Elimina (marca como eliminado) un mensaje.
|
|
78
|
+
*/
|
|
79
|
+
deleteMessage(convId: string, msgId: string): Observable<void>;
|
|
80
|
+
/**
|
|
81
|
+
* Construye el path base para los datos de una conversacion.
|
|
82
|
+
* Nota: usamos el path completo con skipPrefix porque el path ya incluye
|
|
83
|
+
* apps/{appId}/orgs/{orgId} que el FirestoreService prefijaria de nuevo.
|
|
84
|
+
* En cambio armamos el path como sub-coleccion directamente.
|
|
85
|
+
*/
|
|
86
|
+
private convMessagesPath;
|
|
87
|
+
private convTypingPath;
|
|
88
|
+
/**
|
|
89
|
+
* Escucha los mensajes de una conversacion en tiempo real.
|
|
90
|
+
*
|
|
91
|
+
* @param convId - ID de la conversacion
|
|
92
|
+
* @param orgId - ID de la organizacion
|
|
93
|
+
* @param appId - ID de la aplicacion
|
|
94
|
+
* @param limit - Cantidad maxima de mensajes a cargar (default 50)
|
|
95
|
+
*/
|
|
96
|
+
watchMessages(convId: string, orgId: string, appId: string, limit?: number): Observable<Message[]>;
|
|
97
|
+
/**
|
|
98
|
+
* Escucha los usuarios que estan escribiendo en una conversacion.
|
|
99
|
+
* Devuelve un array de displayNames.
|
|
100
|
+
*
|
|
101
|
+
* @param convId - ID de la conversacion
|
|
102
|
+
* @param orgId - ID de la organizacion
|
|
103
|
+
* @param appId - ID de la aplicacion
|
|
104
|
+
*/
|
|
105
|
+
watchTyping(convId: string, orgId: string, appId: string): Observable<string[]>;
|
|
106
|
+
/**
|
|
107
|
+
* Registra que el usuario actual esta escribiendo.
|
|
108
|
+
* El documento se sobreescribe para actualizar el timestamp.
|
|
109
|
+
* Debe llamarse con un TTL/cleanup (ver stopTyping).
|
|
110
|
+
*
|
|
111
|
+
* @param convId - ID de la conversacion
|
|
112
|
+
* @param orgId - ID de la organizacion
|
|
113
|
+
* @param appId - ID de la aplicacion
|
|
114
|
+
* @param displayName - Nombre visible del usuario
|
|
115
|
+
*/
|
|
116
|
+
startTyping(convId: string, orgId: string, appId: string, displayName: string): void;
|
|
117
|
+
/**
|
|
118
|
+
* Elimina el documento de "escribiendo" del usuario actual.
|
|
119
|
+
*
|
|
120
|
+
* @param convId - ID de la conversacion
|
|
121
|
+
* @param orgId - ID de la organizacion
|
|
122
|
+
* @param appId - ID de la aplicacion
|
|
123
|
+
*/
|
|
124
|
+
stopTyping(convId: string, orgId: string, appId: string): void;
|
|
125
|
+
/**
|
|
126
|
+
* Marca un mensaje como leido por el usuario actual.
|
|
127
|
+
* Escribe directamente en Firestore sin pasar por el backend.
|
|
128
|
+
*
|
|
129
|
+
* @param convId - ID de la conversacion
|
|
130
|
+
* @param msgId - ID del ultimo mensaje leido
|
|
131
|
+
* @param orgId - ID de la organizacion
|
|
132
|
+
* @param appId - ID de la aplicacion
|
|
133
|
+
*/
|
|
134
|
+
markRead(convId: string, msgId: string, orgId: string, appId: string): void;
|
|
135
|
+
/**
|
|
136
|
+
* Importa ABS_PATH_SENTINEL de forma lazy para evitar dependencias circulares.
|
|
137
|
+
*/
|
|
138
|
+
private getAbsPathSentinel;
|
|
139
|
+
/**
|
|
140
|
+
* Obtiene el userId del usuario actual desde sessionStorage / localStorage
|
|
141
|
+
* como fallback no-DI para el contexto de escritura de Firestore.
|
|
142
|
+
* En prod, el AuthService actualiza el userId en el contexto de la app.
|
|
143
|
+
*/
|
|
144
|
+
private getCurrentUserId;
|
|
145
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ConversationService, never>;
|
|
146
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<ConversationService>;
|
|
147
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chat Service Types
|
|
3
|
+
*
|
|
4
|
+
* Tipos compartidos para el sistema de chat en tiempo real.
|
|
5
|
+
* Firestore paths:
|
|
6
|
+
* /apps/{appId}/orgs/{orgId}/conversations/{convId}/messages/{msgId}
|
|
7
|
+
* /apps/{appId}/orgs/{orgId}/conversations/{convId}/typing/{userId}
|
|
8
|
+
*/
|
|
9
|
+
import { FirestoreDocument } from '../firebase/types';
|
|
10
|
+
/** Tipo de conversacion. */
|
|
11
|
+
export type ConversationType = 'direct' | 'group' | 'entity';
|
|
12
|
+
/** Estado de una conversacion. */
|
|
13
|
+
export type ConversationStatus = 'open' | 'closed';
|
|
14
|
+
/** Participante de una conversacion. */
|
|
15
|
+
export interface ConversationParticipant {
|
|
16
|
+
/** ID del usuario. */
|
|
17
|
+
userId: string;
|
|
18
|
+
/** Nombre visible del usuario. */
|
|
19
|
+
displayName: string;
|
|
20
|
+
/** URL del avatar del usuario (opcional). */
|
|
21
|
+
avatarUrl?: string;
|
|
22
|
+
/** Fecha en que se unio a la conversacion. */
|
|
23
|
+
joinedAt: Date;
|
|
24
|
+
/** Ultimo mensaje leido por este participante. */
|
|
25
|
+
lastReadMsgId?: string;
|
|
26
|
+
}
|
|
27
|
+
/** Documento de conversacion en Firestore. */
|
|
28
|
+
export interface Conversation extends FirestoreDocument {
|
|
29
|
+
/** Tipo de conversacion. */
|
|
30
|
+
type: ConversationType;
|
|
31
|
+
/** Estado de la conversacion. */
|
|
32
|
+
status: ConversationStatus;
|
|
33
|
+
/** Participantes. */
|
|
34
|
+
participants: ConversationParticipant[];
|
|
35
|
+
/** Tipo de entidad asociada (para tipo entity). */
|
|
36
|
+
entityType?: string;
|
|
37
|
+
/** ID de la entidad asociada. */
|
|
38
|
+
entityId?: string;
|
|
39
|
+
/** Titulo de la conversacion (para grupos). */
|
|
40
|
+
title?: string;
|
|
41
|
+
/** ID del ultimo mensaje. */
|
|
42
|
+
lastMsgId?: string;
|
|
43
|
+
/** Texto del ultimo mensaje (preview). */
|
|
44
|
+
lastMsgBody?: string;
|
|
45
|
+
/** Fecha del ultimo mensaje. */
|
|
46
|
+
lastMsgAt?: Date;
|
|
47
|
+
/** Conteo de mensajes no leidos por userId. */
|
|
48
|
+
unreadCount?: Record<string, number>;
|
|
49
|
+
}
|
|
50
|
+
/** Tipo de mensaje. */
|
|
51
|
+
export type MessageType = 'text' | 'image' | 'file' | 'system';
|
|
52
|
+
/** Estado de envio del mensaje. */
|
|
53
|
+
export type MessageStatus = 'sending' | 'sent' | 'failed';
|
|
54
|
+
/** Archivo adjunto en un mensaje. */
|
|
55
|
+
export interface MessageAttachment {
|
|
56
|
+
/** Nombre del archivo. */
|
|
57
|
+
name: string;
|
|
58
|
+
/** URL de descarga. */
|
|
59
|
+
url: string;
|
|
60
|
+
/** Tipo MIME. */
|
|
61
|
+
mimeType: string;
|
|
62
|
+
/** Tamano en bytes. */
|
|
63
|
+
size?: number;
|
|
64
|
+
}
|
|
65
|
+
/** Reaccion a un mensaje. */
|
|
66
|
+
export interface MessageReaction {
|
|
67
|
+
/** Token del emoji (ej: 'like', 'heart'). */
|
|
68
|
+
token: string;
|
|
69
|
+
/** Cantidad de usuarios que reaccionaron con este emoji. */
|
|
70
|
+
count: number;
|
|
71
|
+
/** Si el usuario actual tiene activa esta reaccion. */
|
|
72
|
+
active: boolean;
|
|
73
|
+
}
|
|
74
|
+
/** Referencia al mensaje al que se responde. */
|
|
75
|
+
export interface MessageReplyTo {
|
|
76
|
+
/** ID del mensaje original. */
|
|
77
|
+
msgId: string;
|
|
78
|
+
/** Nombre del emisor del mensaje original. */
|
|
79
|
+
senderName: string;
|
|
80
|
+
/** Texto del mensaje original (preview). */
|
|
81
|
+
body: string;
|
|
82
|
+
}
|
|
83
|
+
/** Documento de mensaje en Firestore. */
|
|
84
|
+
export interface Message extends FirestoreDocument {
|
|
85
|
+
/** ID del emisor. */
|
|
86
|
+
senderId: string;
|
|
87
|
+
/** Nombre visible del emisor. */
|
|
88
|
+
senderName: string;
|
|
89
|
+
/** URL del avatar del emisor (opcional). */
|
|
90
|
+
senderAvatar?: string;
|
|
91
|
+
/** Cuerpo del mensaje. */
|
|
92
|
+
body: string;
|
|
93
|
+
/** Tipo de mensaje. */
|
|
94
|
+
type: MessageType;
|
|
95
|
+
/** Fecha de creacion del mensaje. */
|
|
96
|
+
createdAt: Date;
|
|
97
|
+
/** Si el mensaje fue eliminado. */
|
|
98
|
+
isDeleted?: boolean;
|
|
99
|
+
/** Si el mensaje fue editado. */
|
|
100
|
+
isEdited?: boolean;
|
|
101
|
+
/** Mensaje al que se responde. */
|
|
102
|
+
replyTo?: MessageReplyTo;
|
|
103
|
+
/** Archivos adjuntos. */
|
|
104
|
+
attachments?: MessageAttachment[];
|
|
105
|
+
/** Reacciones del mensaje. */
|
|
106
|
+
reactions?: MessageReaction[];
|
|
107
|
+
/** Estado de envio (para mensajes optimistas del lado del cliente). */
|
|
108
|
+
status?: MessageStatus;
|
|
109
|
+
}
|
|
110
|
+
/** Documento de "escribiendo" en Firestore. */
|
|
111
|
+
export interface TypingDocument extends FirestoreDocument {
|
|
112
|
+
/** Nombre visible del usuario que esta escribiendo. */
|
|
113
|
+
displayName: string;
|
|
114
|
+
/** Timestamp de la ultima actualizacion. */
|
|
115
|
+
updatedAt: Date;
|
|
116
|
+
}
|
|
117
|
+
/** Request para crear una conversacion. */
|
|
118
|
+
export interface CreateConversationRequest {
|
|
119
|
+
/** Tipo de conversacion. */
|
|
120
|
+
type: ConversationType;
|
|
121
|
+
/** IDs de los participantes iniciales. */
|
|
122
|
+
participantIds?: string[];
|
|
123
|
+
/** Para tipo entity: tipo de la entidad. */
|
|
124
|
+
entityType?: string;
|
|
125
|
+
/** Para tipo entity: ID de la entidad. */
|
|
126
|
+
entityId?: string;
|
|
127
|
+
/** Titulo (para grupos). */
|
|
128
|
+
title?: string;
|
|
129
|
+
}
|
|
130
|
+
/** Request para actualizar una conversacion. */
|
|
131
|
+
export interface UpdateConversationRequest {
|
|
132
|
+
/** Nuevo titulo (opcional). */
|
|
133
|
+
title?: string;
|
|
134
|
+
/** Nuevo estado (opcional). */
|
|
135
|
+
status?: ConversationStatus;
|
|
136
|
+
}
|
|
137
|
+
/** Response de listado de conversaciones. */
|
|
138
|
+
export interface ListConversationsResponse {
|
|
139
|
+
/** Lista de conversaciones. */
|
|
140
|
+
conversations: Conversation[];
|
|
141
|
+
/** Cursor para paginacion. */
|
|
142
|
+
nextCursor?: string;
|
|
143
|
+
/** Si hay mas paginas. */
|
|
144
|
+
hasMore: boolean;
|
|
145
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Observable } from 'rxjs';
|
|
2
|
+
import { EntityFeedItem, EntityFeedItemWithReaction } from './types';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* EntityFeedService — capa de lectura Firestore para entidades proyectables.
|
|
6
|
+
*
|
|
7
|
+
* Soporta cualquier tipo de entidad (posts, articles, adoptions, reels...)
|
|
8
|
+
* siguiendo el esquema de paths:
|
|
9
|
+
* - Entidades: apps/{appId}/orgs/{orgId}/{entityType}s/{entityId}
|
|
10
|
+
* - Reacciones del usuario: apps/{appId}/users/{uid}/reactions/{entityType}_{entityId}
|
|
11
|
+
*
|
|
12
|
+
* FirestoreService auto-prefija los paths con apps/{appId}/.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* const feed = inject(EntityFeedService);
|
|
16
|
+
*
|
|
17
|
+
* // Solo entidades
|
|
18
|
+
* feed.watchEntities<Post>('org_x', 'post').subscribe(posts => ...);
|
|
19
|
+
*
|
|
20
|
+
* // Feed con reaccion del viewer incluida
|
|
21
|
+
* feed.watchFeed<Post>('org_x', 'post').subscribe(items => {
|
|
22
|
+
* items.forEach(item => console.log(item.viewerHasReacted, item.viewerToken));
|
|
23
|
+
* });
|
|
24
|
+
*/
|
|
25
|
+
export declare class EntityFeedService {
|
|
26
|
+
private fs;
|
|
27
|
+
private auth;
|
|
28
|
+
/**
|
|
29
|
+
* Suscripcion en tiempo real a entidades publicadas de un tipo dado.
|
|
30
|
+
*
|
|
31
|
+
* Coleccion: orgs/{orgId}/{entityType}s
|
|
32
|
+
* Auto-prefijada a: apps/{appId}/orgs/{orgId}/{entityType}s
|
|
33
|
+
*
|
|
34
|
+
* Filtra por status === 'published', ordena por publishedAt desc.
|
|
35
|
+
*
|
|
36
|
+
* @param orgId - ID de la organizacion
|
|
37
|
+
* @param entityType - Tipo de entidad en singular (ej. 'post', 'article')
|
|
38
|
+
* @param options - Opciones opcionales (limit, default 20)
|
|
39
|
+
*/
|
|
40
|
+
watchEntities<T extends EntityFeedItem>(orgId: string, entityType: string, options?: {
|
|
41
|
+
limit?: number;
|
|
42
|
+
}): Observable<T[]>;
|
|
43
|
+
/**
|
|
44
|
+
* Suscripcion en tiempo real a las reacciones del usuario actual para un tipo de entidad.
|
|
45
|
+
*
|
|
46
|
+
* Coleccion: users/{uid}/reactions
|
|
47
|
+
* Auto-prefijada a: apps/{appId}/users/{uid}/reactions
|
|
48
|
+
*
|
|
49
|
+
* Retorna un Map<entityId, token> para lookup O(1) al combinar con el feed.
|
|
50
|
+
* Si no hay usuario autenticado, retorna un Map vacio.
|
|
51
|
+
*
|
|
52
|
+
* @param entityType - Tipo de entidad a filtrar (ej. 'post', 'article')
|
|
53
|
+
*/
|
|
54
|
+
watchMyReactions(entityType: string): Observable<Map<string, string>>;
|
|
55
|
+
/**
|
|
56
|
+
* Combina watchEntities + watchMyReactions en un unico stream.
|
|
57
|
+
*
|
|
58
|
+
* Cada item del feed incluye viewerToken y viewerHasReacted, listos para
|
|
59
|
+
* renderizar el estado de reaccion del usuario actual sin logica adicional
|
|
60
|
+
* en la pagina.
|
|
61
|
+
*
|
|
62
|
+
* @param orgId - ID de la organizacion
|
|
63
|
+
* @param entityType - Tipo de entidad en singular (ej. 'post', 'article')
|
|
64
|
+
* @param options - Opciones opcionales (limit, default 20)
|
|
65
|
+
*/
|
|
66
|
+
watchFeed<T extends EntityFeedItem>(orgId: string, entityType: string, options?: {
|
|
67
|
+
limit?: number;
|
|
68
|
+
}): Observable<EntityFeedItemWithReaction<T>[]>;
|
|
69
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<EntityFeedService, never>;
|
|
70
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<EntityFeedService>;
|
|
71
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface EntityFeedItem {
|
|
2
|
+
id: string;
|
|
3
|
+
entityType: string;
|
|
4
|
+
visibility: 'public' | 'org' | 'private';
|
|
5
|
+
authorId: string;
|
|
6
|
+
authorName: string;
|
|
7
|
+
authorAvatarUrl?: string;
|
|
8
|
+
title?: string;
|
|
9
|
+
excerpt?: string;
|
|
10
|
+
coverImage?: string;
|
|
11
|
+
publishedAt?: Date;
|
|
12
|
+
updatedAt?: Date;
|
|
13
|
+
reactionCounts?: Record<string, number>;
|
|
14
|
+
commentCount?: number;
|
|
15
|
+
}
|
|
16
|
+
export interface UserReactionDoc {
|
|
17
|
+
id: string;
|
|
18
|
+
token: string;
|
|
19
|
+
entityType: string;
|
|
20
|
+
entityId: string;
|
|
21
|
+
createdAt?: Date;
|
|
22
|
+
}
|
|
23
|
+
export type EntityFeedItemWithReaction<T extends EntityFeedItem = EntityFeedItem> = T & {
|
|
24
|
+
viewerToken: string | null;
|
|
25
|
+
viewerHasReacted: boolean;
|
|
26
|
+
};
|
package/package.json
CHANGED
package/public-api.d.ts
CHANGED
|
@@ -413,6 +413,7 @@ export * from './lib/components/molecules/request-form/types';
|
|
|
413
413
|
export * from './lib/components/molecules/content-reaction/content-reaction.component';
|
|
414
414
|
export * from './lib/components/molecules/content-reaction/types';
|
|
415
415
|
export * from './lib/services/reactions/index';
|
|
416
|
+
export * from './lib/services/entity-feed/index';
|
|
416
417
|
export * from './lib/components/molecules/reaction-bar/reaction-bar.component';
|
|
417
418
|
export * from './lib/components/molecules/reaction-bar/types';
|
|
418
419
|
export * from './lib/services/splash-screen';
|
|
@@ -469,3 +470,15 @@ export * from './lib/components/organisms/qr-scanner/qr-scanner.component';
|
|
|
469
470
|
export * from './lib/components/organisms/qr-scanner/types';
|
|
470
471
|
export * from './lib/components/organisms/html-viewer-modal/html-viewer-modal.component';
|
|
471
472
|
export * from './lib/components/molecules/form-field/form-field.component';
|
|
473
|
+
export { ConversationService } from './lib/services/chat/conversation.service';
|
|
474
|
+
export { provideValtechChat, VALTECH_CHAT_CONFIG } from './lib/services/chat/config';
|
|
475
|
+
export type { ValtechChatConfig } from './lib/services/chat/config';
|
|
476
|
+
export * from './lib/services/chat/types';
|
|
477
|
+
export { MessageBubbleComponent } from './lib/components/molecules/message-bubble/message-bubble.component';
|
|
478
|
+
export * from './lib/components/molecules/message-bubble/types';
|
|
479
|
+
export { ChatInputComponent } from './lib/components/molecules/chat-input/chat-input.component';
|
|
480
|
+
export * from './lib/components/molecules/chat-input/types';
|
|
481
|
+
export { TypingIndicatorComponent } from './lib/components/molecules/typing-indicator/typing-indicator.component';
|
|
482
|
+
export { ChatWindowComponent } from './lib/components/organisms/chat-window/chat-window.component';
|
|
483
|
+
export * from './lib/components/organisms/chat-window/types';
|
|
484
|
+
export { ThreadPanelComponent } from './lib/components/organisms/thread-panel/thread-panel.component';
|