| @@ -28,19 +28,22 @@ | |||
| <div class="sidebar-section"> | |||
| @if (!IsCollapsed) | |||
| { | |||
| <button class="new-chat-button" @onclick="OnNewChat" aria-label="Nouvelle discussion"> | |||
| <span class="icon"> | |||
| <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chat-dots" viewBox="0 0 16 16"> | |||
| <path d="M5 8a1 1 0 1 1-2 0 1 1 0 0 1 2 0m4 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0m3 1a1 1 0 1 0 0-2 1 1 0 0 0 0 2" /> | |||
| <path d="m2.165 15.803.02-.004c1.83-.363 2.948-.842 3.468-1.105A9 9 0 0 0 8 15c4.418 0 8-3.134 8-7s-3.582-7-8-7-8 3.134-8 7c0 1.76.743 3.37 1.97 4.6a10.4 10.4 0 0 1-.524 2.318l-.003.011a11 11 0 0 1-.244.637c-.079.186.074.394.273.362a22 22 0 0 0 .693-.125m.8-3.108a1 1 0 0 0-.287-.801C1.618 10.83 1 9.468 1 8c0-3.192 3.004-6 7-6s7 2.808 7 6-3.004 6-7 6a8 8 0 0 1-2.088-.272 1 1 0 0 0-.711.074c-.387.196-1.24.57-2.634.893a11 11 0 0 0 .398-2" /> | |||
| </svg> | |||
| </span> | |||
| <span>Nouvelle discussion</span> | |||
| </button> | |||
| <h3 class="section-title"> Conversations</h3> | |||
| <div class="conversations-section"> | |||
| <button class="new-chat-button" @onclick="OnNewChat" aria-label="Nouvelle conversation"> | |||
| <span class="icon"> | |||
| <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chat-dots" viewBox="0 0 16 16"> | |||
| <path d="M5 8a1 1 0 1 1-2 0 1 1 0 0 1 2 0m4 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0m3 1a1 1 0 1 0 0-2 1 1 0 0 0 0 2" /> | |||
| <path d="m2.165 15.803.02-.004c1.83-.363 2.948-.842 3.468-1.105A9 9 0 0 0 8 15c4.418 0 8-3.134 8-7s-3.582-7-8-7-8 3.134-8 7c0 1.76.743 3.37 1.97 4.6a10.4 10.4 0 0 1-.524 2.318l-.003.011a11 11 0 0 1-.244.637c-.079.186.074.394.273.362a22 22 0 0 0 .693-.125m.8-3.108a1 1 0 0 0-.287-.801C1.618 10.83 1 9.468 1 8c0-3.192 3.004-6 7-6s7 2.808 7 6-3.004 6-7 6a8 8 0 0 1-2.088-.272 1 1 0 0 0-.711.074c-.387.196-1.24.57-2.634.893a11 11 0 0 0 .398-2" /> | |||
| </svg> | |||
| </span> | |||
| <span>Nouvelle conversation</span> | |||
| </button> | |||
| @if (IsLoadingChat) | |||
| { | |||
| @@ -98,15 +101,6 @@ | |||
| </h3> | |||
| <div class="conversations-section"> | |||
| <button class="new-chat-button" @onclick="OnNewRagChat" aria-label="Nouveau RAG"> | |||
| <span class="icon"> | |||
| <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chat-dots" viewBox="0 0 16 16"> | |||
| <path d="M5 8a1 1 0 1 1-2 0 1 1 0 0 1 2 0m4 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0m3 1a1 1 0 1 0 0-2 1 1 0 0 0 0 2" /> | |||
| <path d="m2.165 15.803.02-.004c1.83-.363 2.948-.842 3.468-1.105A9 9 0 0 0 8 15c4.418 0 8-3.134 8-7s-3.582-7-8-7-8 3.134-8 7c0 1.76.743 3.37 1.97 4.6a10.4 10.4 0 0 1-.524 2.318l-.003.011a11 11 0 0 1-.244.637c-.079.186.074.394.273.362a22 22 0 0 0 .693-.125m.8-3.108a1 1 0 0 0-.287-.801C1.618 10.83 1 9.468 1 8c0-3.192 3.004-6 7-6s7 2.808 7 6-3.004 6-7 6a8 8 0 0 1-2.088-.272 1 1 0 0 0-.711.074c-.387.196-1.24.57-2.634.893a11 11 0 0 0 .398-2" /> | |||
| </svg> | |||
| </span> | |||
| <span>Nouveau RAG</span> | |||
| </button> | |||
| @if (IsLoadingRag) | |||
| { | |||
| @@ -1,6 +1,27 @@ | |||
| @page "/chatroom_base/{typellm:int}" | |||
| @page "/chatroom_base/{typellm:int}/{conversationid}" | |||
| <script> | |||
| window.autoResizeTextarea = function (element) { | |||
| if (!element) return; | |||
| element.style.height = 'auto'; | |||
| element.style.height = Math.min(element.scrollHeight, 200) + 'px'; | |||
| }; | |||
| window.setupTextareaAutoResize = function (textareaId) { | |||
| const textarea = document.getElementById(textareaId); | |||
| if (!textarea) return; | |||
| textarea.addEventListener('input', function () { | |||
| window.autoResizeTextarea(this); | |||
| }); | |||
| // Initial resize | |||
| window.autoResizeTextarea(textarea); | |||
| }; | |||
| </script> | |||
| @if (TypeLLM == 0) | |||
| { | |||
| <!-- Vue Home --> | |||
| @@ -42,8 +63,9 @@ | |||
| } | |||
| <div class="input-wrapper @(UploadedDocuments.Any() ? "has-files" : "")"> | |||
| <textarea @bind="CurrentInput" | |||
| @bind:event="oninput" | |||
| <textarea id="homeTextarea" | |||
| @bind="CurrentInput" | |||
| @oninput="OnHomeTextareaInput" | |||
| placeholder="Nouvelle conversation..." | |||
| rows="1" | |||
| disabled="@isDisabled"></textarea> | |||
| @@ -305,8 +327,9 @@ else | |||
| <!-- Input wrapper --> | |||
| <div class="input-wrapper @(UploadedDocuments.Any() ? "has-files" : "")"> | |||
| <textarea @bind="CurrentInput" | |||
| @bind:event="oninput" | |||
| <textarea id="chatroomTextarea" | |||
| @bind="CurrentInput" | |||
| @oninput="OnChatroomTextareaInput" | |||
| @onkeydown="HandleKeyPress" | |||
| placeholder="Nouvelle conversation..." | |||
| rows="1"></textarea> | |||
| @@ -234,7 +234,7 @@ namespace ReAct_PME.WebUI.Pages.ChatRoom | |||
| { | |||
| if (!RagDomains.Any()) | |||
| await LoadRagDomains(); | |||
| domain = RagDomains.Any() ? RagDomains[0] : ""; | |||
| domain = !string.IsNullOrEmpty(SelectedDomain) ? SelectedDomain : (RagDomains.Any() ? RagDomains[0] : ""); | |||
| } | |||
| var payload = new SendMessageRequest | |||
| @@ -406,10 +406,17 @@ namespace ReAct_PME.WebUI.Pages.ChatRoom | |||
| return $"{len:0.##} {sizes[order]}"; | |||
| } | |||
| // Méthodes spécifiques à la vue Home | |||
| private void SelectAgent(int agentId) | |||
| private async Task SelectAgent(int agentId) | |||
| { | |||
| SelectedAgentType = agentId; | |||
| if (agentId == 2 && !RagDomains.Any()) | |||
| { | |||
| await LoadRagDomains(); | |||
| if (RagDomains.Any()) | |||
| SelectedDomain = RagDomains[0]; | |||
| } | |||
| StateHasChanged(); | |||
| } | |||
| @@ -417,5 +424,38 @@ namespace ReAct_PME.WebUI.Pages.ChatRoom | |||
| { | |||
| await UploadDocuments(e); | |||
| } | |||
| private async Task OnHomeTextareaInput() | |||
| { | |||
| await JSRuntime.InvokeVoidAsync("autoResizeTextarea", | |||
| await JSRuntime.InvokeAsync<object>("document.getElementById", "homeTextarea")); | |||
| } | |||
| private async Task OnChatroomTextareaInput() | |||
| { | |||
| await JSRuntime.InvokeVoidAsync("autoResizeTextarea", | |||
| await JSRuntime.InvokeAsync<object>("document.getElementById", "chatroomTextarea")); | |||
| } | |||
| protected override async Task OnAfterRenderAsync(bool firstRender) | |||
| { | |||
| if (firstRender) | |||
| { | |||
| try | |||
| { | |||
| if (TypeLLM == 0) | |||
| { | |||
| await JSRuntime.InvokeVoidAsync("setupTextareaAutoResize", "homeTextarea"); | |||
| } | |||
| else | |||
| { | |||
| await JSRuntime.InvokeVoidAsync("setupTextareaAutoResize", "chatroomTextarea"); | |||
| } | |||
| } | |||
| catch | |||
| { | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -244,8 +244,27 @@ | |||
| max-height: 200px; | |||
| line-height: 1.5; | |||
| padding: 0; | |||
| overflow-y: auto; | |||
| transition: height 0.1s ease; | |||
| } | |||
| .input-wrapper textarea::-webkit-scrollbar { | |||
| width: 4px; | |||
| } | |||
| .input-wrapper textarea::-webkit-scrollbar-track { | |||
| background: transparent; | |||
| } | |||
| .input-wrapper textarea::-webkit-scrollbar-thumb { | |||
| background: #d1d5db; | |||
| border-radius: 2px; | |||
| } | |||
| .input-wrapper textarea::-webkit-scrollbar-thumb:hover { | |||
| background: #9ca3af; | |||
| } | |||
| .input-wrapper textarea::placeholder { | |||
| color: #9ca3af; | |||
| } | |||
| @@ -544,7 +563,7 @@ | |||
| .bubble { | |||
| padding: 1rem 1.25rem; | |||
| border-radius: 16px; | |||
| font-size: 1rem; | |||
| font-size: 0.85rem; | |||
| line-height: 1.6; | |||
| word-wrap: break-word; | |||
| white-space: pre-wrap; | |||