From 211f8acbddd87bf0ae30ce5c8f50e8d089f57835 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Mon, 27 Oct 2025 15:17:20 +0100 Subject: [PATCH] Added the "attach documents" component --- .../DocumentAnalysisAssistant.razor | 2 +- .../DocumentAnalysisAssistant.razor.cs | 13 +-- .../Assistants/I18N/allTexts.lua | 9 ++ .../Components/AttachDocuments.razor | 15 ++++ .../Components/AttachDocuments.razor.cs | 88 +++++++++++++++++++ 5 files changed, 120 insertions(+), 7 deletions(-) create mode 100644 app/MindWork AI Studio/Components/AttachDocuments.razor create mode 100644 app/MindWork AI Studio/Components/AttachDocuments.razor.cs diff --git a/app/MindWork AI Studio/Assistants/DocumentAnalysis/DocumentAnalysisAssistant.razor b/app/MindWork AI Studio/Assistants/DocumentAnalysis/DocumentAnalysisAssistant.razor index 18c0e258..febcbc63 100644 --- a/app/MindWork AI Studio/Assistants/DocumentAnalysis/DocumentAnalysisAssistant.razor +++ b/app/MindWork AI Studio/Assistants/DocumentAnalysis/DocumentAnalysisAssistant.razor @@ -68,6 +68,6 @@ else - TODO + \ No newline at end of file diff --git a/app/MindWork AI Studio/Assistants/DocumentAnalysis/DocumentAnalysisAssistant.razor.cs b/app/MindWork AI Studio/Assistants/DocumentAnalysis/DocumentAnalysisAssistant.razor.cs index 3a5a10b9..f6b1b0d6 100644 --- a/app/MindWork AI Studio/Assistants/DocumentAnalysis/DocumentAnalysisAssistant.razor.cs +++ b/app/MindWork AI Studio/Assistants/DocumentAnalysis/DocumentAnalysisAssistant.razor.cs @@ -33,7 +33,7 @@ public partial class DocumentAnalysisAssistant : AssistantBaseCore true; - protected override string SubmitText => T("Analyze document"); + protected override string SubmitText => T("Analyze documents"); protected override Func SubmitAction => this.Analyze; @@ -99,10 +99,9 @@ public partial class DocumentAnalysisAssistant : AssistantBaseCore(Event.SEND_TO_DOCUMENT_ANALYSIS_ASSISTANT).FirstOrDefault(); - // if (deferredContent is not null) - #warning Add handling of deferred content -> load into input area - //this. + var receivedDeferredContent = MessageBus.INSTANCE.CheckDeferredMessages(Event.SEND_TO_DOCUMENT_ANALYSIS_ASSISTANT).FirstOrDefault(); + if (receivedDeferredContent is not null) + this.deferredContent = receivedDeferredContent; await base.OnInitializedAsync(); } @@ -137,6 +136,8 @@ public partial class DocumentAnalysisAssistant : AssistantBaseCore loadedDocumentPaths = []; private bool IsNoPolicySelectedOrProtected => this.selectedPolicy is null || this.selectedPolicy.IsProtected; diff --git a/app/MindWork AI Studio/Assistants/I18N/allTexts.lua b/app/MindWork AI Studio/Assistants/I18N/allTexts.lua index a1e5bacf..af004e3c 100644 --- a/app/MindWork AI Studio/Assistants/I18N/allTexts.lua +++ b/app/MindWork AI Studio/Assistants/I18N/allTexts.lua @@ -1459,6 +1459,15 @@ UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T4188329028"] = "No, kee -- Open Settings UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ASSISTANTBLOCK::T1172211894"] = "Open Settings" +-- Images are not supported yet +UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ATTACHDOCUMENTS::T298062956"] = "Images are not supported yet" + +-- Executables are not allowed +UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ATTACHDOCUMENTS::T4167762413"] = "Executables are not allowed" + +-- Select a file to attach +UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ATTACHDOCUMENTS::T595772870"] = "Select a file to attach" + -- Changelog UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHANGELOG::T3017574265"] = "Changelog" diff --git a/app/MindWork AI Studio/Components/AttachDocuments.razor b/app/MindWork AI Studio/Components/AttachDocuments.razor new file mode 100644 index 00000000..f86d4aa8 --- /dev/null +++ b/app/MindWork AI Studio/Components/AttachDocuments.razor @@ -0,0 +1,15 @@ +@inherits MSGComponentBase + + + + + Drag and drop files here or click to attach documents. + + @foreach (var fileInfo in this.DocumentPaths.Select(file => new FileInfo(file))) + { + + } + + \ No newline at end of file diff --git a/app/MindWork AI Studio/Components/AttachDocuments.razor.cs b/app/MindWork AI Studio/Components/AttachDocuments.razor.cs new file mode 100644 index 00000000..cf1b88cc --- /dev/null +++ b/app/MindWork AI Studio/Components/AttachDocuments.razor.cs @@ -0,0 +1,88 @@ +using AIStudio.Tools.Rust; +using AIStudio.Tools.Services; + +using Microsoft.AspNetCore.Components; + +namespace AIStudio.Components; + +public partial class AttachDocuments : MSGComponentBase +{ + [Parameter] + public List DocumentPaths { get; set; } = []; + + [Parameter] + public EventCallback> DocumentPathsChanged { get; set; } + + [Parameter] + public Func, Task> OnChange { get; set; } = _ => Task.CompletedTask; + + [Inject] + private RustService RustService { get; init; } = null!; + + #region Overrides of MSGComponentBase + + protected override async Task OnInitializedAsync() + { + this.ApplyFilters([], [ Event.TAURI_EVENT_RECEIVED ]); + await base.OnInitializedAsync(); + } + + protected override async Task ProcessIncomingMessage(ComponentBase? sendingComponent, Event triggeredEvent, T? data) where T : default + { + switch (triggeredEvent) + { + case Event.TAURI_EVENT_RECEIVED when data is TauriEvent { EventType: TauriEventType.FILE_DROP_HOVERED }: + this.SetDragClass(); + break; + + case Event.TAURI_EVENT_RECEIVED when data is TauriEvent { EventType: TauriEventType.FILE_DROP_DROPPED, Payload: var paths }: + this.ClearDragClass(); + foreach (var path in paths) + this.DocumentPaths.Add(path); + await this.DocumentPathsChanged.InvokeAsync(this.DocumentPaths); + await this.OnChange(this.DocumentPaths); + break; + + case Event.TAURI_EVENT_RECEIVED when data is TauriEvent { EventType: TauriEventType.FILE_DROP_CANCELED }: + this.ClearDragClass(); + break; + } + } + + #endregion + + private const string DEFAULT_DRAG_CLASS = "relative rounded-lg border-2 border-dashed pa-4 mt-4 mud-width-full mud-height-full"; + + private string dragClass = DEFAULT_DRAG_CLASS; + + private async Task AddFilesManually() + { + var selectedFile = await this.RustService.SelectFile(T("Select a file to attach")); + if (selectedFile.UserCancelled) + return; + + if (!File.Exists(selectedFile.SelectedFilePath)) + return; + + var ext = Path.GetExtension(selectedFile.SelectedFilePath).TrimStart('.'); + if (Array.Exists(FileTypeFilter.Executables.FilterExtensions, x => x.Equals(ext, StringComparison.OrdinalIgnoreCase))) + { + await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.AppBlocking, T("Executables are not allowed"))); + return; + } + + if (Array.Exists(FileTypeFilter.AllImages.FilterExtensions, x => x.Equals(ext, StringComparison.OrdinalIgnoreCase))) + { + await MessageBus.INSTANCE.SendWarning(new(Icons.Material.Filled.ImageNotSupported, T("Images are not supported yet"))); + return; + } + + this.DocumentPaths.Add(selectedFile.SelectedFilePath); + await this.DocumentPathsChanged.InvokeAsync(this.DocumentPaths); + await this.OnChange(this.DocumentPaths); + } + + private void SetDragClass() => this.dragClass = $"{DEFAULT_DRAG_CLASS} mud-border-primary"; + + private void ClearDragClass() => this.dragClass = DEFAULT_DRAG_CLASS; +} \ No newline at end of file