From b0b30b0f9b559ac54f1ed8c2312bca74ead909fe Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Wed, 9 Sep 2026 16:14:46 +0200 Subject: [PATCH] Always show the embedding status in the navigation --- .../Assistants/I18N/allTexts.lua | 3 ++ .../Layout/MainLayout.razor.cs | 31 +++++++++++++++---- .../plugin.lua | 3 ++ .../plugin.lua | 3 ++ .../Services/DataSourceEmbeddingOverview.cs | 2 +- .../Services/DataSourceEmbeddingService.cs | 5 ++- 6 files changed, 37 insertions(+), 10 deletions(-) diff --git a/app/MindWork AI Studio/Assistants/I18N/allTexts.lua b/app/MindWork AI Studio/Assistants/I18N/allTexts.lua index a6fa350e..d753b8ec 100644 --- a/app/MindWork AI Studio/Assistants/I18N/allTexts.lua +++ b/app/MindWork AI Studio/Assistants/I18N/allTexts.lua @@ -8701,6 +8701,9 @@ UI_TEXT_CONTENT["AISTUDIO::LAYOUT::MAINLAYOUT::T3692372066"] = "Show details" -- Security notice UI_TEXT_CONTENT["AISTUDIO::LAYOUT::MAINLAYOUT::T4004397997"] = "Security notice" +-- All data sources are up to date. +UI_TEXT_CONTENT["AISTUDIO::LAYOUT::MAINLAYOUT::T4055300176"] = "All data sources are up to date." + -- Information UI_TEXT_CONTENT["AISTUDIO::LAYOUT::MAINLAYOUT::T4256323669"] = "Information" diff --git a/app/MindWork AI Studio/Layout/MainLayout.razor.cs b/app/MindWork AI Studio/Layout/MainLayout.razor.cs index a8cc0af6..801ce2f6 100644 --- a/app/MindWork AI Studio/Layout/MainLayout.razor.cs +++ b/app/MindWork AI Studio/Layout/MainLayout.razor.cs @@ -80,7 +80,7 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan private readonly SemaphoreSlim mandatoryInfoDialogSemaphore = new(1, 1); private readonly SemaphoreSlim promptInjectionDialogSemaphore = new(1, 1); - private DataSourceEmbeddingOverview embeddingOverview = new(false, DataSourceEmbeddingState.COMPLETED, 0, 0, 0); + private DataSourceEmbeddingOverview embeddingOverview = new(DataSourceEmbeddingState.COMPLETED, 0, 0, 0); private IReadOnlyCollection navItems = []; private NavBarItem embeddingItem = new (string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, false); private bool showEmbeddingStatusIcon; @@ -459,13 +459,29 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan private void LoadEmbeddingItem() { this.embeddingOverview = this.DataSourceEmbeddingService.GetOverview(); - this.showEmbeddingStatusIcon = this.embeddingOverview.IsVisible; + + // + // The entry is shown whenever local RAG is available, in every state. Hiding it while + // nothing was running looked tidier, but a data source which was just added has no status + // yet: the service creates one when the run begins. The icon was therefore missing during + // the very moment the user was waiting for it. What the entry does communicate is its + // state, through the icon below. + // + // The preview feature is what gates it now. The route itself is not gated, so without this + // check, users who have no RAG at all would get a navigation entry for it. + // + this.showEmbeddingStatusIcon = PreviewFeatures.PRE_RAG_2024.IsEnabled(this.SettingsManager); + var palette = this.ColorTheme.GetCurrentPalette(this.SettingsManager); (string icon, string lightcolor, string darkcolor) embeddingIcon = this.embeddingOverview.State switch { - (DataSourceEmbeddingState.FAILED) => (Icons.Material.Filled.Warning, palette.Error.Value, "#d32f2f"), - (DataSourceEmbeddingState.QUEUED) => (Icons.Material.Filled.Sync, palette.Info.Value, "#1976d2"), - _ => (Icons.Material.Filled.Sync, palette.Warning.Value, "#d29f00"), + DataSourceEmbeddingState.FAILED => (Icons.Material.Filled.Warning, palette.Error.Value, "#d32f2f"), + DataSourceEmbeddingState.QUEUED => (Icons.Material.Filled.Sync, palette.Info.Value, "#1976d2"), + DataSourceEmbeddingState.RUNNING => (Icons.Material.Filled.Sync, palette.Warning.Value, "#d29f00"), + + // Nothing to do: the entry keeps the colors of its neighbors, so a permanently visible + // icon does not draw attention while there is nothing to attend to: + _ => (Icons.Material.Filled.CloudDone, palette.DarkLighten, palette.GrayLight), }; this.embeddingItem = new NavBarItem(T("Embeddings"), embeddingIcon.icon, embeddingIcon.lightcolor, embeddingIcon.darkcolor, Routes.EMBEDDINGS, false); } @@ -480,7 +496,10 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan DataSourceEmbeddingState.FAILED => this.embeddingOverview.FailedFiles > 0 ? string.Format(T("Some embeddings failed. {0} file(s) need attention."), this.embeddingOverview.FailedFiles) : T("Some embeddings failed and need attention."), - _ => string.Empty + + // The entry is always visible, so its resting state needs words as well. An empty tooltip + // would leave the user guessing what the icon is there for: + _ => T("All data sources are up to date.") }; private async Task ShowUpdateDialog() diff --git a/app/MindWork AI Studio/Plugins/languages/de-de-43065dbc-78d0-45b7-92be-f14c2926e2dc/plugin.lua b/app/MindWork AI Studio/Plugins/languages/de-de-43065dbc-78d0-45b7-92be-f14c2926e2dc/plugin.lua index 180a0c33..42057668 100644 --- a/app/MindWork AI Studio/Plugins/languages/de-de-43065dbc-78d0-45b7-92be-f14c2926e2dc/plugin.lua +++ b/app/MindWork AI Studio/Plugins/languages/de-de-43065dbc-78d0-45b7-92be-f14c2926e2dc/plugin.lua @@ -8703,6 +8703,9 @@ UI_TEXT_CONTENT["AISTUDIO::LAYOUT::MAINLAYOUT::T3692372066"] = "Details anzeigen -- Security notice UI_TEXT_CONTENT["AISTUDIO::LAYOUT::MAINLAYOUT::T4004397997"] = "Sicherheitshinweis" +-- All data sources are up to date. +UI_TEXT_CONTENT["AISTUDIO::LAYOUT::MAINLAYOUT::T4055300176"] = "Alle Datenquellen sind auf dem neuesten Stand." + -- Information UI_TEXT_CONTENT["AISTUDIO::LAYOUT::MAINLAYOUT::T4256323669"] = "Information" diff --git a/app/MindWork AI Studio/Plugins/languages/en-us-97dfb1ba-50c4-4440-8dfa-6575daf543c8/plugin.lua b/app/MindWork AI Studio/Plugins/languages/en-us-97dfb1ba-50c4-4440-8dfa-6575daf543c8/plugin.lua index 31b9f0bd..7b26d329 100644 --- a/app/MindWork AI Studio/Plugins/languages/en-us-97dfb1ba-50c4-4440-8dfa-6575daf543c8/plugin.lua +++ b/app/MindWork AI Studio/Plugins/languages/en-us-97dfb1ba-50c4-4440-8dfa-6575daf543c8/plugin.lua @@ -8703,6 +8703,9 @@ UI_TEXT_CONTENT["AISTUDIO::LAYOUT::MAINLAYOUT::T3692372066"] = "Show details" -- Security notice UI_TEXT_CONTENT["AISTUDIO::LAYOUT::MAINLAYOUT::T4004397997"] = "Security notice" +-- All data sources are up to date. +UI_TEXT_CONTENT["AISTUDIO::LAYOUT::MAINLAYOUT::T4055300176"] = "All data sources are up to date." + -- Information UI_TEXT_CONTENT["AISTUDIO::LAYOUT::MAINLAYOUT::T4256323669"] = "Information" diff --git a/app/MindWork AI Studio/Tools/Services/DataSourceEmbeddingOverview.cs b/app/MindWork AI Studio/Tools/Services/DataSourceEmbeddingOverview.cs index 604e7862..032c9eff 100644 --- a/app/MindWork AI Studio/Tools/Services/DataSourceEmbeddingOverview.cs +++ b/app/MindWork AI Studio/Tools/Services/DataSourceEmbeddingOverview.cs @@ -1,3 +1,3 @@ namespace AIStudio.Tools.Services; -public sealed record DataSourceEmbeddingOverview(bool IsVisible, DataSourceEmbeddingState State, int IndexedFiles, int TotalFiles, int FailedFiles); +public sealed record DataSourceEmbeddingOverview(DataSourceEmbeddingState State, int IndexedFiles, int TotalFiles, int FailedFiles); diff --git a/app/MindWork AI Studio/Tools/Services/DataSourceEmbeddingService.cs b/app/MindWork AI Studio/Tools/Services/DataSourceEmbeddingService.cs index 1cc8ac61..086b2f75 100644 --- a/app/MindWork AI Studio/Tools/Services/DataSourceEmbeddingService.cs +++ b/app/MindWork AI Studio/Tools/Services/DataSourceEmbeddingService.cs @@ -95,7 +95,6 @@ public sealed partial class DataSourceEmbeddingService(SettingsManager settingsM { var total = Math.Max(activeStatus.TotalFiles, 1); return new( - true, activeStatus.State, activeStatus.IndexedFiles, total, @@ -106,9 +105,9 @@ public sealed partial class DataSourceEmbeddingService(SettingsManager settingsM .FirstOrDefault(status => status.State is DataSourceEmbeddingState.FAILED || status.FailedFiles > 0); if (failedStatus is not null) - return new(true, DataSourceEmbeddingState.FAILED, failedStatus.IndexedFiles, failedStatus.TotalFiles, failedStatus.FailedFiles); + return new(DataSourceEmbeddingState.FAILED, failedStatus.IndexedFiles, failedStatus.TotalFiles, failedStatus.FailedFiles); - return new(false, DataSourceEmbeddingState.COMPLETED, 0, 0, 0); + return new(DataSourceEmbeddingState.COMPLETED, 0, 0, 0); } public Task QueueAllInternalDataSourcesAsync()