From 0d57a8cbfab9177791e4087df43c4306581f3e21 Mon Sep 17 00:00:00 2001 From: Pascal Date: Mon, 2 Dec 2024 21:37:46 +0100 Subject: [PATCH] chat_component_ok --- src/main.ts | 12 +- src/pages/chat/chat-component.ts | 59 +++ src/pages/chat/chat.ts | 841 ++++++++++++++++++------------- src/pages/signature/signature.ts | 63 +-- src/router.ts | 11 +- 5 files changed, 585 insertions(+), 401 deletions(-) create mode 100644 src/pages/chat/chat-component.ts diff --git a/src/main.ts b/src/main.ts index 0768d99..bbbb06a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,10 +1,14 @@ import { SignatureComponent } from './pages/signature/signature-component'; import { SignatureElement } from './pages/signature/signature'; +import { ChatComponent } from './pages/chat/chat-component'; +import { ChatElement } from './pages/chat/chat'; export { SignatureComponent, - SignatureElement + SignatureElement, + ChatComponent, + ChatElement }; @@ -12,6 +16,8 @@ declare global { interface HTMLElementTagNameMap { 'signature-component': SignatureComponent; 'signature-element': SignatureElement; + 'chat-component': ChatComponent; + 'chat-element': ChatElement; } } @@ -20,4 +26,6 @@ if ((import.meta as any).env.VITE_IS_INDEPENDANT_LIB) { // Initialiser les composants si nécessaire customElements.define('signature-component', SignatureComponent); customElements.define('signature-element', SignatureElement); -} \ No newline at end of file + customElements.define('chat-component', ChatComponent); + customElements.define('chat-element', ChatElement); +} diff --git a/src/pages/chat/chat-component.ts b/src/pages/chat/chat-component.ts new file mode 100644 index 0000000..3d533ed --- /dev/null +++ b/src/pages/chat/chat-component.ts @@ -0,0 +1,59 @@ +import { ChatElement } from './chat'; +import chatCss from '../../../public/style/chat.css?raw' +import Services from '../../services/service.js' + +class ChatComponent extends HTMLElement { + _callback: any + chatElement: ChatElement | null = null; + + constructor() { + super(); + console.log('INIT') + this.attachShadow({ mode: 'open' }); + + this.chatElement = this.shadowRoot?.querySelector('chat-element') || null; + } + + connectedCallback() { + console.log('CALLBACKs') + this.render(); + this.fetchData(); + + if (!customElements.get('chat-element')) { + customElements.define('chat-element', ChatElement); + } + } + + async fetchData() { + if ((import.meta as any).env.VITE_IS_INDEPENDANT_LIB === false) { + const data = await (window as any).myService?.getProcesses(); + } else { + const service = await Services.getInstance() + const data = await service.getProcesses(); + } + } + + set callback(fn) { + if (typeof fn === 'function') { + this._callback = fn; + } else { + console.error('Callback is not a function'); + } + } + + get callback() { + return this._callback; + } + + render() { + if(this.shadowRoot) { + // Créer l'élément chat-element + const chatElement = document.createElement('chat-element'); + this.shadowRoot.innerHTML = ``; + this.shadowRoot.appendChild(chatElement); + } + } +} + +export { ChatComponent } +customElements.define('chat-component', ChatComponent); diff --git a/src/pages/chat/chat.ts b/src/pages/chat/chat.ts index 55910be..a641760 100755 --- a/src/pages/chat/chat.ts +++ b/src/pages/chat/chat.ts @@ -1,373 +1,536 @@ -import { groupsMock } from '../../mocks/mock-signature/groupsMock.js'; -import { messageStore } from '../../utils/messageMock.js'; - -let messagesMock = messageStore.getMessages(); - -let selectedMemberId: number | null = null; - -// Load the list of groups -function loadGroupList() { - const groupList = document.getElementById('group-list'); - if (!groupList) return; - - groupsMock.forEach(group => { - const li = document.createElement('li'); - li.textContent = group.name; - li.onclick = (event) => { - event.stopPropagation(); - toggleRoles(group, li); - }; - groupList.appendChild(li); - }); -} - -// Toggle the list of Roles -function toggleRoles(group: { roles: { name: string; members: any[] }[] }, groupElement: HTMLElement) { - let roleList = groupElement.querySelector('.role-list') as HTMLElement; - if (roleList) { - roleList.style.display = roleList.style.display === 'none' ? 'block' : 'none'; - return; +declare global { + interface Window { + toggleUserList: () => void; + switchUser: (userId: string | number) => void; + loadMemberChat: (memberId: string | number) => void; } - - roleList = document.createElement('ul'); - roleList.className = 'role-list'; - - group.roles.forEach(role => { - const roleItem = document.createElement('li'); - roleItem.textContent = role.name; - - roleItem.onclick = (event) => { - event.stopPropagation(); - toggleMembers(role, roleItem); - }; - - roleList.appendChild(roleItem); - }); - - groupElement.appendChild(roleList); } -// Toggle the list of membres -function toggleMembers(role: { members: { id: number; name: string; }[] }, roleElement: HTMLElement) { - let memberList = roleElement.querySelector('.member-list') as HTMLElement; - if (memberList) { - memberList.style.display = memberList.style.display === 'none' ? 'block' : 'none'; - return; - } - - memberList = document.createElement('ul'); - memberList.className = 'member-list'; - - role.members.forEach(member => { - const memberItem = document.createElement('li'); - memberItem.textContent = member.name; - - memberItem.onclick = (event) => { - event.stopPropagation(); - loadMemberChat(member.id); - }; - - memberList.appendChild(memberItem); - }); - - roleElement.appendChild(memberList); -} - -// Load the list of members -function loadMemberChat(memberId: string | number) { - selectedMemberId = Number(memberId); - const memberMessages = messagesMock.find(m => String(m.memberId) === String(memberId)); - - // Trouver le processus et le rôle du membre - let memberInfo = { processName: '', roleName: '', memberName: '' }; - groupsMock.forEach(process => { - process.roles.forEach(role => { - const member = role.members.find(m => String(m.id) === String(memberId)); - if (member) { - memberInfo = { - processName: process.name, - roleName: role.name, - memberName: member.name - }; - } - }); - }); - - const chatHeader = document.getElementById('chat-header'); - const messagesContainer = document.getElementById('messages'); - - if (!chatHeader || !messagesContainer) return; - - chatHeader.textContent = `Chat with ${memberInfo.roleName} ${memberInfo.memberName} from ${memberInfo.processName}`; - messagesContainer.innerHTML = ''; - - if (memberMessages) { - memberMessages.messages.forEach((message: { - type: string; - fileData?: string; - fileName?: string; - sender: string; - text?: string; - time: string; - }) => { - const messageElement = document.createElement('div'); - messageElement.className = 'message-container'; - - const messageContent = document.createElement('div'); - messageContent.className = 'message'; - if (message.type === 'file') { - messageContent.innerHTML = `${message.fileName}`; - messageContent.classList.add('user'); - } else { - messageContent.innerHTML = `${message.sender}: ${message.text} ${message.time}`; - if (message.sender === "4NK") { - messageContent.classList.add('user'); - } - } - - messageElement.appendChild(messageContent); - messagesContainer.appendChild(messageElement); - }); - } +import { groupsMock } from '../../mocks/mock-signature/groupsMock'; +import { messagesMock as initialMessagesMock, messagesMock } from '../../mocks/mock-signature/messagesMock'; +import { membersMock } from '../../mocks/mock-signature/membersMocks'; +import { + Message, + DocumentSignature, + } from '../../models/signature.models'; +import { messageStore } from '../../utils/messageMock'; +import { Member } from '../../interface/memberInterface'; +import { Group } from '../../interface/groupInterface'; +import { getCorrectDOM } from '../../utils/document.utils'; - scrollToBottom(messagesContainer); -} +let currentUser: Member = membersMock[0]; -// Scroll down the conversation after loading messages -function scrollToBottom(container: HTMLElement) { - container.scrollTop = container.scrollHeight; -} - -// Generate an automatic response -function generateAutoReply(senderName: string) { - return { - id: Date.now(), - sender: senderName, - text: "OK...", - time: new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }), - type: 'text' - }; -} - -// Send a messsage -function sendMessage() { - const messageInput = document.getElementById('message-input') as HTMLInputElement; - if (!messageInput) return; - const messageText = messageInput.value.trim(); - - if (messageText === '' || selectedMemberId === null) { - return; - } - - const newMessage = { - id: Date.now(), - sender: "4NK", - text: messageText, - time: new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }), - type: 'text' - }; - - // Ajouter et afficher le message immédiatement - messageStore.addMessage(selectedMemberId, newMessage); - messagesMock = messageStore.getMessages(); - loadMemberChat(selectedMemberId); - - // Réinitialiser l'input - messageInput.value = ''; - - // Réponse automatique après 2 secondes - setTimeout(() => { - if (selectedMemberId === null) return; - - const autoReply = generateAutoReply(`Member ${selectedMemberId}`); - messageStore.addMessage(selectedMemberId, autoReply); - messagesMock = messageStore.getMessages(); - loadMemberChat(selectedMemberId); - addNotification(selectedMemberId, autoReply); - }, 2000); -} - -// Add an event for the submit button -const sendBtn = document.getElementById('send-button'); -const messageInput = document.getElementById('message-input'); - -if (sendBtn) sendBtn.onclick = sendMessage; -if (messageInput) { - messageInput.addEventListener('keydown', function (event) { - if (event.key === 'Enter') { - event.preventDefault(); - sendMessage(); - } - }); -} - -// Send a file -function sendFile(file: File) { - const reader = new FileReader(); - reader.onloadend = function () { - const fileData = reader.result; - const fileName = file.name; - - const newFileMessage = { - id: Date.now(), - sender: "4NK", - fileName: fileName, - fileData: fileData, - time: new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }), - type: 'file' - }; - - if (selectedMemberId === null) return; - messageStore.addMessage(selectedMemberId, newFileMessage); - - messagesMock = messageStore.getMessages(); - - if (selectedMemberId !== null) { - loadMemberChat(selectedMemberId); - } - }; - - reader.readAsDataURL(file); -} - -// Managing the sent file -document.getElementById('file-input')?.addEventListener('change', function (event: Event) { - const file = (event.target as HTMLInputElement).files?.[0]; - if (file) { - sendFile(file); - } -}); - - -///////////////////// Notification module ///////////////////// -const notificationBadge = document.querySelector('.notification-badge') as HTMLElement; -const notificationBoard = document.getElementById('notification-board'); -const notificationBell = document.getElementById('notification-bell'); - -interface Notification { - memberId: number; +interface LocalNotification { + memberId: string; text: string; time: string; } -let notifications: Notification[] = []; -let unreadCount = 0; -// Update notification badge -function updateNotificationBadge() { - if (!notificationBadge) return; - const count = notifications.length; - notificationBadge.textContent = count > 99 ? '+99' : count.toString(); - notificationBadge.style.display = count > 0 ? 'block' : 'none'; +export function initChat() { + const chatElement = document.createElement('chat-element'); + const container = document.querySelector('.container'); + if (container) { + container.appendChild(chatElement); + } } -// Add notification -function addNotification(memberId: number, message: { text: string; time: string }) { - // Creating a new notification - const notification = { - memberId, - text: `New message from Member ${memberId}: ${message.text}`, - time: message.time - }; +class ChatElement extends HTMLElement { + private selectedMemberId: string | null = null; + private messagesMock: any[] = []; + private dom: Node; + private notifications: LocalNotification[] = []; + private notificationBadge = document.querySelector('.notification-badge'); + private notificationBoard = document.getElementById('notification-board'); + private notificationBell = document.getElementById('notification-bell'); + private selectedSignatories: DocumentSignature[] = []; + private allMembers = membersMock.map(member => ({ + id: member.id, + name: member.name, + roleName: 'Default Role' + })); - // Added notification to list and interface - notifications.push(notification); - renderNotifications(); - updateNotificationBadge(); -} - -// Show notifications -function renderNotifications() { - if (!notificationBoard) return; - // Reset the interface - notificationBoard.innerHTML = ''; + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this.dom = getCorrectDOM('signature-element'); - // Displays "No notifications available" if there are no notifications - if (notifications.length === 0) { - notificationBoard.innerHTML = '
No notifications available
'; + window.toggleUserList = this.toggleUserList.bind(this); + window.switchUser = this.switchUser.bind(this); + window.loadMemberChat = this.loadMemberChat.bind(this); + + // Initialiser les événements de notification + document.addEventListener('click', (event: Event): void => { + if (this.notificationBoard && this.notificationBoard.style.display === 'block' && + !this.notificationBoard.contains(event.target as Node) && + this.notificationBell && !this.notificationBell.contains(event.target as Node)) { + this.notificationBoard.style.display = 'none'; + } + }); + this.initMessageEvents(); + this.initFileUpload(); + } + + private initMessageEvents() { + // Pour le bouton Send + const sendButton = document.getElementById('send-button'); + if (sendButton) { + sendButton.addEventListener('click', () => this.sendMessage()); + } + + // Pour la touche Entrée + const messageInput = document.getElementById('message-input'); + if (messageInput) { + messageInput.addEventListener('keypress', (event: KeyboardEvent) => { + if (event.key === 'Enter' && !event.shiftKey) { + event.preventDefault(); + this.sendMessage(); + } + }); + } + } + + private initFileUpload() { + const fileInput = document.getElementById('file-input') as HTMLInputElement; + if (fileInput) { + fileInput.addEventListener('change', (event: Event) => { + const target = event.target as HTMLInputElement; + if (target.files && target.files.length > 0) { + this.sendFile(target.files[0]); + } + }); + } + } + + ///////////////////// Notification module ///////////////////// + // Delete a notification + private removeNotification(index: number) { + this.notifications?.splice(index, 1); // Ajout de ?. + this.renderNotifications(); + this.updateNotificationBadge(); + } + // Show notifications + private renderNotifications() { + if (!this.notificationBoard) return; + + // Reset the interface + this.notificationBoard.innerHTML = ''; + + // Displays "No notifications available" if there are no notifications + if (this.notifications.length === 0) { + this.notificationBoard.innerHTML = '
No notifications available
'; + return; + } + + // Add each notification to the list + this.notifications.forEach((notif, index) => { + const notifElement = document.createElement('div'); + notifElement.className = 'notification-item'; + notifElement.textContent = `${notif.text} at ${notif.time}`; + notifElement.onclick = () => { + this.loadMemberChat(notif.memberId); + this.removeNotification(index); + }; + this.notificationBoard?.appendChild(notifElement); + }); + } + private updateNotificationBadge() { + if (!this.notificationBadge) return; + const count = this.notifications.length; + this.notificationBadge.textContent = count > 99 ? '+99' : count.toString(); + (this.notificationBadge as HTMLElement).style.display = count > 0 ? 'block' : 'none'; + } + + + // Add notification + private addNotification(memberId: string, message: Message) { + // Creating a new notification + const notification = { + memberId, + text: `New message from Member ${memberId}: ${message.text}`, + time: message.time + }; + + // Added notification to list and interface + this.notifications.push(notification); + this.renderNotifications(); + this.updateNotificationBadge(); + } + +// Send a messsage + private sendMessage() { + const messageInput = document.getElementById('message-input') as HTMLInputElement; + if (!messageInput) return; + const messageText = messageInput.value.trim(); + + if (messageText === '' || this.selectedMemberId === null) { return; } - // Add each notification to the list - notifications.forEach((notif, index) => { - const notifElement = document.createElement('div'); - notifElement.className = 'notification-item'; - notifElement.textContent = `${notif.text} at ${notif.time}`; - notifElement.onclick = () => { - loadMemberChat(notif.memberId); - removeNotification(index); - }; - notificationBoard.appendChild(notifElement); - }); -} - -// Delete a notification -function removeNotification(index: number) { - notifications.splice(index, 1); - renderNotifications(); - updateNotificationBadge(); -} - -// Adds an event for deploying the notification list -if (notificationBell && notificationBoard) { - notificationBell.onclick = () => { - notificationBoard.style.display = notificationBoard.style.display === 'block' ? 'none' : 'block'; + const newMessage: Message = { + id: Date.now(), + sender: "4NK", + text: messageText, + time: new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }), + type: 'text' as const }; -} + // Add and display the message immediately + messageStore.addMessage(this.selectedMemberId, newMessage); + this.messagesMock = messageStore.getMessages(); + this.loadMemberChat(this.selectedMemberId); -// Close the notification board when clicking outside of it -document.addEventListener('click', (event) => { - if (notificationBoard && notificationBell && - notificationBoard.style.display === 'block' && - !notificationBoard.contains(event.target as Node) && - !notificationBell.contains(event.target as Node)) { - notificationBoard.style.display = 'none'; + // Reset the input + messageInput.value = ''; + + // Automatic response after 2 seconds + setTimeout(() => { + if (this.selectedMemberId) { + const autoReply = this.generateAutoReply(`Member ${this.selectedMemberId}`); + messageStore.addMessage(this.selectedMemberId, autoReply); + this.messagesMock = messageStore.getMessages(); + this.loadMemberChat(this.selectedMemberId); + this.addNotification(this.selectedMemberId, autoReply); + } + }, 2000); } -}); -// Loads group list at startup -//loadGroupList(); - -export function initChat(): void { - loadGroupList(); + // Scroll down the conversation after loading messages + private scrollToBottom(container: HTMLElement) { + container.scrollTop = container.scrollHeight; + } - // Re-initialize event listeners - const sendBtn = document.getElementById('send-button'); - const messageInput = document.getElementById('message-input'); - const fileInput = document.getElementById('file-input'); - - if (sendBtn) sendBtn.onclick = sendMessage; - if (messageInput) { - messageInput.addEventListener('keydown', function (event) { - if (event.key === 'Enter') { - event.preventDefault(); - sendMessage(); + + // Load the list of members + private loadMemberChat(memberId: string | number) { + this.selectedMemberId = String(memberId); + const memberMessages = this.messagesMock.find(m => String(m.memberId) === String(memberId)); + + // Find the process and the role of the member + let memberInfo = { processName: '', roleName: '', memberName: '' }; + groupsMock.forEach(process => { + process.roles.forEach(role => { + const member = role.members.find(m => String(m.id) === String(memberId)); + if (member) { + memberInfo = { + processName: process.name, + roleName: role.name, + memberName: member.name + }; + } + }); + }); + + const chatHeader = document.getElementById('chat-header'); + const messagesContainer = document.getElementById('messages'); + + if (!chatHeader || !messagesContainer) return; + + chatHeader.textContent = `Chat with ${memberInfo.roleName} ${memberInfo.memberName} from ${memberInfo.processName}`; + messagesContainer.innerHTML = ''; + + if (memberMessages) { + memberMessages.messages.forEach((message: Message) => { + const messageElement = document.createElement('div'); + messageElement.className = 'message-container'; + + const messageContent = document.createElement('div'); + messageContent.className = 'message'; + if (message.type === 'file') { + messageContent.innerHTML = `${message.fileName}`; + messageContent.classList.add('user'); + } else { + messageContent.innerHTML = `${message.sender}: ${message.text} ${message.time}`; + if (message.sender === "4NK") { + messageContent.classList.add('user'); + } + } + + messageElement.appendChild(messageContent); + messagesContainer.appendChild(messageElement); + }); } + + + this.scrollToBottom(messagesContainer); + } + + private toggleMembers(role: { members: { id: string | number; name: string; }[] }, roleElement: HTMLElement) { + let memberList = roleElement.querySelector('.member-list'); + if (memberList) { + (memberList as HTMLElement).style.display = (memberList as HTMLElement).style.display === 'none' ? 'block' : 'none'; + return; + } + + memberList = document.createElement('ul'); + memberList.className = 'member-list'; + + role.members.forEach(member => { + const memberItem = document.createElement('li'); + memberItem.textContent = member.name; + + memberItem.onclick = (event) => { + event.stopPropagation(); + this.loadMemberChat(member.id.toString()); + }; + + memberList.appendChild(memberItem); }); + + roleElement.appendChild(memberList); } - if (fileInput) { - fileInput.addEventListener('change', function (event: Event) { - const file = (event.target as HTMLInputElement).files?.[0]; - if (file) { - sendFile(file); - } + + // Toggle the list of Roles + private toggleRoles(group: Group, groupElement: HTMLElement) { + console.log('=== toggleRoles START ==='); + console.log('Group:', group.name); + console.log('Group roles:', group.roles); // Afficher tous les rôles disponibles + + let roleList = groupElement.querySelector('.role-list'); + console.log('Existing roleList:', roleList); + + if (roleList) { + const roleItems = roleList.querySelectorAll('.role-item'); + roleItems.forEach(roleItem => { + console.log('Processing roleItem:', roleItem.innerHTML); // Voir le contenu HTML complet + + let container = roleItem.querySelector('.role-item-container'); + if (!container) { + container = document.createElement('div'); + container.className = 'role-item-container'; + + // Créer un span pour le nom du rôle + const nameSpan = document.createElement('span'); + nameSpan.className = 'role-name'; + nameSpan.textContent = roleItem.textContent?.trim() || ''; + + container.appendChild(nameSpan); + roleItem.textContent = ''; + roleItem.appendChild(container); + } + + // Récupérer le nom du rôle + const roleName = roleItem.textContent?.trim(); + console.log('Role name from textContent:', roleName); + + // Alternative pour obtenir le nom du rôle + const roleNameAlt = container.querySelector('.role-name')?.textContent; + console.log('Role name from span:', roleNameAlt); + + if (!container.querySelector('.folder-icon')) { + const folderButton = document.createElement('span'); + folderButton.className = 'folder-icon'; + + folderButton.addEventListener('click', (event) => { + event.stopPropagation(); + console.log('Clicked role name:', roleName); + console.log('Available roles:', group.roles.map(r => r.name)); + + const role = group.roles.find(r => r.name === roleName); + if (role) { + console.log('Found role:', role); + } else { + console.error('Role not found. Name:', roleName); + console.error('Available roles:', group.roles); + } + }); + + container.appendChild(folderButton); + } + }); + + (roleList as HTMLElement).style.display = + (roleList as HTMLElement).style.display === 'none' ? 'block' : 'none'; + } + } + + + private loadGroupList(): void { + const groupList = document.getElementById('group-list'); + if (!groupList) return; + + groupsMock.forEach(group => { + const li = document.createElement('li'); + li.className = 'group-list-item'; + + // Create a flex container for the name and the icon + const container = document.createElement('div'); + container.className = 'group-item-container'; + + // Span for the process name + const nameSpan = document.createElement('span'); + nameSpan.textContent = group.name; + nameSpan.className = 'process-name'; + + // Add click event to show roles + nameSpan.addEventListener('click', (event) => { + event.stopPropagation(); + this.toggleRoles(group, li); + }); + + // Assemble the elements + container.appendChild(nameSpan); + li.appendChild(container); + + // Create and append the role list container + const roleList = document.createElement('ul'); + roleList.className = 'role-list'; + roleList.style.display = 'none'; + + // Add roles for this process + group.roles.forEach(role => { + const roleItem = document.createElement('li'); + roleItem.className = 'role-item'; + roleItem.textContent = role.name; + roleItem.onclick = (event) => { + event.stopPropagation(); + this.toggleMembers(role, roleItem); + }; + roleList.appendChild(roleItem); + }); + + li.appendChild(roleList); + groupList.appendChild(li); }); } - // Initialize notification listeners - const notificationBell = document.getElementById('notification-bell'); - const notificationBoard = document.getElementById('notification-board'); - - if (notificationBell && notificationBoard) { - notificationBell.onclick = () => { - notificationBoard.style.display = notificationBoard.style.display === 'block' ? 'none' : 'block'; + + // Function to manage the list of users + private toggleUserList() { + const userList = getCorrectDOM('userList'); + if (!userList) return; + + if (!(userList as HTMLElement).classList.contains('show')) { + (userList as HTMLElement).innerHTML = membersMock.map(member => ` +
+ ${member.avatar} +
+ ${member.name} + ${member.email} +
+
+ `).join(''); + } + (userList as HTMLElement).classList.toggle('show'); + } + + private switchUser(userId: string | number) { + const user = membersMock.find(member => member.id === userId); + if (!user) return; + currentUser = user; + this.updateCurrentUserDisplay(); + const userList = getCorrectDOM('userList') as HTMLElement; + userList?.classList.remove('show'); + } + + // Function to update the display of the current user + private updateCurrentUserDisplay() { + const userDisplay = getCorrectDOM('current-user') as HTMLElement; + if (userDisplay) { + userDisplay.innerHTML = ` +
+ ${currentUser.avatar} + ${currentUser.name} +
+ `; + } + } + // Generate an automatic response + private generateAutoReply(senderName: string): Message { + return { + id: Date.now(), + sender: senderName, + text: "OK...", + time: new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }), + type: 'text' as const }; } + + // Send a file + private sendFile(file: File) { + console.log('SendFile called with file:', file); + const reader = new FileReader(); + reader.onloadend = () => { + const fileData = reader.result; + const fileName = file.name; + console.log('File loaded:', fileName); + + if (this.selectedMemberId) { + messageStore.addMessage(this.selectedMemberId, { + id: Date.now(), + sender: "4NK", + fileName: fileName, + fileData: fileData, + time: new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }), + type: 'file' + }); + console.log('Message added to store'); + + this.messagesMock = messageStore.getMessages(); + this.loadMemberChat(this.selectedMemberId); + } + }; + reader.readAsDataURL(file); + } + + private initializeEventListeners() { + document.addEventListener('DOMContentLoaded', (): void => { + }); + + // Gestionnaire d'événements pour le chat + const sendBtn = this.shadowRoot?.querySelector('#send-button'); + if (sendBtn) { + sendBtn.addEventListener('click', this.sendMessage.bind(this)); + } + + const messageInput = this.shadowRoot?.querySelector('#message-input'); + if (messageInput) { + messageInput.addEventListener('keypress', (event: Event) => { + if ((event as KeyboardEvent).key === 'Enter') { + event.preventDefault(); + this.sendMessage(); + } + }); + } + + // Gestionnaire pour l'envoi de fichiers + const fileInput = this.shadowRoot?.querySelector('#file-input'); + if (fileInput) { + fileInput.addEventListener('change', (event: Event) => { + const file = (event.target as HTMLInputElement).files?.[0]; + if (file) { + this.sendFile(file); + } + }); + } + } + + connectedCallback() { + if (this.shadowRoot) { + this.shadowRoot.innerHTML = ` +
+
+
    +
    +
    + +
    +
    + `; + } + + this.messagesMock = messageStore.getMessages(); + if (this.messagesMock.length === 0) { + messageStore.setMessages(initialMessagesMock); + this.messagesMock = messageStore.getMessages(); + } + this.updateCurrentUserDisplay(); + this.initializeEventListeners(); + this.loadGroupList(); + } } -function saveMessagesToLocalStorage(messages: any[]) { - messageStore.setMessages(messages); - messagesMock = messageStore.getMessages(); -} +customElements.define('chat-element', ChatElement); +export { ChatElement }; + diff --git a/src/pages/signature/signature.ts b/src/pages/signature/signature.ts index 2d0fdd5..39e0802 100755 --- a/src/pages/signature/signature.ts +++ b/src/pages/signature/signature.ts @@ -518,7 +518,7 @@ class SignatureElement extends HTMLElement { const signButton = !isVierge ? ` ${totalSignatures > 0 && signedCount < totalSignatures && canSign ? ` ` : ''} ` : ''; @@ -595,7 +595,7 @@ class SignatureElement extends HTMLElement { document.signatures.filter((sig: DocumentSignature) => sig.signed).length < document.signatures.length && canSign ? ` ` : ''} ` : ''; @@ -1658,59 +1658,6 @@ class SignatureElement extends HTMLElement { }); }); } - - const addMembersBtn = document.getElementById('addMembersBtn'); - if (addMembersBtn) { - addMembersBtn.addEventListener('click', () => { - const selectedMembers: string[] = []; - - // Use this.allMembers instead of allMembers - const membersToSelect = this.allMembers.map(member => ` -
    - - -
    - `).join(''); - - // Create a modal for member selection - const modalContent = ` - - `; - - // Append the modal to the body - document.body.insertAdjacentHTML('beforeend', modalContent); - - // Add event for the confirmation button - const confirmBtn = document.getElementById('confirmSelectionBtn'); - if (confirmBtn) { - confirmBtn.addEventListener('click', () => { - // Retrieve selected members - const selectedCheckboxes = document.querySelectorAll('.modal input[type="checkbox"]:checked'); - selectedCheckboxes.forEach((checkbox: Element) => { - selectedMembers.push((checkbox as HTMLInputElement).value); - }); - - // Add selected members to the list - const membersList = document.getElementById('members-list'); - if (membersList) { - selectedMembers.forEach(memberId => { - const member = this.allMembers.find((m: {id: number, name: string, roleName: string}) => m.id === parseInt(memberId)); - if (member) { - membersList.insertAdjacentHTML('beforeend', `
    ${member.name} (${member.roleName})
    `); - } - }); - } - - // Close the modal - document.querySelector('.modal')?.remove(); - }); - } - }); - } }); // Gestionnaire d'événements pour le chat @@ -1719,15 +1666,15 @@ class SignatureElement extends HTMLElement { sendBtn.addEventListener('click', this.sendMessage.bind(this)); } - const messageInput = this.shadowRoot?.querySelector('#message-input'); - if (messageInput) { + const messageInput = this.shadowRoot?.querySelector('#message-input'); + if (messageInput) { messageInput.addEventListener('keypress', (event: Event) => { if ((event as KeyboardEvent).key === 'Enter') { event.preventDefault(); this.sendMessage(); } }); - } + } // Gestionnaire pour l'envoi de fichiers const fileInput = this.shadowRoot?.querySelector('#file-input'); diff --git a/src/router.ts b/src/router.ts index 4d7441f..07e90b4 100755 --- a/src/router.ts +++ b/src/router.ts @@ -69,8 +69,15 @@ async function handleLocation(path: string) { break; case 'chat': - const { initChat } = await import('./pages/chat/chat'); - initChat(); + const { ChatComponent } = await import('./pages/chat/chat-component'); + const chatContainer = document.querySelector('.group-list'); + if (chatContainer) { + if (!customElements.get('chat-component')) { + customElements.define('chat-component', ChatComponent); + } + const chatComponent = document.createElement('chat-component'); + chatContainer.appendChild(chatComponent); + } break; case 'signature':