diff --git a/app/MindWork AI Studio/Components/Settings/SettingsPanelDataSources.razor.cs b/app/MindWork AI Studio/Components/Settings/SettingsPanelDataSources.razor.cs index 415ed5e5..41daae93 100644 --- a/app/MindWork AI Studio/Components/Settings/SettingsPanelDataSources.razor.cs +++ b/app/MindWork AI Studio/Components/Settings/SettingsPanelDataSources.razor.cs @@ -228,6 +228,15 @@ public partial class SettingsPanelDataSources : SettingsPanelBase await this.DialogService.ShowAsync("Local File Data Source Information", localFileDialogParameters, DialogOptions.FULLSCREEN); break; + + case DataSourceLocalDirectory localDirectory: + var localDirectoryDialogParameters = new DialogParameters + { + { x => x.DataSource, localDirectory }, + }; + + await this.DialogService.ShowAsync("Local Directory Data Source Information", localDirectoryDialogParameters, DialogOptions.FULLSCREEN); + break; } } diff --git a/app/MindWork AI Studio/Dialogs/DataSourceLocalDirectoryInfoDialog.razor b/app/MindWork AI Studio/Dialogs/DataSourceLocalDirectoryInfoDialog.razor new file mode 100644 index 00000000..05932699 --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/DataSourceLocalDirectoryInfoDialog.razor @@ -0,0 +1,52 @@ + + + + + + @if (!this.IsDirectoryAvailable) + { + + The directory chosen for the data source does not exist anymore. Please edit the data source and correct the path. + + } + else + { + + The directory chosen for the data source exists. + + } + + + @if (this.IsCloudEmbedding) + { + + 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. + + } + else + { + + The embedding runs locally or in your organization. Your data is not sent to the cloud. + + } + + + + @if (this.directorySizeNumFiles > 100) + { + + For performance reasons, only the first 100 files are shown. The directory contains @this.NumberFilesInDirectory files in total. + + } + + + @if (this.IsOperationInProgress) + { + + } + + + Close + + \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/DataSourceLocalDirectoryInfoDialog.razor.cs b/app/MindWork AI Studio/Dialogs/DataSourceLocalDirectoryInfoDialog.razor.cs new file mode 100644 index 00000000..672a8bbd --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/DataSourceLocalDirectoryInfoDialog.razor.cs @@ -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 +} \ No newline at end of file