|
|
|
@@ -28,53 +28,63 @@ |
|
|
|
<div class="sidebar-section"> |
|
|
|
@if (!IsCollapsed) |
|
|
|
{ |
|
|
|
<button class="new-chat-button" @onclick="OnNewChat" aria-label="Nouvelle discussion"> |
|
|
|
<button class="new-chat-button" @onclick="OnNewChat" aria-label="Nouvelle activité"> |
|
|
|
<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 xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 16 16"> |
|
|
|
<path d="M6 12.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5M3 8.062C3 6.76 4.235 5.765 5.53 5.886a26.6 26.6 0 0 0 4.94 0C11.765 5.765 13 6.76 13 8.062v1.157a.93.93 0 0 1-.765.935c-.845.147-2.34.346-4.235.346s-3.39-.2-4.235-.346A.93.93 0 0 1 3 9.219zm4.542-.827a.25.25 0 0 0-.217.068l-.92.9a25 25 0 0 1-1.871-.183.25.25 0 0 0-.068.495c.55.076 1.232.149 2.02.193a.25.25 0 0 0 .189-.071l.754-.736.847 1.71a.25.25 0 0 0 .404.062l.932-.97a25 25 0 0 0 1.922-.188.25.25 0 0 0-.068-.495c-.538.074-1.207.145-1.98.189a.25.25 0 0 0-.166.076l-.754.785-.842-1.7a.25.25 0 0 0-.182-.135" /> |
|
|
|
<path d="M8.5 1.866a1 1 0 1 0-1 0V3h-2A4.5 4.5 0 0 0 1 7.5V8a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1v1a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-1a1 1 0 0 0 1-1V9a1 1 0 0 0-1-1v-.5A4.5 4.5 0 0 0 10.5 3h-2zM14 7.5V13a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V7.5A3.5 3.5 0 0 1 5.5 4h5A3.5 3.5 0 0 1 14 7.5" /> |
|
|
|
</svg> |
|
|
|
|
|
|
|
</span> |
|
|
|
<span>Nouvelle discussion</span> |
|
|
|
<span>Nouvelle activité</span> |
|
|
|
</button> |
|
|
|
|
|
|
|
|
|
|
|
<h3 class="section-title"> Conversations</h3> |
|
|
|
|
|
|
|
<div class="conversations-section"> |
|
|
|
|
|
|
|
|
|
|
|
@if (IsLoadingChat) |
|
|
|
{ |
|
|
|
<div class="loading">Chargement...</div> |
|
|
|
} |
|
|
|
else if (ChatConversations.Any()) |
|
|
|
{ |
|
|
|
<div class="conversations-list"> |
|
|
|
@foreach (var conversation in ChatConversations) |
|
|
|
{ |
|
|
|
<div class="conversation-item @(CurrentConversationId == conversation.Id ? "active" : "")" |
|
|
|
@onclick="() => OnSelectConversation(conversation.Id, 1)"> |
|
|
|
<span class="conversation-title"> |
|
|
|
@if (!string.IsNullOrEmpty(conversation.Title)) |
|
|
|
{ |
|
|
|
@conversation.Title |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
@($"Conversation du {conversation.Date:dd/MM/yyyy}") |
|
|
|
} |
|
|
|
</span> |
|
|
|
</div> |
|
|
|
} |
|
|
|
</div> |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
<div class="empty-state">Aucune conversation</div> |
|
|
|
} |
|
|
|
</div> |
|
|
|
<button class="section-title-button" @onclick="ToggleChatSection"> |
|
|
|
<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>Conversations</span> |
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" |
|
|
|
class="chevron @(IsChatSectionOpen ? "open" : "")" viewBox="0 0 16 16"> |
|
|
|
<path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708" /> |
|
|
|
</svg> |
|
|
|
</button> |
|
|
|
|
|
|
|
@if (IsChatSectionOpen) |
|
|
|
{ |
|
|
|
<div class="conversations-section"> |
|
|
|
@if (IsLoadingChat) |
|
|
|
{ |
|
|
|
<div class="loading">Chargement...</div> |
|
|
|
} |
|
|
|
else if (ChatConversations.Any()) |
|
|
|
{ |
|
|
|
<div class="conversations-list"> |
|
|
|
@foreach (var conversation in ChatConversations) |
|
|
|
{ |
|
|
|
<div class="conversation-item @(CurrentConversationId == conversation.Id ? "active" : "")" |
|
|
|
@onclick="() => OnSelectConversation(conversation.Id, 1)"> |
|
|
|
<span class="conversation-title"> |
|
|
|
@if (!string.IsNullOrEmpty(conversation.Title)) |
|
|
|
{ |
|
|
|
@conversation.Title |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
@($"Conversation du {conversation.Date:dd/MM/yyyy}") |
|
|
|
} |
|
|
|
</span> |
|
|
|
</div> |
|
|
|
} |
|
|
|
</div> |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
<div class="empty-state">Aucune conversation</div> |
|
|
|
} |
|
|
|
</div> |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
@@ -93,45 +103,51 @@ |
|
|
|
<div class="sidebar-section"> |
|
|
|
@if (!IsCollapsed) |
|
|
|
{ |
|
|
|
<h3 class="section-title"> |
|
|
|
<button class="section-title-button" @onclick="ToggleRagSection"> |
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-folder" viewBox="0 0 16 16"> |
|
|
|
<path d="M.54 3.87.5 3a2 2 0 0 1 2-2h3.672a2 2 0 0 1 1.414.586l.828.828A2 2 0 0 0 9.828 3h3.982a2 2 0 0 1 1.992 2.181l-.637 7A2 2 0 0 1 13.174 14H2.826a2 2 0 0 1-1.991-1.819l-.637-7a2 2 0 0 1 .342-1.31zM2.19 4a1 1 0 0 0-.996 1.09l.637 7a1 1 0 0 0 .995.91h10.348a1 1 0 0 0 .995-.91l.637-7A1 1 0 0 0 13.81 4zm4.69-1.707A1 1 0 0 0 6.172 2H2.5a1 1 0 0 0-1 .981l.006.139q.323-.119.684-.12h5.396z" /> |
|
|
|
</svg> |
|
|
|
RAG |
|
|
|
</h3> |
|
|
|
|
|
|
|
<div class="conversations-section"> |
|
|
|
|
|
|
|
@if (IsLoadingRag) |
|
|
|
{ |
|
|
|
<div class="loading">Chargement...</div> |
|
|
|
} |
|
|
|
else if (RagConversations.Any()) |
|
|
|
{ |
|
|
|
<div class="conversations-list"> |
|
|
|
@foreach (var conversation in RagConversations) |
|
|
|
{ |
|
|
|
<div class="conversation-item @(CurrentConversationId == conversation.Id ? "active" : "")" |
|
|
|
@onclick="() => OnSelectConversation(conversation.Id, 2)"> |
|
|
|
<span class="conversation-title"> |
|
|
|
@if (!string.IsNullOrEmpty(conversation.Title)) |
|
|
|
{ |
|
|
|
@conversation.Title |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
@($"RAG du {conversation.Date:dd/MM/yyyy}") |
|
|
|
} |
|
|
|
</span> |
|
|
|
</div> |
|
|
|
} |
|
|
|
</div> |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
<div class="empty-state">Aucune conversation RAG</div> |
|
|
|
} |
|
|
|
</div> |
|
|
|
<span>RAG</span> |
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" |
|
|
|
class="chevron @(IsRagSectionOpen ? "open" : "")" viewBox="0 0 16 16"> |
|
|
|
<path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708" /> |
|
|
|
</svg> |
|
|
|
</button> |
|
|
|
|
|
|
|
@if (IsRagSectionOpen) |
|
|
|
{ |
|
|
|
<div class="conversations-section"> |
|
|
|
@if (IsLoadingRag) |
|
|
|
{ |
|
|
|
<div class="loading">Chargement...</div> |
|
|
|
} |
|
|
|
else if (RagConversations.Any()) |
|
|
|
{ |
|
|
|
<div class="conversations-list"> |
|
|
|
@foreach (var conversation in RagConversations) |
|
|
|
{ |
|
|
|
<div class="conversation-item @(CurrentConversationId == conversation.Id ? "active" : "")" |
|
|
|
@onclick="() => OnSelectConversation(conversation.Id, 2)"> |
|
|
|
<span class="conversation-title"> |
|
|
|
@if (!string.IsNullOrEmpty(conversation.Title)) |
|
|
|
{ |
|
|
|
@conversation.Title |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
@($"RAG du {conversation.Date:dd/MM/yyyy}") |
|
|
|
} |
|
|
|
</span> |
|
|
|
</div> |
|
|
|
} |
|
|
|
</div> |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
<div class="empty-state">Aucune conversation RAG</div> |
|
|
|
} |
|
|
|
</div> |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
@@ -146,6 +162,72 @@ |
|
|
|
} |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="sidebar-section"> |
|
|
|
@if (!IsCollapsed) |
|
|
|
{ |
|
|
|
<button class="section-title-button" @onclick="ToggleAuditSection"> |
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-folder" viewBox="0 0 16 16"> |
|
|
|
<path d="M.54 3.87.5 3a2 2 0 0 1 2-2h3.672a2 2 0 0 1 1.414.586l.828.828A2 2 0 0 0 9.828 3h3.982a2 2 0 0 1 1.992 2.181l-.637 7A2 2 0 0 1 13.174 14H2.826a2 2 0 0 1-1.991-1.819l-.637-7a2 2 0 0 1 .342-1.31zM2.19 4a1 1 0 0 0-.996 1.09l.637 7a1 1 0 0 0 .995.91h10.348a1 1 0 0 0 .995-.91l.637-7A1 1 0 0 0 13.81 4zm4.69-1.707A1 1 0 0 0 6.172 2H2.5a1 1 0 0 0-1 .981l.006.139q.323-.119.684-.12h5.396z" /> |
|
|
|
</svg> |
|
|
|
<span>AUDIT</span> |
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" |
|
|
|
class="chevron @(IsAuditSectionOpen ? "open" : "")" viewBox="0 0 16 16"> |
|
|
|
<path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708" /> |
|
|
|
</svg> |
|
|
|
</button> |
|
|
|
|
|
|
|
@if (IsAuditSectionOpen) |
|
|
|
{ |
|
|
|
<div class="conversations-section"> |
|
|
|
@if (IsLoadingAudit) |
|
|
|
{ |
|
|
|
<div class="loading">Chargement...</div> |
|
|
|
} |
|
|
|
else if (AuditConversations.Any()) |
|
|
|
{ |
|
|
|
<div class="conversations-list"> |
|
|
|
@foreach (var conversation in AuditConversations) |
|
|
|
{ |
|
|
|
<div class="conversation-item @(CurrentConversationId == conversation.Id ? "active" : "")" |
|
|
|
@onclick="() => OnSelectConversation(conversation.Id, 3)"> |
|
|
|
<span class="conversation-title"> |
|
|
|
@if (!string.IsNullOrEmpty(conversation.Title)) |
|
|
|
{ |
|
|
|
@conversation.Title |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
@($"AUDIT du {conversation.Date:dd/MM/yyyy}") |
|
|
|
} |
|
|
|
</span> |
|
|
|
</div> |
|
|
|
} |
|
|
|
</div> |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
<div class="empty-state">Aucune conversation AUDIT</div> |
|
|
|
} |
|
|
|
</div> |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
<button class="sidebar-icon-button" aria-label="AUDIT"> |
|
|
|
<span class="icon"> |
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-folder" viewBox="0 0 16 16"> |
|
|
|
<path d="M.54 3.87.5 3a2 2 0 0 1 2-2h3.672a2 2 0 0 1 1.414.586l.828.828A2 2 0 0 0 9.828 3h3.982a2 2 0 0 1 1.992 2.181l-.637 7A2 2 0 0 1 13.174 14H2.826a2 2 0 0 1-1.991-1.819l-.637-7a2 2 0 0 1 .342-1.31zM2.19 4a1 1 0 0 0-.996 1.09l.637 7a1 1 0 0 0 .995.91h10.348a1 1 0 0 0 .995-.91l.637-7A1 1 0 0 0 13.81 4zm4.69-1.707A1 1 0 0 0 6.172 2H2.5a1 1 0 0 0-1 .981l.006.139q.323-.119.684-.12h5.396z" /> |
|
|
|
</svg> |
|
|
|
|
|
|
|
</span> |
|
|
|
</button> |
|
|
|
} |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
<script> |
|
|
|
@@ -158,11 +240,17 @@ |
|
|
|
private bool IsCollapsed = false; |
|
|
|
private string CurrentConversationId = ""; |
|
|
|
|
|
|
|
private bool IsChatSectionOpen = true; |
|
|
|
private bool IsRagSectionOpen = true; |
|
|
|
private bool IsAuditSectionOpen = true; |
|
|
|
|
|
|
|
private List<ConversationDto> ChatConversations { get; set; } = new(); |
|
|
|
private List<ConversationDto> RagConversations { get; set; } = new(); |
|
|
|
private List<ConversationDto> AuditConversations { get; set; } = new(); |
|
|
|
|
|
|
|
private bool IsLoadingChat = false; |
|
|
|
private bool IsLoadingRag = false; |
|
|
|
private bool IsLoadingAudit = false; |
|
|
|
|
|
|
|
protected override async Task OnInitializedAsync() |
|
|
|
{ |
|
|
|
@@ -179,6 +267,8 @@ |
|
|
|
|
|
|
|
await LoadChatConversations(); |
|
|
|
await LoadRagConversations(); |
|
|
|
await LoadAuditConversations(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
protected override async Task OnAfterRenderAsync(bool firstRender) |
|
|
|
@@ -207,6 +297,21 @@ |
|
|
|
IsCollapsed = !IsCollapsed; |
|
|
|
} |
|
|
|
|
|
|
|
private void ToggleChatSection() |
|
|
|
{ |
|
|
|
IsChatSectionOpen = !IsChatSectionOpen; |
|
|
|
} |
|
|
|
|
|
|
|
private void ToggleRagSection() |
|
|
|
{ |
|
|
|
IsRagSectionOpen = !IsRagSectionOpen; |
|
|
|
} |
|
|
|
|
|
|
|
private void ToggleAuditSection() |
|
|
|
{ |
|
|
|
IsAuditSectionOpen = !IsAuditSectionOpen; |
|
|
|
} |
|
|
|
|
|
|
|
private void UpdateCurrentConversationFromUrl() |
|
|
|
{ |
|
|
|
var uri = new Uri(Navigation.Uri); |
|
|
|
@@ -309,6 +414,44 @@ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private async Task LoadAuditConversations() |
|
|
|
{ |
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(AuthService.ID)) |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
IsLoadingAudit = true; |
|
|
|
StateHasChanged(); |
|
|
|
|
|
|
|
try |
|
|
|
{ |
|
|
|
var url = $"/api/ChatRoom/conversations/{AuthService.ID}/3"; |
|
|
|
|
|
|
|
var allConversations = await Http.GetFromJsonAsync<List<ConversationDto>>(url) ?? new(); |
|
|
|
|
|
|
|
|
|
|
|
// Filtrer uniquement celles avec TypeConv = "AUDIT" |
|
|
|
AuditConversations = allConversations |
|
|
|
.Where(c => c.TypeConv == "AUDIT") |
|
|
|
.OrderByDescending(c => c.Messages.Any() |
|
|
|
? c.Messages.Max(m => m.CreatedAt) |
|
|
|
: c.Date) |
|
|
|
.ToList(); |
|
|
|
|
|
|
|
} |
|
|
|
catch (Exception ex) |
|
|
|
{ |
|
|
|
AuditConversations = new(); |
|
|
|
} |
|
|
|
finally |
|
|
|
{ |
|
|
|
IsLoadingAudit = false; |
|
|
|
StateHasChanged(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void OnNewChat() |
|
|
|
{ |
|
|
|
Navigation.NavigateTo("chatroom_base/0"); |