Moved the add and import buttons of the settings dialogs into their footer (#1060)

Co-authored-by: Thorsten Sommer <SommerEngineering@users.noreply.github.com>
This commit is contained in:
Paul KoudelkaandThorsten Sommer authored and GitHub committed 2026-10-20 08:35:44 +02:00
1 parent f26d132d56
commit 6b42af864c
13 files changed
+409 -320

No files matched your search

@@ -4024,6 +4024,48 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATAFOLDERS::T813925103"] = "The followin
-- On this computer, the data folder lies inside the configuration folder. A backup of the configuration folder therefore takes the data folder along.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATAFOLDERS::T91194331"] = "On this computer, the data folder lies inside the configuration folder. A backup of the configuration folder therefore takes the data folder along."
-- Local File, requires an embedding provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T1317002733"] = "Local File, requires an embedding provider"
-- Add Local Directory as Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T1454193397"] = "Add Local Directory as Data Source"
-- Local File
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T1687345358"] = "Local File"
-- Mailbox (IMAP), requires an embedding provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T2363290424"] = "Mailbox (IMAP), requires an embedding provider"
-- Mailbox (IMAP), not allowed by your organization
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T308474155"] = "Mailbox (IMAP), not allowed by your organization"
-- Add Mailbox
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T3173750212"] = "Add Mailbox"
-- Add Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T3387511033"] = "Add Data Source"
-- Add Local File as Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T3500365052"] = "Add Local File as Data Source"
-- Local Directory, requires an embedding provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T3698039736"] = "Local Directory, requires an embedding provider"
-- Import Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T381231449"] = "Import Data Source"
-- Mailbox (IMAP)
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T3859543867"] = "Mailbox (IMAP)"
-- Add ERI v1 Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T590005498"] = "Add ERI v1 Data Source"
-- External Data (ERI-Server v1)
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T774473996"] = "External Data (ERI-Server v1)"
-- Local Directory
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T926703547"] = "Local Directory"
-- Yes, please send my data to the external embedding provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCECLOUDEMBEDDINGWARNING::T1159107763"] = "Yes, please send my data to the external embedding provider"
@@ -4081,15 +4123,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1208397349"] = "Au
-- Edit Local Directory Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1215599168"] = "Edit Local Directory Data Source"
-- Local File, requires an embedding provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1317002733"] = "Local File, requires an embedding provider"
-- Refresh
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T135637716"] = "Refresh"
-- Add Local Directory as Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1454193397"] = "Add Local Directory as Data Source"
-- Delete
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1469573738"] = "Delete"
@@ -4105,9 +4141,6 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1592527757"] = "Ca
-- External (ERI)
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1652430727"] = "External (ERI)"
-- Local File
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1687345358"] = "Local File"
-- Delete Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1849107431"] = "Delete Data Source"
@@ -4120,9 +4153,6 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T2146756020"] = "Lo
-- Edit ERI v1 Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T221059217"] = "Edit ERI v1 Data Source"
-- Mailbox (IMAP), requires an embedding provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T2363290424"] = "Mailbox (IMAP), requires an embedding provider"
-- Edit Local File Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T2453292893"] = "Edit Local File Data Source"
@@ -4159,12 +4189,6 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T2940206485"] = "Yo
-- This data source is managed by your organization.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3031462878"] = "This data source is managed by your organization."
-- Mailbox (IMAP), not allowed by your organization
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T308474155"] = "Mailbox (IMAP), not allowed by your organization"
-- Add Mailbox
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3173750212"] = "Add Mailbox"
-- Delete Mailbox
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3264675802"] = "Delete Mailbox"
@@ -4174,18 +4198,12 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3267849393"] = "Ed
-- Are you sure you want to delete the data source '{0}' of type '{1}'?
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3337072977"] = "Are you sure you want to delete the data source '{0}' of type '{1}'?"
-- Add Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3387511033"] = "Add Data Source"
-- Unknown
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3424652889"] = "Unknown"
-- Close
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3448155331"] = "Close"
-- Add Local File as Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3500365052"] = "Add Local File as Data Source"
-- Type
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3512062061"] = "Type"
@@ -4201,21 +4219,12 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3595669127"] = "Ex
-- Local data sources refresh when files change.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3687976654"] = "Local data sources refresh when files change."
-- Local Directory, requires an embedding provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3698039736"] = "Local Directory, requires an embedding provider"
-- Not available
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3706935413"] = "Not available"
-- Import Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T381231449"] = "Import Data Source"
-- Export ERI Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3831281036"] = "Export ERI Data Source"
-- Mailbox (IMAP)
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3859543867"] = "Mailbox (IMAP)"
-- Actions
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3865031940"] = "Actions"
@@ -4228,15 +4237,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T4108252513"] = "Wa
-- Information
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T4256323669"] = "Information"
-- Add ERI v1 Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T590005498"] = "Add ERI v1 Data Source"
-- Cannot export this ERI data source because no enterprise encryption secret is configured.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T750361472"] = "Cannot export this ERI data source because no enterprise encryption secret is configured."
-- External Data (ERI-Server v1)
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T774473996"] = "External Data (ERI-Server v1)"
-- Cannot export this ERI data source because no authentication secret is configured. The issue was: {0}
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T782820095"] = "Cannot export this ERI data source because no authentication secret is configured. The issue was: {0}"
@@ -4249,9 +4252,6 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T854231603"] = "Loc
-- The password of this mailbox could not be deleted from the operating system, so the mailbox was kept. The issue was: {0}
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T87980240"] = "The password of this mailbox could not be deleted from the operating system, so the mailbox was kept. The issue was: {0}"
-- Local Directory
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T926703547"] = "Local Directory"
-- Import Embedding
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMISSINGEMBEDDINGWARNING::T1681763001"] = "Import Embedding"
@@ -0,0 +1,29 @@
@using AIStudio.Settings.DataModel
@using AIStudio.Tools.PluginSystem
@inherits MSGComponentBase
<MudStack Row="true" Wrap="Wrap.Wrap">
<MudMenu EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="@T("Add Data Source")" Color="Color.Primary" Variant="Variant.Filled" AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomLeft">
<MudMenuItem OnClick="@(() => this.AddDataSource(DataSourceType.ERI_V1))">
@T("External Data (ERI-Server v1)")
</MudMenuItem>
@*
Without an embedding provider, the dialogs of the local data sources could never be saved.
They stay listed with the reason, so nobody concludes that AI Studio cannot read local files:
*@
<MudMenuItem OnClick="@(() => this.AddDataSource(DataSourceType.LOCAL_DIRECTORY))" Disabled="@(!this.HasEmbeddingProvider)">
@(this.HasEmbeddingProvider ? T("Local Directory") : T("Local Directory, requires an embedding provider"))
</MudMenuItem>
<MudMenuItem OnClick="@(() => this.AddDataSource(DataSourceType.LOCAL_FILE))" Disabled="@(!this.HasEmbeddingProvider)">
@(this.HasEmbeddingProvider ? T("Local File") : T("Local File, requires an embedding provider"))
</MudMenuItem>
@if (PreviewFeatures.PRE_MAILBOXES_2026.IsEnabled(this.SettingsManager))
{
@* Shown with a lock rather than left out, like the locked buttons for adding providers: *@
<MudMenuItem OnClick="@this.AddMailbox" Disabled="@(!this.MayAddMailbox || !this.HasEmbeddingProvider)" Icon="@(this.MayAddMailbox ? null : Icons.Material.Filled.Lock)">
@this.MailboxMenuText
</MudMenuItem>
}
</MudMenu>
<LockableButton Text="@T("Import Data Source")" IsLocked="@(() => !this.SettingsManager.ConfigurationData.App.CanImportConfigurationSnippet(PluginConfigurationObjectType.DATA_SOURCE))" Icon="@Icons.Material.Filled.FileDownload" OnClickAsync="@this.ImportERIDataSource" ButtonVariant="Variant.Outlined" NoMargin="true" />
</MudStack>
@@ -0,0 +1,209 @@
using AIStudio.Dialogs;
using AIStudio.Settings;
using AIStudio.Settings.DataModel;
using AIStudio.Tools.PluginSystem;
using AIStudio.Tools.Services;
using Microsoft.AspNetCore.Components;
using DialogOptions = AIStudio.Dialogs.DialogOptions;
namespace AIStudio.Components;
/// <summary>
/// Adds and imports data sources and mailboxes. It is kept apart from DataSourceManagement, so that the
/// data source settings dialog can place these buttons in its footer, where they stay in reach however
/// long the table of data sources grows. The data source panel in the app settings places them below the table.
/// </summary>
public partial class DataSourceAddButtons : MSGComponentBase
{
[Inject]
private DataSourceEmbeddingService DataSourceEmbeddingService { get; init; } = null!;
[Inject]
private IDialogService DialogService { get; init; } = null!;
[Inject]
private RustService RustService { get; init; } = null!;
private bool MayAddMailbox => this.SettingsManager.ConfigurationData.App.AllowUserToAddMailbox;
/// <summary>
/// Whether an embedding provider exists, which every local data source needs.
/// </summary>
private bool HasEmbeddingProvider => !EmbeddingProviderSetup.IsMissing(this.SettingsManager);
/// <remarks>
/// The rule of the organization comes first: an embedding provider would not make the mailbox possible.
/// </remarks>
private string MailboxMenuText => !this.MayAddMailbox
? T("Mailbox (IMAP), not allowed by your organization")
: this.HasEmbeddingProvider
? T("Mailbox (IMAP)")
: T("Mailbox (IMAP), requires an embedding provider");
#region Overrides of ComponentBase
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
this.ApplyFilters([], [ Event.CONFIGURATION_CHANGED ]);
}
#endregion
#region Overrides of MSGComponentBase
protected override Task ProcessIncomingMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data) where T : default
{
switch (triggeredEvent)
{
// The embedding providers and the rules of the organization decide what the buttons offer:
case Event.CONFIGURATION_CHANGED:
this.StateHasChanged();
break;
}
return Task.CompletedTask;
}
#endregion
private async Task ImportERIDataSource()
{
var import = await ConfigurationSnippetImportDialog.ShowAsync(this.DialogService, PluginConfigurationObjectType.DATA_SOURCE, T("Import Data Source"));
if (import?.ConfigurationObject is not DataSourceERI_V1 dataSource)
return;
var eriDialogParameters = new DialogParameters<DataSourceERI_V1Dialog>
{
{ x => x.IsEditing, false },
{ x => x.IsImport, true },
{ x => x.DataSource, dataSource },
{ x => x.ImportedSecret, import.Secret },
};
var eriDialogReference = await this.DialogService.ShowAsync<DataSourceERI_V1Dialog>(T("Add ERI v1 Data Source"), eriDialogParameters, DialogOptions.FULLSCREEN);
var eriDialogResult = await eriDialogReference.Result;
if (eriDialogResult is null || eriDialogResult.Canceled)
return;
//
// An organization can lock the import while the user is still filling in the form, e.g.,
// with a new version of its configuration plugin. Hence, the permission is checked once
// more before the imported data source is stored:
//
if (!this.SettingsManager.ConfigurationData.App.CanImportConfigurationSnippet(PluginConfigurationObjectType.DATA_SOURCE))
return;
var eriDataSource = (DataSourceERI_V1)eriDialogResult.Data!;
await this.StoreAddedDataSource(eriDataSource with { Num = this.SettingsManager.ConfigurationData.NextDataSourceNum++ });
}
private async Task AddDataSource(DataSourceType type)
{
// The menu offers no local data source without an embedding provider, but the last one may have gone since it was drawn:
if (type is DataSourceType.LOCAL_FILE or DataSourceType.LOCAL_DIRECTORY && !this.HasEmbeddingProvider)
return;
IDataSource? addedDataSource = null;
switch (type)
{
case DataSourceType.LOCAL_FILE:
var localFileDialogParameters = new DialogParameters<DataSourceLocalFileDialog>
{
{ x => x.IsEditing, false },
};
var localFileDialogReference = await this.DialogService.ShowAsync<DataSourceLocalFileDialog>(T("Add Local File as Data Source"), localFileDialogParameters, DialogOptions.FULLSCREEN);
var localFileDialogResult = await localFileDialogReference.Result;
if (localFileDialogResult is null || localFileDialogResult.Canceled)
return;
var localFile = (DataSourceLocalFile)localFileDialogResult.Data!;
localFile = localFile with { Num = this.SettingsManager.ConfigurationData.NextDataSourceNum++ };
addedDataSource = localFile;
break;
case DataSourceType.LOCAL_DIRECTORY:
var localDirectoryDialogParameters = new DialogParameters<DataSourceLocalDirectoryDialog>
{
{ x => x.IsEditing, false },
};
var localDirectoryDialogReference = await this.DialogService.ShowAsync<DataSourceLocalDirectoryDialog>(T("Add Local Directory as Data Source"), localDirectoryDialogParameters, DialogOptions.FULLSCREEN);
var localDirectoryDialogResult = await localDirectoryDialogReference.Result;
if (localDirectoryDialogResult is null || localDirectoryDialogResult.Canceled)
return;
var localDirectory = (DataSourceLocalDirectory)localDirectoryDialogResult.Data!;
localDirectory = localDirectory with { Num = this.SettingsManager.ConfigurationData.NextDataSourceNum++ };
addedDataSource = localDirectory;
break;
case DataSourceType.ERI_V1:
var eriDialogParameters = new DialogParameters<DataSourceERI_V1Dialog>
{
{ x => x.IsEditing, false },
};
var eriDialogReference = await this.DialogService.ShowAsync<DataSourceERI_V1Dialog>(T("Add ERI v1 Data Source"), eriDialogParameters, DialogOptions.FULLSCREEN);
var eriDialogResult = await eriDialogReference.Result;
if (eriDialogResult is null || eriDialogResult.Canceled)
return;
var eriDataSource = (DataSourceERI_V1)eriDialogResult.Data!;
eriDataSource = eriDataSource with { Num = this.SettingsManager.ConfigurationData.NextDataSourceNum++ };
addedDataSource = eriDataSource;
break;
}
if(addedDataSource is null)
return;
await this.StoreAddedDataSource(addedDataSource);
}
private async Task StoreAddedDataSource(IDataSource addedDataSource)
{
this.SettingsManager.ConfigurationData.DataSources.Add(addedDataSource);
await this.SettingsManager.StoreSettings();
await this.DataSourceEmbeddingService.QueueDataSourceAsync(addedDataSource);
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
}
private async Task AddMailbox()
{
if (!this.MayAddMailbox || !this.HasEmbeddingProvider)
return;
var dialogParameters = new DialogParameters<DataSourceMailboxDialog>
{
{ x => x.IsEditing, false },
};
var dialogReference = await this.DialogService.ShowAsync<DataSourceMailboxDialog>(T("Add Mailbox"), dialogParameters, DialogOptions.FULLSCREEN);
var dialogResult = await dialogReference.Result;
if (dialogResult is null || dialogResult.Canceled)
return;
var mailbox = (DataSourceMailbox)dialogResult.Data!;
//
// The dialog refuses to add a mailbox once the organization rules them out, but the rule
// may change while it stores the password. Then the password goes again, as far as possible:
//
if (!this.MayAddMailbox)
{
await this.RustService.DeleteSecret(mailbox, SecretStoreType.DATA_SOURCE);
return;
}
mailbox = mailbox with { Num = this.SettingsManager.ConfigurationData.NextDataSourceNum++ };
this.SettingsManager.ConfigurationData.Mailboxes.Add(mailbox);
await this.SettingsManager.StoreSettings();
await this.DataSourceEmbeddingService.QueueDataSourceAsync(mailbox);
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
}
}
@@ -1,6 +1,5 @@
@using AIStudio.Settings
@using AIStudio.Settings.DataModel
@using AIStudio.Tools.PluginSystem
@inherits MSGComponentBase
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
@@ -125,30 +124,4 @@
<MudText Typo="Typo.h6" Class="mt-3">
@T("No data sources configured yet.")
</MudText>
}
<MudStack Row="true" Wrap="Wrap.Wrap" Class="mt-3 mb-6">
<MudMenu EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="@T("Add Data Source")" Color="Color.Primary" Variant="Variant.Filled" AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomLeft">
<MudMenuItem OnClick="@(() => this.AddDataSource(DataSourceType.ERI_V1))">
@T("External Data (ERI-Server v1)")
</MudMenuItem>
@*
Without an embedding provider, the dialogs of the local data sources could never be saved.
They stay listed with the reason, so nobody concludes that AI Studio cannot read local files:
*@
<MudMenuItem OnClick="@(() => this.AddDataSource(DataSourceType.LOCAL_DIRECTORY))" Disabled="@(!this.HasEmbeddingProvider)">
@(this.HasEmbeddingProvider ? T("Local Directory") : T("Local Directory, requires an embedding provider"))
</MudMenuItem>
<MudMenuItem OnClick="@(() => this.AddDataSource(DataSourceType.LOCAL_FILE))" Disabled="@(!this.HasEmbeddingProvider)">
@(this.HasEmbeddingProvider ? T("Local File") : T("Local File, requires an embedding provider"))
</MudMenuItem>
@if (PreviewFeatures.PRE_MAILBOXES_2026.IsEnabled(this.SettingsManager))
{
@* Shown with a lock rather than left out, like the locked buttons for adding providers: *@
<MudMenuItem OnClick="@this.AddMailbox" Disabled="@(!this.MayAddMailbox || !this.HasEmbeddingProvider)" Icon="@(this.MayAddMailbox ? null : Icons.Material.Filled.Lock)">
@this.MailboxMenuText
</MudMenuItem>
}
</MudMenu>
<LockableButton Text="@T("Import Data Source")" IsLocked="@(() => !this.SettingsManager.ConfigurationData.App.CanImportConfigurationSnippet(PluginConfigurationObjectType.DATA_SOURCE))" Icon="@Icons.Material.Filled.FileDownload" OnClickAsync="@this.ImportERIDataSource" ButtonVariant="Variant.Outlined" NoMargin="true" />
</MudStack>
}
@@ -14,7 +14,8 @@ namespace AIStudio.Components;
/// <summary>
/// Manages the configured data sources. Used by the data source settings dialog, which the chat
/// opens, and by the data source panel in the app settings.
/// opens, and by the data source panel in the app settings. Adding and importing a data source is
/// up to DataSourceAddButtons, which each of them places on its own.
/// </summary>
public partial class DataSourceManagement : MSGComponentBase
{
@@ -38,22 +39,6 @@ public partial class DataSourceManagement : MSGComponentBase
private bool AreMailboxesEnabled => PreviewFeatures.PRE_MAILBOXES_2026.IsEnabled(this.SettingsManager);
private bool MayAddMailbox => this.SettingsManager.ConfigurationData.App.AllowUserToAddMailbox;
/// <summary>
/// Whether an embedding provider exists, which every local data source needs.
/// </summary>
private bool HasEmbeddingProvider => !EmbeddingProviderSetup.IsMissing(this.SettingsManager);
/// <remarks>
/// The rule of the organization comes first: an embedding provider would not make the mailbox possible.
/// </remarks>
private string MailboxMenuText => !this.MayAddMailbox
? T("Mailbox (IMAP), not allowed by your organization")
: this.HasEmbeddingProvider
? T("Mailbox (IMAP)")
: T("Mailbox (IMAP), requires an embedding provider");
#region Overrides of ComponentBase
protected override async Task OnInitializedAsync()
@@ -189,109 +174,6 @@ public partial class DataSourceManagement : MSGComponentBase
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
}
private async Task ImportERIDataSource()
{
var import = await ConfigurationSnippetImportDialog.ShowAsync(this.DialogService, PluginConfigurationObjectType.DATA_SOURCE, T("Import Data Source"));
if (import?.ConfigurationObject is not DataSourceERI_V1 dataSource)
return;
var eriDialogParameters = new DialogParameters<DataSourceERI_V1Dialog>
{
{ x => x.IsEditing, false },
{ x => x.IsImport, true },
{ x => x.DataSource, dataSource },
{ x => x.ImportedSecret, import.Secret },
};
var eriDialogReference = await this.DialogService.ShowAsync<DataSourceERI_V1Dialog>(T("Add ERI v1 Data Source"), eriDialogParameters, DialogOptions.FULLSCREEN);
var eriDialogResult = await eriDialogReference.Result;
if (eriDialogResult is null || eriDialogResult.Canceled)
return;
//
// An organization can lock the import while the user is still filling in the form, e.g.,
// with a new version of its configuration plugin. Hence, the permission is checked once
// more before the imported data source is stored:
//
if (!this.SettingsManager.ConfigurationData.App.CanImportConfigurationSnippet(PluginConfigurationObjectType.DATA_SOURCE))
return;
var eriDataSource = (DataSourceERI_V1)eriDialogResult.Data!;
await this.StoreAddedDataSource(eriDataSource with { Num = this.SettingsManager.ConfigurationData.NextDataSourceNum++ });
}
private async Task AddDataSource(DataSourceType type)
{
// The menu offers no local data source without an embedding provider, but the last one may have gone since it was drawn:
if (type is DataSourceType.LOCAL_FILE or DataSourceType.LOCAL_DIRECTORY && !this.HasEmbeddingProvider)
return;
IDataSource? addedDataSource = null;
switch (type)
{
case DataSourceType.LOCAL_FILE:
var localFileDialogParameters = new DialogParameters<DataSourceLocalFileDialog>
{
{ x => x.IsEditing, false },
};
var localFileDialogReference = await this.DialogService.ShowAsync<DataSourceLocalFileDialog>(T("Add Local File as Data Source"), localFileDialogParameters, DialogOptions.FULLSCREEN);
var localFileDialogResult = await localFileDialogReference.Result;
if (localFileDialogResult is null || localFileDialogResult.Canceled)
return;
var localFile = (DataSourceLocalFile)localFileDialogResult.Data!;
localFile = localFile with { Num = this.SettingsManager.ConfigurationData.NextDataSourceNum++ };
addedDataSource = localFile;
break;
case DataSourceType.LOCAL_DIRECTORY:
var localDirectoryDialogParameters = new DialogParameters<DataSourceLocalDirectoryDialog>
{
{ x => x.IsEditing, false },
};
var localDirectoryDialogReference = await this.DialogService.ShowAsync<DataSourceLocalDirectoryDialog>(T("Add Local Directory as Data Source"), localDirectoryDialogParameters, DialogOptions.FULLSCREEN);
var localDirectoryDialogResult = await localDirectoryDialogReference.Result;
if (localDirectoryDialogResult is null || localDirectoryDialogResult.Canceled)
return;
var localDirectory = (DataSourceLocalDirectory)localDirectoryDialogResult.Data!;
localDirectory = localDirectory with { Num = this.SettingsManager.ConfigurationData.NextDataSourceNum++ };
addedDataSource = localDirectory;
break;
case DataSourceType.ERI_V1:
var eriDialogParameters = new DialogParameters<DataSourceERI_V1Dialog>
{
{ x => x.IsEditing, false },
};
var eriDialogReference = await this.DialogService.ShowAsync<DataSourceERI_V1Dialog>(T("Add ERI v1 Data Source"), eriDialogParameters, DialogOptions.FULLSCREEN);
var eriDialogResult = await eriDialogReference.Result;
if (eriDialogResult is null || eriDialogResult.Canceled)
return;
var eriDataSource = (DataSourceERI_V1)eriDialogResult.Data!;
eriDataSource = eriDataSource with { Num = this.SettingsManager.ConfigurationData.NextDataSourceNum++ };
addedDataSource = eriDataSource;
break;
}
if(addedDataSource is null)
return;
await this.StoreAddedDataSource(addedDataSource);
}
private async Task StoreAddedDataSource(IDataSource addedDataSource)
{
this.SettingsManager.ConfigurationData.DataSources.Add(addedDataSource);
await this.SettingsManager.StoreSettings();
await this.DataSourceEmbeddingService.QueueDataSourceAsync(addedDataSource);
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
}
private async Task ExportDataSource(IDataSourceBase dataSource)
{
if (!this.SettingsManager.ConfigurationData.App.ShowAdminSettings)
@@ -537,41 +419,6 @@ public partial class DataSourceManagement : MSGComponentBase
_ => Task.CompletedTask,
};
private async Task AddMailbox()
{
if (!this.MayAddMailbox || !this.HasEmbeddingProvider)
return;
var dialogParameters = new DialogParameters<DataSourceMailboxDialog>
{
{ x => x.IsEditing, false },
};
var dialogReference = await this.DialogService.ShowAsync<DataSourceMailboxDialog>(T("Add Mailbox"), dialogParameters, DialogOptions.FULLSCREEN);
var dialogResult = await dialogReference.Result;
if (dialogResult is null || dialogResult.Canceled)
return;
var mailbox = (DataSourceMailbox)dialogResult.Data!;
//
// The dialog refuses to add a mailbox once the organization rules them out, but the rule
// may change while it stores the password. Then the password goes again, as far as possible:
//
if (!this.MayAddMailbox)
{
await this.RustService.DeleteSecret(mailbox, SecretStoreType.DATA_SOURCE);
return;
}
mailbox = mailbox with { Num = this.SettingsManager.ConfigurationData.NextDataSourceNum++ };
this.SettingsManager.ConfigurationData.Mailboxes.Add(mailbox);
await this.SettingsManager.StoreSettings();
await this.DataSourceEmbeddingService.QueueDataSourceAsync(mailbox);
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
}
private async Task EditMailbox(DataSourceMailbox mailbox)
{
if (await MailboxEditing.EditAsync(this.DialogService, this.SettingsManager, this.DataSourceEmbeddingService, mailbox.Id))
@@ -6,5 +6,8 @@
<ExpansionPanel HeaderIcon="@AppIcons.DATABASE" HeaderText="@T("Configure Data Sources")">
<PreviewBeta ApplyInnerScrollingFix="true"/>
<DataSourceManagement/>
<div class="mt-3 mb-6">
<DataSourceAddButtons/>
</div>
</ExpansionPanel>
}
@@ -1,7 +1,7 @@
@using AIStudio.Tools.PluginSystem
@inherits SettingsDialogBase
<MudDialog>
<MudDialog ContentClass="dialog-content-aligned" ActionsClass="dialog-actions-aligned">
<TitleContent>
<MudText Typo="Typo.h6" Class="d-flex align-center">
<MudIcon Icon="@Icons.Material.Filled.RateReview" Class="mr-2" />
@@ -81,15 +81,16 @@
@T("No chat templates configured yet.")
</MudText>
}
<MudStack Row="true" Wrap="Wrap.Wrap" Class="mt-3 mb-6">
</DialogContent>
<DialogActions>
@* In the footer, adding and importing stay in reach however long the table grows: *@
<MudStack Row="true" Wrap="Wrap.Wrap">
<MudButton Variant="Variant.Filled" Color="@Color.Primary" StartIcon="@Icons.Material.Filled.AddRoad" OnClick="@this.AddChatTemplate">
@T("Add Chat Template")
</MudButton>
<LockableButton Text="@T("Import Chat Template")" IsLocked="@(() => !this.SettingsManager.ConfigurationData.App.CanImportConfigurationSnippet(PluginConfigurationObjectType.CHAT_TEMPLATE))" Icon="@Icons.Material.Filled.FileDownload" OnClickAsync="@this.ImportChatTemplate" ButtonVariant="Variant.Outlined" NoMargin="true" />
</MudStack>
</DialogContent>
<DialogActions>
<MudSpacer/>
<MudButton OnClick="@this.Close" Variant="Variant.Filled">
@T("Close")
</MudButton>
@@ -1,6 +1,6 @@
@inherits SettingsDialogBase
<MudDialog>
<MudDialog ContentClass="dialog-content-aligned" ActionsClass="dialog-actions-aligned">
<TitleContent>
<PreviewBeta/>
<MudText Typo="Typo.h6" Class="d-flex align-center">
@@ -12,6 +12,9 @@
<DataSourceManagement/>
</DialogContent>
<DialogActions>
@* In the footer, adding and importing stay in reach however long the table grows: *@
<DataSourceAddButtons/>
<MudSpacer/>
<MudButton OnClick="@this.Close" Variant="Variant.Filled">
@T("Close")
</MudButton>
@@ -1,7 +1,7 @@
@using AIStudio.Tools.PluginSystem
@inherits SettingsDialogBase
<MudDialog>
<MudDialog ContentClass="dialog-content-aligned" ActionsClass="dialog-actions-aligned">
<TitleContent>
<MudText Typo="Typo.h6" Class="d-flex align-center">
<MudIcon Icon="@Icons.Material.Filled.Person4" Class="mr-2" />
@@ -64,15 +64,16 @@
@T("No profiles configured yet.")
</MudText>
}
<MudStack Row="true" Wrap="Wrap.Wrap" Class="mt-3 mb-6">
</DialogContent>
<DialogActions>
@* In the footer, adding and importing stay in reach however long the table grows: *@
<MudStack Row="true" Wrap="Wrap.Wrap">
<MudButton Variant="Variant.Filled" Color="@Color.Primary" StartIcon="@Icons.Material.Filled.AddRoad" OnClick="@this.AddProfile">
@T("Add Profile")
</MudButton>
<LockableButton Text="@T("Import Profile")" IsLocked="@(() => !this.SettingsManager.ConfigurationData.App.CanImportConfigurationSnippet(PluginConfigurationObjectType.PROFILE))" Icon="@Icons.Material.Filled.FileDownload" OnClickAsync="@this.ImportProfile" ButtonVariant="Variant.Outlined" NoMargin="true" />
</MudStack>
</DialogContent>
<DialogActions>
<MudSpacer/>
<MudButton OnClick="@this.Close" Variant="Variant.Filled">
@T("Close")
</MudButton>
@@ -4026,6 +4026,48 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATAFOLDERS::T813925103"] = "Das Folgende
-- On this computer, the data folder lies inside the configuration folder. A backup of the configuration folder therefore takes the data folder along.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATAFOLDERS::T91194331"] = "Auf diesem Rechner befindet sich der Datenordner im Konfigurationsordner. Bei einer Sicherung des Konfigurationsordners wird daher auch der Datenordner mitgesichert."
-- Local File, requires an embedding provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T1317002733"] = "Lokale Datei, erfordert einen Einbettungsanbieter"
-- Add Local Directory as Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T1454193397"] = "Lokalen Ordner als Datenquelle hinzufügen"
-- Local File
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T1687345358"] = "Lokale Datei"
-- Mailbox (IMAP), requires an embedding provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T2363290424"] = "Postfach (IMAP), erfordert einen Einbettungsanbieter"
-- Mailbox (IMAP), not allowed by your organization
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T308474155"] = "Postfach (IMAP), von Ihrer Organisation nicht erlaubt"
-- Add Mailbox
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T3173750212"] = "Postfach hinzufügen"
-- Add Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T3387511033"] = "Datenquelle hinzufügen"
-- Add Local File as Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T3500365052"] = "Lokale Datei als Datenquelle hinzufügen"
-- Local Directory, requires an embedding provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T3698039736"] = "Lokaler Ordner, erfordert einen Einbettungsanbieter"
-- Import Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T381231449"] = "Datenquelle importieren"
-- Mailbox (IMAP)
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T3859543867"] = "Postfach (IMAP)"
-- Add ERI v1 Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T590005498"] = "ERI v1 Datenquelle hinzufügen"
-- External Data (ERI-Server v1)
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T774473996"] = "Externe Daten (ERI-Server v1)"
-- Local Directory
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T926703547"] = "Lokaler Ordner"
-- Yes, please send my data to the external embedding provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCECLOUDEMBEDDINGWARNING::T1159107763"] = "Ja, bitte senden Sie meine Daten an den externen Einbettungsanbieter"
@@ -4083,15 +4125,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1208397349"] = "Au
-- Edit Local Directory Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1215599168"] = "Datenquelle bearbeiten: Lokaler Ordner"
-- Local File, requires an embedding provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1317002733"] = "Lokale Datei, erfordert einen Einbettungsanbieter"
-- Refresh
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T135637716"] = "Aktualisieren"
-- Add Local Directory as Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1454193397"] = "Lokalen Ordner als Datenquelle hinzufügen"
-- Delete
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1469573738"] = "Löschen"
@@ -4107,9 +4143,6 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1592527757"] = "Di
-- External (ERI)
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1652430727"] = "Extern (ERI)"
-- Local File
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1687345358"] = "Lokale Datei"
-- Delete Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1849107431"] = "Datenquelle löschen"
@@ -4122,9 +4155,6 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T2146756020"] = "In
-- Edit ERI v1 Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T221059217"] = "ERI v1 Datenquelle bearbeiten"
-- Mailbox (IMAP), requires an embedding provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T2363290424"] = "Postfach (IMAP), erfordert einen Einbettungsanbieter"
-- Edit Local File Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T2453292893"] = "Datenquelle bearbeiten: Lokale Datei"
@@ -4161,12 +4191,6 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T2940206485"] = "Si
-- This data source is managed by your organization.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3031462878"] = "Diese Datenquelle wird von Ihrer Organisation verwaltet."
-- Mailbox (IMAP), not allowed by your organization
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T308474155"] = "Postfach (IMAP), von Ihrer Organisation nicht erlaubt"
-- Add Mailbox
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3173750212"] = "Postfach hinzufügen"
-- Delete Mailbox
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3264675802"] = "Postfach löschen"
@@ -4176,18 +4200,12 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3267849393"] = "Be
-- Are you sure you want to delete the data source '{0}' of type '{1}'?
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3337072977"] = "Möchten Sie die Datenquelle „{0}“ vom Typ „{1}“ wirklich löschen?"
-- Add Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3387511033"] = "Datenquelle hinzufügen"
-- Unknown
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3424652889"] = "Unbekannt"
-- Close
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3448155331"] = "Schließen"
-- Add Local File as Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3500365052"] = "Lokale Datei als Datenquelle hinzufügen"
-- Type
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3512062061"] = "Typ"
@@ -4203,21 +4221,12 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3595669127"] = "Zu
-- Local data sources refresh when files change.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3687976654"] = "Lokale Datenquellen werden aktualisiert, wenn sich Dateien ändern."
-- Local Directory, requires an embedding provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3698039736"] = "Lokaler Ordner, erfordert einen Einbettungsanbieter"
-- Not available
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3706935413"] = "Nicht verfügbar"
-- Import Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T381231449"] = "Datenquelle importieren"
-- Export ERI Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3831281036"] = "ERI-Datenquelle exportieren"
-- Mailbox (IMAP)
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3859543867"] = "Postfach (IMAP)"
-- Actions
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3865031940"] = "Aktionen"
@@ -4230,15 +4239,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T4108252513"] = "Wa
-- Information
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T4256323669"] = "Information"
-- Add ERI v1 Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T590005498"] = "ERI v1 Datenquelle hinzufügen"
-- Cannot export this ERI data source because no enterprise encryption secret is configured.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T750361472"] = "Diese ERI-Datenquelle kann nicht exportiert werden, da kein Geheimnis für die Verschlüsselung des Unternehmens konfiguriert ist."
-- External Data (ERI-Server v1)
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T774473996"] = "Externe Daten (ERI-Server v1)"
-- Cannot export this ERI data source because no authentication secret is configured. The issue was: {0}
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T782820095"] = "Diese ERI-Datenquelle kann nicht exportiert werden, da kein Geheimnis für die Authentifizierung konfiguriert ist. Das Problem war: {0}"
@@ -4251,9 +4254,6 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T854231603"] = "Lok
-- The password of this mailbox could not be deleted from the operating system, so the mailbox was kept. The issue was: {0}
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T87980240"] = "Das Passwort für dieses Postfach konnte nicht aus dem Betriebssystem gelöscht werden. Daher wurde das Postfach beibehalten. Das Problem war: {0}"
-- Local Directory
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T926703547"] = "Lokaler Ordner"
-- Import Embedding
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMISSINGEMBEDDINGWARNING::T1681763001"] = "Einbettung importieren"
@@ -4026,6 +4026,48 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATAFOLDERS::T813925103"] = "The followin
-- On this computer, the data folder lies inside the configuration folder. A backup of the configuration folder therefore takes the data folder along.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATAFOLDERS::T91194331"] = "On this computer, the data folder lies inside the configuration folder. A backup of the configuration folder therefore takes the data folder along."
-- Local File, requires an embedding provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T1317002733"] = "Local File, requires an embedding provider"
-- Add Local Directory as Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T1454193397"] = "Add Local Directory as Data Source"
-- Local File
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T1687345358"] = "Local File"
-- Mailbox (IMAP), requires an embedding provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T2363290424"] = "Mailbox (IMAP), requires an embedding provider"
-- Mailbox (IMAP), not allowed by your organization
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T308474155"] = "Mailbox (IMAP), not allowed by your organization"
-- Add Mailbox
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T3173750212"] = "Add Mailbox"
-- Add Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T3387511033"] = "Add Data Source"
-- Add Local File as Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T3500365052"] = "Add Local File as Data Source"
-- Local Directory, requires an embedding provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T3698039736"] = "Local Directory, requires an embedding provider"
-- Import Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T381231449"] = "Import Data Source"
-- Mailbox (IMAP)
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T3859543867"] = "Mailbox (IMAP)"
-- Add ERI v1 Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T590005498"] = "Add ERI v1 Data Source"
-- External Data (ERI-Server v1)
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T774473996"] = "External Data (ERI-Server v1)"
-- Local Directory
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEADDBUTTONS::T926703547"] = "Local Directory"
-- Yes, please send my data to the external embedding provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCECLOUDEMBEDDINGWARNING::T1159107763"] = "Yes, please send my data to the external embedding provider"
@@ -4083,15 +4125,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1208397349"] = "Au
-- Edit Local Directory Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1215599168"] = "Edit Local Directory Data Source"
-- Local File, requires an embedding provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1317002733"] = "Local File, requires an embedding provider"
-- Refresh
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T135637716"] = "Refresh"
-- Add Local Directory as Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1454193397"] = "Add Local Directory as Data Source"
-- Delete
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1469573738"] = "Delete"
@@ -4107,9 +4143,6 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1592527757"] = "Ca
-- External (ERI)
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1652430727"] = "External (ERI)"
-- Local File
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1687345358"] = "Local File"
-- Delete Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T1849107431"] = "Delete Data Source"
@@ -4122,9 +4155,6 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T2146756020"] = "Lo
-- Edit ERI v1 Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T221059217"] = "Edit ERI v1 Data Source"
-- Mailbox (IMAP), requires an embedding provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T2363290424"] = "Mailbox (IMAP), requires an embedding provider"
-- Edit Local File Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T2453292893"] = "Edit Local File Data Source"
@@ -4161,12 +4191,6 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T2940206485"] = "Yo
-- This data source is managed by your organization.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3031462878"] = "This data source is managed by your organization."
-- Mailbox (IMAP), not allowed by your organization
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T308474155"] = "Mailbox (IMAP), not allowed by your organization"
-- Add Mailbox
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3173750212"] = "Add Mailbox"
-- Delete Mailbox
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3264675802"] = "Delete Mailbox"
@@ -4176,18 +4200,12 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3267849393"] = "Ed
-- Are you sure you want to delete the data source '{0}' of type '{1}'?
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3337072977"] = "Are you sure you want to delete the data source '{0}' of type '{1}'?"
-- Add Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3387511033"] = "Add Data Source"
-- Unknown
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3424652889"] = "Unknown"
-- Close
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3448155331"] = "Close"
-- Add Local File as Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3500365052"] = "Add Local File as Data Source"
-- Type
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3512062061"] = "Type"
@@ -4203,21 +4221,12 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3595669127"] = "Ex
-- Local data sources refresh when files change.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3687976654"] = "Local data sources refresh when files change."
-- Local Directory, requires an embedding provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3698039736"] = "Local Directory, requires an embedding provider"
-- Not available
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3706935413"] = "Not available"
-- Import Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T381231449"] = "Import Data Source"
-- Export ERI Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3831281036"] = "Export ERI Data Source"
-- Mailbox (IMAP)
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3859543867"] = "Mailbox (IMAP)"
-- Actions
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T3865031940"] = "Actions"
@@ -4230,15 +4239,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T4108252513"] = "Wa
-- Information
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T4256323669"] = "Information"
-- Add ERI v1 Data Source
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T590005498"] = "Add ERI v1 Data Source"
-- Cannot export this ERI data source because no enterprise encryption secret is configured.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T750361472"] = "Cannot export this ERI data source because no enterprise encryption secret is configured."
-- External Data (ERI-Server v1)
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T774473996"] = "External Data (ERI-Server v1)"
-- Cannot export this ERI data source because no authentication secret is configured. The issue was: {0}
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T782820095"] = "Cannot export this ERI data source because no authentication secret is configured. The issue was: {0}"
@@ -4251,9 +4254,6 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T854231603"] = "Loc
-- The password of this mailbox could not be deleted from the operating system, so the mailbox was kept. The issue was: {0}
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T87980240"] = "The password of this mailbox could not be deleted from the operating system, so the mailbox was kept. The issue was: {0}"
-- Local Directory
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMANAGEMENT::T926703547"] = "Local Directory"
-- Import Embedding
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCEMISSINGEMBEDDINGWARNING::T1681763001"] = "Import Embedding"
+22
View File
@@ -531,3 +531,25 @@ tr:has(> .provider-group-header) .mud-icon-button {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
}
/*
* Dialogs whose footer carries buttons on the left as well, such as Add and Import next to Close.
* MudBlazor pads the content with 24px to the left and right, but the footer with only 8px, so the
* buttons stood out of the column of the table above them. The footer takes over the 24px. On the
* right, the content also gives up the room of its scrollbar as soon as the table grows long, and
* how wide that is depends on the operating system and its settings, down to nothing for scrollbars
* which only show while scrolling. So no fixed padding fits: the content reserves that room for good,
* and the footer reserves the very same, which scrollbar-gutter only does for an element that clips
* its overflow. The popovers of menus and tooltips live elsewhere, so the footer clips no more than
* the outermost blur of a button shadow. A web view without scrollbar-gutter keeps the old offset on
* the right only. Both rules name the MudBlazor classes to outweigh their specificity.
*/
.mud-dialog .mud-dialog-content.dialog-content-aligned {
scrollbar-gutter: stable;
}
.mud-dialog .mud-dialog-actions.dialog-actions-aligned {
padding: 8px 24px;
overflow: hidden;
scrollbar-gutter: stable;
}
@@ -44,6 +44,7 @@
- Improved the organization-wide management of the app settings. IT departments can now also set whether AI Studio saves energy while the AI writes its answers, which helps on virtual desktops, for example.
- Improved attaching files to a chat. You can now attach any file that contains readable text, for example, program code or configuration files of a kind AI Studio did not know before.
- Improved adding a local data source when you have not configured an embedding provider yet. Until now, you only found out when saving the dialog, after filling in everything else. The data source settings now tell you right away and let you add an embedding provider right there, without losing what you entered.
- Improved the dialogs for managing your data sources, profiles, and chat templates, which you open, for example, from a chat. The buttons for adding and importing now stay at the bottom of the dialog, so you no longer need to scroll past a long list to reach them. Thanks, Paul Koudelka (`PaulKoudelka`), for this contribution.
- Changed the banner on the start page to a fresh design that shows what AI Studio can do today.
- Fixed a warning about the confidence level that stayed in the dialog for adding a local data source, even after you chose an embedding provider that meets it. The dialog now checks again whenever you change either of them, so a warning also appears when you switch to a provider that falls short.
- Fixed the list of data sources squeezing their names into a very narrow column when you opened it from a chat or from the background embeddings page, so the names were hard to read.