Implemented the local directory info dialog

This commit is contained in:
Thorsten Sommer 2025-01-23 13:54:40 +01:00
parent 6ac122bfd8
commit 7dcf7a1571
Signed by: tsommer
GPG Key ID: 371BBA77A02C0108
3 changed files with 161 additions and 0 deletions

View File

@ -228,6 +228,15 @@ public partial class SettingsPanelDataSources : SettingsPanelBase
await this.DialogService.ShowAsync<DataSourceLocalFileInfoDialog>("Local File Data Source Information", localFileDialogParameters, DialogOptions.FULLSCREEN);
break;
case DataSourceLocalDirectory localDirectory:
var localDirectoryDialogParameters = new DialogParameters<DataSourceLocalDirectoryInfoDialog>
{
{ x => x.DataSource, localDirectory },
};
await this.DialogService.ShowAsync<DataSourceLocalDirectoryInfoDialog>("Local Directory Data Source Information", localDirectoryDialogParameters, DialogOptions.FULLSCREEN);
break;
}
}

View File

@ -0,0 +1,52 @@
<MudDialog>
<DialogContent>
<TextInfoLine Icon="@Icons.Material.Filled.Tag" Label="Data source name" Value="@this.DataSource.Name" ClipboardTooltipSubject="the data source name"/>
<TextInfoLine Icon="@Icons.Material.Filled.FolderOpen" Label="Path" Value="@this.DataSource.Path" ClipboardTooltipSubject="this path"/>
@if (!this.IsDirectoryAvailable)
{
<MudJustifiedText Typo="Typo.body1" Color="Color.Error" Class="mb-3">
The directory chosen for the data source does not exist anymore. Please edit the data source and correct the path.
</MudJustifiedText>
}
else
{
<MudJustifiedText Typo="Typo.body1" Color="Color.Tertiary" Class="mb-3">
The directory chosen for the data source exists.
</MudJustifiedText>
}
<TextInfoLine Icon="@Icons.Material.Filled.Layers" Label="Embedding name" Value="@this.embeddingProvider.Name" ClipboardTooltipSubject="the embedding name"/>
@if (this.IsCloudEmbedding)
{
<MudJustifiedText Typo="Typo.body1" Color="Color.Error" Class="mb-3">
The embedding runs in the cloud. All your data from the folder '@this.DataSource.Path' and all its subdirectories
will be sent to the cloud.
</MudJustifiedText>
}
else
{
<MudJustifiedText Typo="Typo.body1" Color="Color.Tertiary" Class="mb-3">
The embedding runs locally or in your organization. Your data is not sent to the cloud.
</MudJustifiedText>
}
<TextInfoLine Icon="@Icons.Material.Filled.SquareFoot" Label="Number of files" Value="@this.NumberFilesInDirectory" ClipboardTooltipSubject="the number of files in the directory"/>
<TextInfoLines Label="Files list" MaxLines="14" Value="@this.directoryFiles.ToString()" ClipboardTooltipSubject="the files list"/>
@if (this.directorySizeNumFiles > 100)
{
<MudJustifiedText Typo="Typo.body1" Color="Color.Warning" Class="mb-3">
For performance reasons, only the first 100 files are shown. The directory contains @this.NumberFilesInDirectory files in total.
</MudJustifiedText>
}
<TextInfoLine Icon="@Icons.Material.Filled.SquareFoot" Label="Total directory size" Value="@this.directorySizeBytes.FileSize()" ClipboardTooltipSubject="the total directory size"/>
@if (this.IsOperationInProgress)
{
<MudProgressLinear Color="Color.Primary" Indeterminate="true" Class="mt-3 mb-3" />
}
</DialogContent>
<DialogActions>
<MudButton OnClick="@this.Close" Variant="Variant.Filled">Close</MudButton>
</DialogActions>
</MudDialog>

View File

@ -0,0 +1,100 @@
using System.Text;
using AIStudio.Settings;
using AIStudio.Settings.DataModel;
using Microsoft.AspNetCore.Components;
namespace AIStudio.Dialogs;
public partial class DataSourceLocalDirectoryInfoDialog : ComponentBase, IAsyncDisposable
{
[CascadingParameter]
private MudDialogInstance MudDialog { get; set; } = null!;
[Parameter]
public DataSourceLocalDirectory DataSource { get; set; }
[Inject]
private SettingsManager SettingsManager { get; init; } = null!;
#region Overrides of ComponentBase
protected override async Task OnInitializedAsync()
{
this.embeddingProvider = this.SettingsManager.ConfigurationData.EmbeddingProviders.FirstOrDefault(x => x.Id == this.DataSource.EmbeddingId);
this.directoryInfo = new DirectoryInfo(this.DataSource.Path);
if (this.directoryInfo.Exists)
this.directorySizeTask = this.directoryInfo.DetermineContentSize(this.UpdateDirectorySize, this.UpdateDirectoryFiles, this.UpdateFileList, MAX_FILES_TO_SHOW, this.DirectoryOperationDone, this.cts.Token);
await base.OnInitializedAsync();
}
#endregion
private const int MAX_FILES_TO_SHOW = 100;
private readonly CancellationTokenSource cts = new();
private EmbeddingProvider embeddingProvider;
private DirectoryInfo directoryInfo = null!;
private long directorySizeBytes;
private long directorySizeNumFiles;
private readonly StringBuilder directoryFiles = new();
private Task directorySizeTask = Task.CompletedTask;
private bool IsOperationInProgress { get; set; } = true;
private bool IsCloudEmbedding => !this.embeddingProvider.IsSelfHosted;
private bool IsDirectoryAvailable => this.directoryInfo.Exists;
private void UpdateFileList(string file)
{
this.directoryFiles.Append("- ");
this.directoryFiles.AppendLine(file);
this.InvokeAsync(this.StateHasChanged);
}
private void UpdateDirectorySize(long size)
{
this.directorySizeBytes = size;
this.InvokeAsync(this.StateHasChanged);
}
private void UpdateDirectoryFiles(long numFiles) => this.directorySizeNumFiles = numFiles;
private void DirectoryOperationDone()
{
this.IsOperationInProgress = false;
this.InvokeAsync(this.StateHasChanged);
}
private string NumberFilesInDirectory => $"{this.directorySizeNumFiles:###,###,###,###}";
private void Close()
{
this.cts.Cancel();
this.MudDialog.Close();
}
#region Implementation of IDisposable
public async ValueTask DisposeAsync()
{
try
{
await this.cts.CancelAsync();
await this.directorySizeTask;
this.cts.Dispose();
}
catch
{
// ignored
}
}
#endregion
}