mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-10-18 10:39:07 +00:00
Added backups of all data, restorable on another computer (#1008)
Co-authored-by: Thorsten Sommer <SommerEngineering@users.noreply.github.com>
This commit is contained in:
1 parent
ab45580473
commit
936043319c
144 files changed
+10417
-424
No files matched your search
@@ -58,6 +58,9 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan
|
||||
[Inject]
|
||||
private DataSourceEmbeddingService DataSourceEmbeddingService { get; init; } = null!;
|
||||
|
||||
[Inject]
|
||||
private DataRestoreService DataRestoreService { get; init; } = null!;
|
||||
|
||||
[Inject]
|
||||
private CircuitStateService CircuitState { get; init; } = null!;
|
||||
|
||||
@@ -82,6 +85,7 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan
|
||||
private bool settingsWriteProtectionWarningShown;
|
||||
private readonly SemaphoreSlim mandatoryInfoDialogSemaphore = new(1, 1);
|
||||
private readonly SemaphoreSlim promptInjectionDialogSemaphore = new(1, 1);
|
||||
private readonly SemaphoreSlim dataRestorePendingDialogSemaphore = new(1, 1);
|
||||
|
||||
private DataSourceEmbeddingOverview embeddingOverview = new(DataSourceEmbeddingState.COMPLETED, 0, 0, 0);
|
||||
private IReadOnlyCollection<NavBarItem> navItems = [];
|
||||
@@ -94,6 +98,7 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan
|
||||
{
|
||||
this.NavigationManager.RegisterLocationChangingHandler(this.OnLocationChanging);
|
||||
this.MediaTranscriptionService.StateChanged += this.OnMediaImportStateChanged;
|
||||
this.DataRestoreService.StateChanged += this.OnDataRestoreStateChanged;
|
||||
|
||||
//
|
||||
// We use the Tauri API (Rust) to get the data and config directories
|
||||
@@ -391,7 +396,7 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan
|
||||
|
||||
case Event.STARTUP_COMPLETED:
|
||||
this.startupCompleted = true;
|
||||
this.EnsureMandatoryInfosAcceptedAsync().Observe($"{nameof(MainLayout)}: mandatory infos after the startup");
|
||||
this.ShowStartupDialogsAsync().Observe($"{nameof(MainLayout)}: dialogs after the startup");
|
||||
break;
|
||||
|
||||
case Event.RAG_EMBEDDING_STATUS_CHANGED:
|
||||
@@ -640,6 +645,70 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan
|
||||
this.StateHasChanged();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows what the user has to see once the plugins started: the mandatory infos first, then how a
|
||||
/// restore of a backup went.
|
||||
/// </summary>
|
||||
private async Task ShowStartupDialogsAsync()
|
||||
{
|
||||
await this.EnsureMandatoryInfosAcceptedAsync();
|
||||
await this.ShowDataRestoreReportAsync();
|
||||
await this.ShowDataRestorePendingDialogAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asks for the restart as soon as a restore is prepared.
|
||||
/// </summary>
|
||||
private void OnDataRestoreStateChanged()
|
||||
{
|
||||
if (this.DataRestoreService.IsRestorePending)
|
||||
this.InvokeAsync(this.ShowDataRestorePendingDialogAsync).Observe($"{nameof(MainLayout)}: asking for the restart which applies a restore");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Blocks AI Studio while a prepared restore waits for the restart, since whatever changes until
|
||||
/// then would be lost.
|
||||
/// </summary>
|
||||
private async Task ShowDataRestorePendingDialogAsync()
|
||||
{
|
||||
if (!await this.dataRestorePendingDialogSemaphore.WaitAsync(0))
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
await this.DataRestoreService.StartupStateLoaded;
|
||||
if (!this.DataRestoreService.IsRestorePending)
|
||||
return;
|
||||
|
||||
var dialogReference = await this.DialogService.ShowAsync<DataRestorePendingDialog>(T("Restore of a Backup"), DialogOptions.BLOCKING_FULLSCREEN);
|
||||
await dialogReference.Result;
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.dataRestorePendingDialogSemaphore.Release();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tells how the runtime applied a restore at this start, and what remains to do.
|
||||
/// </summary>
|
||||
private async Task ShowDataRestoreReportAsync()
|
||||
{
|
||||
await this.DataRestoreService.StartupStateLoaded;
|
||||
if (this.DataRestoreService.Report is not { } report)
|
||||
return;
|
||||
|
||||
var dialogParameters = new DialogParameters<DataRestoreReportDialog>
|
||||
{
|
||||
{ x => x.Report, report },
|
||||
{ x => x.OpenPoints, await this.DataRestoreService.CollectOpenPointsAsync() },
|
||||
};
|
||||
|
||||
var dialogReference = await this.DialogService.ShowAsync<DataRestoreReportDialog>(T("Restore of a Backup"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||
await dialogReference.Result;
|
||||
this.DataRestoreService.ForgetReport();
|
||||
}
|
||||
|
||||
private async Task EnsureMandatoryInfosAcceptedAsync()
|
||||
{
|
||||
if (!await this.mandatoryInfoDialogSemaphore.WaitAsync(0))
|
||||
@@ -722,9 +791,11 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan
|
||||
public void Dispose()
|
||||
{
|
||||
this.MediaTranscriptionService.StateChanged -= this.OnMediaImportStateChanged;
|
||||
this.DataRestoreService.StateChanged -= this.OnDataRestoreStateChanged;
|
||||
this.CircuitState.ConnectionRestored -= this.OnConnectionRestored;
|
||||
this.MessageBus.Unregister(this);
|
||||
this.mandatoryInfoDialogSemaphore.Dispose();
|
||||
this.dataRestorePendingDialogSemaphore.Dispose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
Reference in new issue
Block a user