From ed52abfd376e0480ddfd6db084263a677c96d4ef Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Mon, 10 Aug 2026 17:10:55 +0200 Subject: [PATCH] Fixed the file preview showing an empty document while the file was still being read (#907) --- .../Assistants/I18N/allTexts.lua | 3 ++ .../Dialogs/DocumentCheckDialog.razor | 10 ++++ .../Dialogs/DocumentCheckDialog.razor.cs | 53 ++++++++++++++----- .../plugin.lua | 3 ++ .../plugin.lua | 3 ++ .../wwwroot/changelog/v26.8.1.md | 3 +- 6 files changed, 60 insertions(+), 15 deletions(-) diff --git a/app/MindWork AI Studio/Assistants/I18N/allTexts.lua b/app/MindWork AI Studio/Assistants/I18N/allTexts.lua index de185236..68813a98 100644 --- a/app/MindWork AI Studio/Assistants/I18N/allTexts.lua +++ b/app/MindWork AI Studio/Assistants/I18N/allTexts.lua @@ -5302,6 +5302,9 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T3688254408"] -- Your security policy UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T4081226330"] = "Your security policy" +-- Please wait while we load the content of your file. Depending on the file type and size, this may take a moment. +UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DOCUMENTCHECKDIALOG::T1205126512"] = "Please wait while we load the content of your file. Depending on the file type and size, this may take a moment." + -- Markdown View UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DOCUMENTCHECKDIALOG::T1373123357"] = "Markdown View" diff --git a/app/MindWork AI Studio/Dialogs/DocumentCheckDialog.razor b/app/MindWork AI Studio/Dialogs/DocumentCheckDialog.razor index f844abb9..62fea886 100644 --- a/app/MindWork AI Studio/Dialogs/DocumentCheckDialog.razor +++ b/app/MindWork AI Studio/Dialogs/DocumentCheckDialog.razor @@ -33,6 +33,16 @@ @T("The specified file could not be found. The file have been moved, deleted, renamed, or is otherwise inaccessible.") } + else if (this.isLoadingContent) + { + + @T("Please wait while we load the content of your file. Depending on the file type and size, this may take a moment.") + + + + + + } else if (this.loadFailureMessage is not null) { diff --git a/app/MindWork AI Studio/Dialogs/DocumentCheckDialog.razor.cs b/app/MindWork AI Studio/Dialogs/DocumentCheckDialog.razor.cs index d652660d..2406b5a3 100644 --- a/app/MindWork AI Studio/Dialogs/DocumentCheckDialog.razor.cs +++ b/app/MindWork AI Studio/Dialogs/DocumentCheckDialog.razor.cs @@ -25,7 +25,13 @@ public partial class DocumentCheckDialog : MSGComponentBase /// Set when reading the file failed, so the dialog shows the reason instead of empty content. /// private string? loadFailureMessage; - + + /// + /// True while we extract the file content. Reading happens after the first render, so the + /// dialog can tell the user that it is working instead of showing an empty document. + /// + private bool isLoadingContent; + [Inject] private RustService RustService { get; init; } = null!; @@ -35,24 +41,40 @@ public partial class DocumentCheckDialog : MSGComponentBase [Inject] private ILogger Logger { get; init; } = null!; + protected override async Task OnInitializedAsync() + { + // + // Decide before the first render whether we have to read the file at all. Images are shown + // as they are, a missing file shows its own message, and content a caller already handed + // us is reused instead of being extracted a second time: + // + this.isLoadingContent = + this.Document is not null && + !this.Document.IsImage && + this.Document.Exists && + string.IsNullOrWhiteSpace(this.FileContent); + + await base.OnInitializedAsync(); + } + protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender && this.Document is not null) { + if (!this.isLoadingContent) + return; + try { - if (!this.Document.IsImage) - { - var extraction = await UserFile.LoadFileData(this.Document.FilePath, this.RustService, this.DialogService); - this.FileContent = extraction.Content; + var extraction = await UserFile.LoadFileData(this.Document.FilePath, this.RustService, this.DialogService); + this.FileContent = extraction.Content; - // - // This dialog exists so the user can check what we hand to the AI. Showing an - // empty document when reading the file failed would answer that question wrong. - // - if (!extraction.HasUsableContent) - this.loadFailureMessage = extraction.ToUserMessage(this.Document.FileName); - } + // + // This dialog exists so the user can check what we hand to the AI. Showing an + // empty document when reading the file failed would answer that question wrong. + // + if (!extraction.HasUsableContent) + this.loadFailureMessage = extraction.ToUserMessage(this.Document.FileName); } catch (Exception ex) { @@ -60,8 +82,11 @@ public partial class DocumentCheckDialog : MSGComponentBase this.FileContent = string.Empty; this.loadFailureMessage = FileExtractionErrorCode.INTERNAL.ToUserMessage(this.Document.FileName); } - - this.StateHasChanged(); + finally + { + this.isLoadingContent = false; + this.StateHasChanged(); + } } else if (firstRender) this.Logger.LogWarning("Document check dialog opened without a valid file path."); 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 0f3c7329..28fb5a33 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 @@ -5304,6 +5304,9 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T3688254408"] -- Your security policy UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T4081226330"] = "Ihre Sicherheitsrichtlinie" +-- Please wait while we load the content of your file. Depending on the file type and size, this may take a moment. +UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DOCUMENTCHECKDIALOG::T1205126512"] = "Bitte warten Sie, während wir den Inhalt Ihrer Datei laden. Je nach Dateityp und -größe kann dies einen Moment dauern." + -- Markdown View UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DOCUMENTCHECKDIALOG::T1373123357"] = "Markdown-Ansicht" 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 0b861aa5..aa294bf6 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 @@ -5304,6 +5304,9 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T3688254408"] -- Your security policy UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T4081226330"] = "Your security policy" +-- Please wait while we load the content of your file. Depending on the file type and size, this may take a moment. +UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DOCUMENTCHECKDIALOG::T1205126512"] = "Please wait while we load the content of your file. Depending on the file type and size, this may take a moment." + -- Markdown View UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DOCUMENTCHECKDIALOG::T1373123357"] = "Markdown View" diff --git a/app/MindWork AI Studio/wwwroot/changelog/v26.8.1.md b/app/MindWork AI Studio/wwwroot/changelog/v26.8.1.md index 73dcff60..153072c4 100644 --- a/app/MindWork AI Studio/wwwroot/changelog/v26.8.1.md +++ b/app/MindWork AI Studio/wwwroot/changelog/v26.8.1.md @@ -7,8 +7,8 @@ - Added options for organizations to disable importing, sharing, and exporting plugins, with a separate option for configuration plugins. Organizations can now let people import assistants while keeping configurations to their IT department. - Added a priority for configuration plugins. Organizations that deploy several configurations can now decide which one wins: a configuration with a higher priority overrides the settings and providers of a lower one. This allows a company-wide base configuration that each department refines for itself. - Added a way for IT departments to try out a configuration before rolling it out. A configuration placed in the new `.config-tests` directory below the plugins directory acts like one your organization deployed, including the approval of assistant plugins, so a test shows exactly what colleagues will see later. No configuration server is needed for this. AI Studio empties that directory every time it starts, so a test configuration is valid for one session, and the information page reports it while it is active. The Enterprise IT documentation describes the whole procedure. -- Improved how your organization's configuration behaves when a configuration plugin is present but cannot be loaded, e.g. because of an error in the plugin. Such a plugin still manages your app, so its settings, providers, data sources, profiles, and chat templates now stay in place instead of being removed. - Added CSV and TSV files to the file types you can attach. AI Studio was already able to read them, but they could not be selected. +- Improved how your organization's configuration behaves when a configuration plugin is present but cannot be loaded, e.g. because of an error in the plugin. Such a plugin still manages your app, so its settings, providers, data sources, profiles, and chat templates now stay in place instead of being removed. - Improved reading large files from slow locations such as network drives. AI Studio now waits considerably longer before it gives up, and it tells you when it does. - Changed how approvals for assistant plugins combine when your organization deploys several configurations. They now add up, so a department can approve additional assistant plugins without repeating the approvals of the company-wide configuration. Previously, the last configuration replaced all earlier approvals, which silently required a new security check for those assistants. - Fixed attached files reaching the AI as empty documents when AI Studio could not read them. The AI then answered as if your file had no content, and nothing pointed to a problem. AI Studio now names the cause instead, for example, an unavailable network drive, a file another program is blocking, a protected PDF, or a scanned PDF without a text layer, and it no longer attaches such a file. @@ -21,6 +21,7 @@ - Fixed PDFs, text files, spreadsheets, and presentations requiring Pandoc. Only Word documents, OpenDocument text files, and HTML files need Pandoc, so every other file can now be attached and read without it. - Fixed attached files that are temporarily unavailable, disappearing from your message without a word. This could happen when a file was stored on a network drive. - Fixed the file preview showing an empty document when reading the file failed. It now shows what went wrong, so the preview again answers what AI Studio will hand to the AI. +- Fixed the file preview looking like an empty file while AI Studio was still reading it. Larger documents and PDFs need a moment to be read, and until now that moment looked like a file without any content. The preview now says that it is still loading and shows the content as soon as it is ready. - Fixed problems while reading files being missing from the log file after the first one. This made exactly those issues hard to track down that only appeared later on. - Fixed reset buttons in assistants. As you may have noticed in the Document Analysis Assistant, resetting it could leave content from the previous analysis visible. Reset buttons now clear previous results completely. - Fixed dropping files after you closed a dialog that accepts files itself. Such a dialog takes over dropped files while it is open, but never handed that role back when you closed it. Afterward, the chat and the assistants silently ignored dropped files until you switched to another page. Each time you opened such a dialog again, the problem got worse.