Enhance document upload and sidebar functionality

- Updated `Sidebar2` in `MainLayout.razor` for SQL Vector Search.
- Improved document upload interface in `Documents.razor` with icons and tooltips.
- Adjusted layout to include Document ID input and changed checkbox to `CheckboxInput`.
- Added `documentId` property for handling document uploads.
- Enhanced `SelectableDocument` class with `ContentType` property for better document info.
This commit is contained in:
Marco Minerva
2025-02-14 18:01:59 +01:00
parent 83e8f8ff23
commit f9a2bf0bf9
2 changed files with 32 additions and 7 deletions
@@ -7,8 +7,8 @@
<SidebarSection> <SidebarSection>
<Sidebar2 Href="/" <Sidebar2 Href="/"
IconName="IconName.BookHalf" IconName="IconName.Search"
Title="Vector Search" Title="SQL Vector Search"
DataProvider="Sidebar2DataProvider" DataProvider="Sidebar2DataProvider"
WidthUnit="Unit.Px" /> WidthUnit="Unit.Px" />
</SidebarSection> </SidebarSection>
@@ -10,11 +10,14 @@
<PageTitle>Documents</PageTitle> <PageTitle>Documents</PageTitle>
<h2 class="mb-4">Upload new document</h2> <h2 class="mb-4">
<Icon Name="IconName.Upload" class="me-2" />
Upload new document
</h2>
<EditForm Model="@this" OnValidSubmit="HandleValidSubmit"> <EditForm Model="@this" OnValidSubmit="HandleValidSubmit">
<div class="row"> <div class="row">
<div class="col-md-10 col-sm-9 col-10"> <div class="col-md-5 col-sm-4 col-5">
<div class="input-group"> <div class="input-group">
<span class="input-group-text"> <span class="input-group-text">
<Tooltip Title="PDF, DOCX, TXT and MD files are supported" Color="TooltipColor.Primary" Placement="TooltipPlacement.Bottom"> <Tooltip Title="PDF, DOCX, TXT and MD files are supported" Color="TooltipColor.Primary" Placement="TooltipPlacement.Bottom">
@@ -24,6 +27,17 @@
<InputFile class="form-control" OnChange="HandleFileSelected" /> <InputFile class="form-control" OnChange="HandleFileSelected" />
</div> </div>
</div> </div>
<div class="col-md-5 col-sm-5 col-5">
<div class="input-group">
<span class="input-group-text">
<Tooltip Title="The unique identifier (GUID) of the document. If not provided, a new one will be generated. If you specify an existing Document ID, the corresponding document will be overwritten." Color="TooltipColor.Primary" Placement="TooltipPlacement.Bottom">
<Icon Class="d-flex text-body-secondary me-2" Name="IconName.InfoCircle"></Icon>
</Tooltip>
Document ID
</span>
<TextInput Placeholder="Enter a valid GUID" @bind-Value="documentId" />
</div>
</div>
<div class="col-md-2 col-sm-3 col-2"> <div class="col-md-2 col-sm-3 col-2">
<div class="d-grid gap-2"> <div class="d-grid gap-2">
<Button @ref="uploadButton" Type="ButtonType.Submit" Color="ButtonColor.Primary" To="#"><Icon Name="IconName.Upload" /><span class="d-none d-lg-inline ps-3">Upload</span></Button> <Button @ref="uploadButton" Type="ButtonType.Submit" Color="ButtonColor.Primary" To="#"><Icon Name="IconName.Upload" /><span class="d-none d-lg-inline ps-3">Upload</span></Button>
@@ -34,13 +48,18 @@
@if (documents.Count > 0) @if (documents.Count > 0)
{ {
<h2 class="mt-4">Available documents</h2> <h2 class="mt-4">
<Icon Name="IconName.Files" class="me-2" />
Available documents
</h2>
<table class="table table-bordered table-striped table-hover"> <table class="table table-bordered table-striped table-hover">
<thead> <thead>
<tr> <tr>
<th></th> <th></th>
<th>Id</th>
<th>Name</th> <th>Name</th>
<th>Content type</th>
<th>Number of chunks</th> <th>Number of chunks</th>
<th>Creation date</th> <th>Creation date</th>
</tr> </tr>
@@ -50,9 +69,11 @@
{ {
<tr> <tr>
<td> <td>
<InputCheckbox class="form-check-input" @bind-Value="document.IsSelected" @onchange="StateHasChanged" /> <CheckboxInput @bind-Value="document.IsSelected" @onchange="StateHasChanged" />
</td> </td>
<td>@document.Id</td>
<td>@document.Name</td> <td>@document.Name</td>
<td>@document.ContentType</td>
<td>@document.ChunkCount</td> <td>@document.ChunkCount</td>
<td>@document.LocalCreationDateString</td> <td>@document.LocalCreationDateString</td>
</tr> </tr>
@@ -82,6 +103,8 @@
[SupplyParameterFromForm] [SupplyParameterFromForm]
public IBrowserFile? File { get; set; } public IBrowserFile? File { get; set; }
public string? documentId { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender) protected override async Task OnAfterRenderAsync(bool firstRender)
{ {
if (!firstRender) if (!firstRender)
@@ -127,7 +150,7 @@
await using var inputStream = File.OpenReadStream(20 * 1024 * 1024); // 20 MB await using var inputStream = File.OpenReadStream(20 * 1024 * 1024); // 20 MB
await using var stream = await inputStream.GetMemoryStreamAsync(); await using var stream = await inputStream.GetMemoryStreamAsync();
await vectorSearchService.ImportAsync(stream, File.Name, MimeUtility.GetMimeMapping(File.Name), null); await vectorSearchService.ImportAsync(stream, File.Name, MimeUtility.GetMimeMapping(File.Name), Guid.Parse(documentId));
CreateToastMessage(ToastType.Success, "Upload document", $"The document {File.Name} has been successfully uploaded and indexed.", await GetLocalDateTimeStringAsync(DateTimeOffset.UtcNow)); CreateToastMessage(ToastType.Success, "Upload document", $"The document {File.Name} has been successfully uploaded and indexed.", await GetLocalDateTimeStringAsync(DateTimeOffset.UtcNow));
@@ -195,6 +218,8 @@
{ {
public bool IsSelected { get; set; } public bool IsSelected { get; set; }
public string ContentType => MimeUtility.GetMimeMapping(Name);
public string LocalCreationDateString { get; set; } = string.Empty; public string LocalCreationDateString { get; set; } = string.Empty;
} }
} }