Compare commits

...

7 Commits

5 changed files with 264 additions and 360 deletions

View File

@@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PrototypWPFHAG" xmlns:local="clr-namespace:PrototypWPFHAG"
StartupUri="MainWindow.xaml"> StartupUri="SearchWindow.xaml">
<Application.Resources> <Application.Resources>
<ResourceDictionary> <ResourceDictionary>
<ResourceDictionary.MergedDictionaries> <ResourceDictionary.MergedDictionaries>

View File

@@ -28,10 +28,6 @@
<PasswordBox Width="170" Height="30" Margin="0,5,34,0" x:Name="PasswordTextBox" <PasswordBox Width="170" Height="30" Margin="0,5,34,0" x:Name="PasswordTextBox"
PasswordChanged="PasswordTextBox_PasswordChanged"/> PasswordChanged="PasswordTextBox_PasswordChanged"/>
<<<<<<< HEAD
<!-- 登录按钮 -->
<Button Height="30" Width="100" Content="Log in" Margin="0,20,0,0" Click="LoginButton_Click" />
=======
<!-- Textbox for visible password (hidden at default) --> <!-- Textbox for visible password (hidden at default) -->
<TextBox Width="170" Height="30" Margin="0,5,34,0" x:Name="PasswordVisibleTextBox" <TextBox Width="170" Height="30" Margin="0,5,34,0" x:Name="PasswordVisibleTextBox"
Visibility="Collapsed" IsReadOnly="True"/> Visibility="Collapsed" IsReadOnly="True"/>
@@ -45,7 +41,6 @@
<!-- Login Button --> <!-- Login Button -->
<Button Height="30" Width="100" Content="Zur Suche" Margin="0,20,0,0" <Button Height="30" Width="100" Content="Zur Suche" Margin="0,20,0,0"
Click="loginButton_Click" IsDefault="True" /> Click="loginButton_Click" IsDefault="True" />
>>>>>>> 1195250b98172d34b8c49b85a81c21d1f26cdbac
</StackPanel> </StackPanel>
</Border> </Border>
</Grid> </Grid>

View File

@@ -1,6 +1,4 @@
using System.Data; using System.Data;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text; using System.Text;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
@@ -25,14 +23,6 @@ public partial class MainWindow : MetroWindow
public MainWindow() public MainWindow()
{ {
InitializeComponent(); InitializeComponent();
<<<<<<< HEAD
//TestConnection();
//Console.ReadKey();
}
private static void TestConnection()
=======
} }
private void Window_Loaded(object sender, RoutedEventArgs e) private void Window_Loaded(object sender, RoutedEventArgs e)
@@ -46,7 +36,6 @@ public partial class MainWindow : MetroWindow
} }
private string ValidateUser(string username, string password) private string ValidateUser(string username, string password)
>>>>>>> 1195250b98172d34b8c49b85a81c21d1f26cdbac
{ {
using (NpgsqlConnection con = GetConnection()) using (NpgsqlConnection con = GetConnection())
{ {
@@ -79,15 +68,8 @@ public partial class MainWindow : MetroWindow
} }
} }
} }
<<<<<<< HEAD
}
private static NpgsqlConnection GetConnection()
{
return new NpgsqlConnection(@"Server=localhost;Port=7854;User Id=postgres;Database=postgres;");
=======
return "Erfolgreich"; return "Erfolgreich";
>>>>>>> 1195250b98172d34b8c49b85a81c21d1f26cdbac
} }
private void ShowPasswordButton_PreviewMouseDown(object sender, RoutedEventArgs e) private void ShowPasswordButton_PreviewMouseDown(object sender, RoutedEventArgs e)

View File

@@ -1,204 +1,153 @@
<mah:MetroWindow xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls" <mah:MetroWindow xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
x:Class="PrototypWPFHAG.SearchWindow" x:Class="PrototypWPFHAG.SearchWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PrototypWPFHAG" xmlns:local="clr-namespace:PrototypWPFHAG"
Title="PDF-Verwaltung (Admin)" Height="600" Width="1000" Title="PDF-Verwaltung (Admin)"
WindowTitleBrush="FireBrick" Height="600" Width="1000"
Icon="pack://application:,,,/Images/databaseicon.png"> MinWidth="800" MinHeight="500"
<Grid> WindowTitleBrush="FireBrick"
<!-- 左侧垂直布局 --> Icon="pack://application:,,,/Images/databaseicon.png"
<Grid.ColumnDefinitions> ResizeMode="CanResizeWithGrip"
<ColumnDefinition Width="56.527"/> WindowStartupLocation="CenterScreen">
<ColumnDefinition Width="143.473"/>
<!-- 左侧固定宽度 -->
<ColumnDefinition Width="*"/>
<!-- 右侧占满剩余空间 -->
</Grid.ColumnDefinitions>
<!-- 左侧区域 --> <Border BorderBrush="FireBrick" BorderThickness="3">
<Border <Grid>
BorderBrush="FireBrick" <Grid.ColumnDefinitions>
BorderThickness="3" Padding="20" <ColumnDefinition Width="500" MinWidth="400"/>
Grid.ColumnSpan="3" <ColumnDefinition Width="*"/>
/> </Grid.ColumnDefinitions>
<StackPanel
Orientation="Vertical"
Margin="10,10,772,10"
Grid.ColumnSpan="3">
<Grid
Margin="0,0,0,10"
Height="85">
<Grid.ColumnDefinitions>
<ColumnDefinition
Width="*"
/>
<ColumnDefinition
Width="Auto"
/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition
Height="Auto"
/>
<RowDefinition
Height="Auto"
/>
</Grid.RowDefinitions>
<Border <!-- Linke Seite -->
BorderBrush="Gray" <Border Grid.Column="0" Margin="10" Padding="10">
BorderThickness="1" <Grid>
Margin="5,10,0,-85" Grid.Row="1"> <Grid.RowDefinitions>
<Canvas <RowDefinition Height="Auto"/>
x:Name="PdfDropCanvas" <!-- Drag & Drop -->
Margin="5,0,0,-24" <RowDefinition Height="Auto"/>
Grid.RowSpan="2" <!-- Upload/Auswahl-Buttons -->
AllowDrop="True" <RowDefinition Height="Auto"/>
Background="Transparent" <!-- Suchmodus -->
DragEnter="PdfDropCanvas_DragEnter" <RowDefinition Height="Auto"/>
Drop="PdfDropCanvas_Drop"> <!-- Suchfeld -->
<RowDefinition Height="*"/>
<!-- Suchergebnisse -->
<RowDefinition Height="Auto"/>
<!-- Status -->
<RowDefinition Height="Auto"/>
<!-- Zurück-Button -->
</Grid.RowDefinitions>
<TextBlock <!-- Drag & Drop Bereich -->
x:Name="DropHintText" <Border Grid.Row="0" Height="75" Margin="0,5"
Text="PDF hier rein ziehen" BorderBrush="Gray" BorderThickness="1">
HorizontalAlignment="Center" <Grid Background="Transparent" AllowDrop="True"
VerticalAlignment="Center" DragEnter="PdfDropCanvas_DragEnter"
Foreground="Gray" Drop="PdfDropCanvas_Drop">
/> <TextBlock x:Name="DropHintText" Text="PDF hier rein ziehen"
VerticalAlignment="Center" HorizontalAlignment="Center"/>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<Image x:Name="PdfIcon" Source="pack://application:,,,/Images/pdf-icon.png"
Width="25" Height="25" Visibility="Collapsed"/>
<TextBlock x:Name="PdfFileNameText" Margin="10"
TextWrapping="Wrap" Visibility="Collapsed"/>
</StackPanel>
</Grid>
</Border>
<!-- Vorschau-Elemente (unsichtbar, bis eine Datei abgelegt wird) --> <!-- Upload/Auswahl-Buttons -->
<Image <StackPanel Grid.Row="1" Orientation="Horizontal" Margin="0,10">
x:Name="PdfIcon" <Button Content="PDF hochladen"
Source="pack://application:,,,/Images/pdf-icon.png" Width="210" Height="30"
Width="25" Height="25" Background="LightGreen"
Margin="0,5,0,0" Click="UploadButton_Click"/>
Visibility="Collapsed"
/>
<TextBlock
x:Name="PdfFileNameText"
Margin="40,10,0,0"
Visibility="Collapsed"
/>
</Canvas>
</Border>
<Button Content="PDF auswählen"
Width="210" Height="30" Margin="40,0,0,0"
Background="Firebrick"
Click="ChoosePdfButton_Click"/>
</StackPanel>
</Grid> <!-- Suchmodus-Auswahl -->
<StackPanel Grid.Row="2" Orientation="Horizontal" Margin="0,10">
<RadioButton x:Name="SearchByIdRadio"
Content="ID"
Margin="5"
IsChecked="True"/>
<RadioButton x:Name="SearchByTextRadio"
Content="Text"
Margin="5"/>
</StackPanel>
<!-- PDFField --> <!-- Suchfeld -->
<Grid Margin="0,0,0,10"> <StackPanel Grid.Row="3" Margin="0,10">
<Grid.ColumnDefinitions> <TextBox x:Name="SearchTextBox"
<ColumnDefinition Margin="0,0,0,5"
Width="*" HorizontalAlignment="Stretch"/>
/> <Button Content="Suchen"
<ColumnDefinition x:Name="SearchButton"
Width="Auto" Height="30"
/> HorizontalAlignment="Stretch"
</Grid.ColumnDefinitions> Click="SearchButton_Click"/>
<Button </StackPanel>
Content="PDF hochladen"
Width="auto" Height="30"
Margin="5,0,0,0"
Background="LightGreen"
Click="UploadButton_Click"
/>
</Grid> <!-- Suchergebnisse -->
<ListBox Grid.Row="4"
x:Name="SearchResultsListBox"
Margin="0,10"
DisplayMemberPath="DocumentName"
ScrollViewer.VerticalScrollBarVisibility="Auto"
SelectionMode="Extended"
SelectionChanged="SearchResultsListBox_SelectionChanged"/>
<StackPanel Orientation="Horizontal" Margin="5,10"> <!-- Status & Fortschritt -->
<RadioButton x:Name="SearchByIdRadio" Content="ID" IsChecked="True"/> <StackPanel Grid.Row="5" Orientation="Vertical" Margin="0,10">
<RadioButton x:Name="SearchByTextRadio" Content="Text" Margin="10,0"/> <TextBlock x:Name="UploadStatusText" TextAlignment="Center"/>
</StackPanel> <ProgressBar x:Name="UploadProgressBar"
Height="10"
Minimum="0"
Maximum="100"
Visibility="Collapsed"/>
</StackPanel>
<TextBox <!-- Zurück-Button -->
x:Name="SearchTextBox" <Button Grid.Row="6"
Margin="5,0,0,0" Content="Zurück zur Anmeldung"
/> Height="30" Margin="0,10"
HorizontalAlignment="Stretch"
Background="#ffd64f"
Click="BackToLogIn_Click"/>
</Grid>
</Border>
<Button <!-- Rechte Seite -->
Content="Suchen" <Border Grid.Column="1" Margin="10">
x:Name="SearchButton" <Grid>
Click="SearchButton_Click" <Grid.RowDefinitions>
Margin="5,10,0,10" <RowDefinition Height="Auto"/>
/> <RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- ListField --> <Label Content="PDF-Inhalt:" Margin="0,0,0,5"/>
<ListBox
x:Name="SearchResultsListBox"
DisplayMemberPath="Filename"
Margin="5,0,0,0"
ItemsSource="{Binding}"
SelectionMode="Extended"
SelectionChanged="SearchResultsListBox_SelectionChanged"
/>
<TextBlock <TextBox Grid.Row="1"
x:Name="UploadStatusText" x:Name="ContentTextBox"
TextAlignment="Center" Margin="0,35,0,35" Height="27" TextWrapping="Wrap"
/> AcceptsReturn="True"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto"
IsReadOnly="True"/>
<ProgressBar <Button Grid.Row="2"
x:Name="UploadProgressBar" Content="Löschen"
Height="10" Width="100" Height="30"
Minimum="0" Maximum="100" Margin="0,10"
Visibility="Collapsed" HorizontalAlignment="Center"
Margin="0,20,0,0" Background="Firebrick"
/> Click="DeleteButton_Click"/>
</Grid>
<Button </Border>
Content="Zurück zur Anmeldung"
Click="BackToLogIn_Click"
Margin="5,10,0,0"
Height="30"
Background="#ffd64f"
/>
</StackPanel>
<!-- 右侧区域 -->
<Grid
Grid.Column="2"
Margin="60,10,10,10">
<Label
Content="PDF-Inhalt:"
HorizontalAlignment="Left"
Margin="0,2,0,8"
/>
<ScrollViewer
x:Name="ContentScrollViewer"
Margin="0,0,0,35"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
<TextBox
x:Name="ContentTextBox"
Text="{Binding SelectedDocument.Content}"
IsReadOnly="True"
TextWrapping="Wrap"
AcceptsReturn="True"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto"
Margin="5,25, 0, 35"
Height="Auto"
MinHeight="494"
/>
</ScrollViewer>
<!-- 删除按钮 -->
<Button
Content="Löschen"
Width="100"
Height="30"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Background="Firebrick"
Click="DeleteButton_Click"
/>
</Grid> </Grid>
</Grid> </Border>
</mah:MetroWindow> </mah:MetroWindow>

View File

@@ -1,14 +1,17 @@
using MahApps.Metro.Controls; using MahApps.Metro.Controls;
using System.ComponentModel;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Text; using System.Text;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using System.Web; using System.Web;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Documents;
namespace PrototypWPFHAG namespace PrototypWPFHAG
@@ -29,6 +32,7 @@ namespace PrototypWPFHAG
private readonly PdfServiceClient _pdfServiceClient = new(); private readonly PdfServiceClient _pdfServiceClient = new();
private const string BaseUrl = "http://localhost:8000"; // Microservice-URL private const string BaseUrl = "http://localhost:8000"; // Microservice-URL
private string _selectedPdfPath; private string _selectedPdfPath;
private List<string> _selectedPdfPaths = new List<string>();
public SearchWindow() public SearchWindow()
{ {
InitializeComponent(); InitializeComponent();
@@ -60,7 +64,7 @@ namespace PrototypWPFHAG
} }
else else
{ {
await SearchByTextAsync(); await SearchBySimilarityAsync();
} }
} }
catch (Exception ex) catch (Exception ex)
@@ -86,34 +90,43 @@ namespace PrototypWPFHAG
try try
{ {
var response = await _httpClient.GetAsync($"/documents/by-id/{documentId}"); var response = await _httpClient.GetAsync($"/documents/{documentId}");
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync(); var json = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<JsonElement>(json); var result = JsonSerializer.Deserialize<DocumentDetail>(json);
// Extrahiere das Array "documents"
var documents = result.GetProperty("documents");
if (documents.GetArrayLength() == 0)
{
MessageBox.Show("Dokument nicht gefunden");
return;
}
// Nimm das erste Element des Arrays
var document = documents[0];
// UI aktualisieren
await Dispatcher.InvokeAsync(() => await Dispatcher.InvokeAsync(() =>
{ {
SearchResultsListBox.ItemsSource = new List<SearchResult> SearchResultsListBox.ItemsSource = new List<DocumentDetail> { result };
ContentTextBox.Text = result.Content;
SearchResultsListBox.DisplayMemberPath = "DocumentName";
});
}
catch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.NotFound)
{ {
new SearchResult MessageBox.Show("Dokument nicht gefunden");
}
catch (Exception ex)
{
MessageBox.Show($"Fehler: {ex.Message}");
}
}
private async Task SearchBySimilarityAsync()
{
try
{
var encodedQuery = HttpUtility.UrlEncode(SearchTextBox.Text);
var response = await _httpClient.GetAsync($"/documents/search/similarity?query={encodedQuery}");
var json = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ApiResponse>(json);
await Dispatcher.InvokeAsync(() =>
{ {
Id = document.GetProperty("id").GetInt32(), SearchResultsListBox.ItemsSource = result?.Documents;
Filename = document.GetProperty("filename").GetString(), SearchResultsListBox.DisplayMemberPath = "DocumentName";
Content = document.GetProperty("content").GetString()
}
};
ContentTextBox.Text = document.GetProperty("content").GetString();
}); });
} }
catch (Exception ex) catch (Exception ex)
@@ -121,31 +134,6 @@ namespace PrototypWPFHAG
MessageBox.Show($"Fehler: {ex.Message}"); MessageBox.Show($"Fehler: {ex.Message}");
} }
} }
private async Task SearchByTextAsync()
{
try
{
var encodedQuery = Uri.EscapeDataString(SearchTextBox.Text);
var response = await _httpClient.GetAsync($"/documents/search?query={encodedQuery}");
var json = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<JsonElement>(json);
var documents = JsonSerializer.Deserialize<List<SearchResult>>(
result.GetProperty("documents").GetRawText());
MessageBox.Show($"Gefundene Dokumente: {documents?.Count}", "Debug");
SearchResultsListBox.ItemsSource = documents;
SearchResultsListBox.DisplayMemberPath = "Filename";
}
catch (Exception ex)
{
MessageBox.Show($"Fehler: {ex.Message}");
}
}
private void PdfDropCanvas_DragEnter(object sender, DragEventArgs e) private void PdfDropCanvas_DragEnter(object sender, DragEventArgs e)
{ {
@@ -166,18 +154,39 @@ namespace PrototypWPFHAG
e.Handled = true; e.Handled = true;
} }
private void ChoosePdfButton_Click(object sender, RoutedEventArgs e)
{
var openFileDialog = new Microsoft.Win32.OpenFileDialog
{
Filter = "PDF Files (*.pdf)|*.pdf",
Multiselect = true
};
if (openFileDialog.ShowDialog() == true)
{
_selectedPdfPaths.AddRange(openFileDialog.FileNames);
PdfIcon.Visibility = Visibility.Visible;
PdfFileNameText.Text = string.Join(", ", _selectedPdfPaths.Select(System.IO.Path.GetFileName));
PdfFileNameText.Visibility = Visibility.Visible;
DropHintText.Visibility = Visibility.Collapsed;
}
}
private void PdfDropCanvas_Drop(object sender, DragEventArgs e) private void PdfDropCanvas_Drop(object sender, DragEventArgs e)
{ {
if (e.Data.GetDataPresent(DataFormats.FileDrop)) if (e.Data.GetDataPresent(DataFormats.FileDrop))
{ {
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
_selectedPdfPath = files.FirstOrDefault(f => System.IO.Path.GetExtension(f).Equals(".pdf", StringComparison.OrdinalIgnoreCase)); var pdfFiles = files.Where(f => System.IO.Path.GetExtension(f).Equals(".pdf", StringComparison.OrdinalIgnoreCase)).ToList();
if (_selectedPdfPath != null) if (pdfFiles.Any())
{ {
// Vorschau anzeigen _selectedPdfPaths.AddRange(pdfFiles);
// 更新UI以显示所有文件
PdfIcon.Visibility = Visibility.Visible; PdfIcon.Visibility = Visibility.Visible;
PdfFileNameText.Text = System.IO.Path.GetFileName(_selectedPdfPath); PdfFileNameText.Text = string.Join(", ", _selectedPdfPaths.Select(System.IO.Path.GetFileName));
PdfFileNameText.Visibility = Visibility.Visible; PdfFileNameText.Visibility = Visibility.Visible;
DropHintText.Visibility = Visibility.Collapsed; DropHintText.Visibility = Visibility.Collapsed;
} }
@@ -192,19 +201,47 @@ namespace PrototypWPFHAG
[JsonPropertyName("document")] [JsonPropertyName("document")]
public DocumentDetail Document { get; set; } public DocumentDetail Document { get; set; }
[JsonPropertyName("documents")]
public List<DocumentDetail> Documents { get; set; }
} }
public class DocumentDetail public class DocumentDetail : INotifyPropertyChanged
{ {
[JsonPropertyName("id")] [JsonPropertyName("id")]
public int Id { get; set; } public int Id { get; set; }
[JsonPropertyName("filename")] [JsonPropertyName("document_name")]
public string Filename { get; set; } public string DocumentName { get; set; }
[JsonPropertyName("content")] [JsonPropertyName("content")]
public string Content { get; set; } public string Content { get; set; }
[JsonPropertyName("distance")]
public double Distance { get; set; }
private bool _isSelected;
public bool IsSelected
{
get => _isSelected;
set
{
if (_isSelected != value)
{
_isSelected = value;
OnPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
} }
public class ApiError public class ApiError
{ {
public string Detail { get; set; } public string Detail { get; set; }
@@ -212,66 +249,35 @@ namespace PrototypWPFHAG
private async void UploadButton_Click(object sender, RoutedEventArgs e) private async void UploadButton_Click(object sender, RoutedEventArgs e)
{ {
if (string.IsNullOrEmpty(_selectedPdfPath)) if (!_selectedPdfPaths.Any())
{ {
MessageBox.Show("Keine PDF ausgewählt!"); MessageBox.Show("Keine PDF ausgewählt!");
return; return;
} }
// UI zurücksetzen
UploadProgressBar.Visibility = Visibility.Visible; UploadProgressBar.Visibility = Visibility.Visible;
UploadProgressBar.Value = 0; UploadProgressBar.Value = 0;
UploadStatusText.Text = "Upload läuft..."; UploadStatusText.Text = "Upload läuft...";
try try
{ {
using (var httpClient = new HttpClient()) using var formData = new MultipartFormDataContent();
using (var fileStream = File.OpenRead(_selectedPdfPath))
foreach (var pdfPath in _selectedPdfPaths)
{ {
var progress = new Progress<float>(percent => var fileContent = new StreamContent(File.OpenRead(pdfPath));
{ formData.Add(fileContent, "files", Path.GetFileName(pdfPath));
Dispatcher.Invoke(() => }
{
UploadProgressBar.Value = percent * 100;
UploadStatusText.Text = $"Upload: {(int)(percent * 100)}%";
});
});
var content = new StreamContent(fileStream); var response = await _httpClient.PostAsync("/upload-pdfs/", formData);
var formData = new MultipartFormDataContent(); response.EnsureSuccessStatusCode();
formData.Add(content, "file", Path.GetFileName(_selectedPdfPath));
// Simulierter Fortschritt var json = await response.Content.ReadAsStringAsync();
for (int i = 0; i <= 100; i += 10) var result = JsonSerializer.Deserialize<ApiResponse>(json);
{
await Task.Delay(100);
((IProgress<float>)progress).Report(i / 100f);
}
var response = await httpClient.PostAsync($"{BaseUrl}/upload-pdf", formData); if (result?.Success == true)
{
if (response.IsSuccessStatusCode) UploadStatusText.Text = "Upload erfolgreich!";
{
// Erfolgsmeldung anzeigen
UploadStatusText.Text = "Erfolgreich hochgeladen!";
// Canvas zurücksetzen
Dispatcher.Invoke(() =>
{
PdfIcon.Visibility = Visibility.Collapsed;
PdfFileNameText.Visibility = Visibility.Collapsed;
DropHintText.Visibility = Visibility.Visible;
_selectedPdfPath = null;
});
// Erfolgsmeldung nach 3 Sekunden ausblenden
await Task.Delay(3000);
UploadStatusText.Text = string.Empty;
}
else
{
UploadStatusText.Text = "Fehler beim Upload";
}
} }
} }
catch (Exception ex) catch (Exception ex)
@@ -281,6 +287,10 @@ namespace PrototypWPFHAG
finally finally
{ {
UploadProgressBar.Visibility = Visibility.Collapsed; UploadProgressBar.Visibility = Visibility.Collapsed;
_selectedPdfPaths.Clear();
PdfIcon.Visibility = Visibility.Collapsed;
PdfFileNameText.Visibility = Visibility.Collapsed;
DropHintText.Visibility = Visibility.Visible;
} }
} }
private async void DeleteButton_Click(object sender, RoutedEventArgs e) private async void DeleteButton_Click(object sender, RoutedEventArgs e)
@@ -303,89 +313,57 @@ namespace PrototypWPFHAG
var deletedIds = new List<int>(); var deletedIds = new List<int>();
var errorIds = new List<int>(); var errorIds = new List<int>();
foreach (var item in SearchResultsListBox.SelectedItems.Cast<SearchResult>().ToList()) foreach (var item in SearchResultsListBox.SelectedItems.Cast<DocumentDetail>().ToList())
{ {
try try
{ {
var response = await _httpClient.DeleteAsync($"/documents/by-id/{item.Id}/delete"); var response = await _httpClient.DeleteAsync($"/documents/{item.Id}");
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {
deletedIds.Add(item.Id); deletedIds.Add(item.Id);
Debug.WriteLine($"Gelöscht: {item.Id}");
} }
else else
{ {
errorIds.Add(item.Id); errorIds.Add(item.Id);
var errorContent = await response.Content.ReadAsStringAsync();
Debug.WriteLine($"Fehler bei {item.Id}: {errorContent}");
} }
} }
catch (Exception ex) catch
{ {
errorIds.Add(item.Id); errorIds.Add(item.Id);
Debug.WriteLine($"Ausnahme: {ex.Message}");
} }
} }
// Aktualisiere die Liste unabhängig vom Suchmodus // Aktualisiere die Liste
if (SearchByIdRadio.IsChecked == true) if (SearchByIdRadio.IsChecked == true)
{ {
await SearchByIdAsync(); // Neu laden der ID-Suche await SearchByIdAsync();
} }
else else
{ {
await SearchByTextAsync(); // Neu laden der Textsuche await SearchBySimilarityAsync();
} }
// Feedback an Benutzer // Feedback
var message = new StringBuilder(); var message = new StringBuilder();
if (deletedIds.Count > 0) if (deletedIds.Count > 0) message.AppendLine($"{deletedIds.Count} Dokument(e) gelöscht.");
{ if (errorIds.Count > 0) message.AppendLine($"{errorIds.Count} Dokument(e) konnten nicht gelöscht werden.");
message.AppendLine($"{deletedIds.Count} Dokument(e) gelöscht.");
}
if (errorIds.Count > 0)
{
message.AppendLine($"{errorIds.Count} Dokument(e) konnten nicht gelöscht werden.");
}
MessageBox.Show(message.ToString()); MessageBox.Show(message.ToString());
} }
private async void SearchResultsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) private async void SearchResultsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{ {
if (SearchResultsListBox.SelectedItem is SearchResult selectedDocument) if (SearchResultsListBox.SelectedItem is DocumentDetail selected)
{ {
try try
{ {
var response = await _httpClient.GetAsync($"/documents/by-id/{selectedDocument.Id}"); var response = await _httpClient.GetAsync($"/documents/{selected.Id}/markdown");
var json = await response.Content.ReadAsStringAsync(); var content = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<JsonElement>(json); var result = JsonSerializer.Deserialize<JsonElement>(content);
// Sicherstellen, dass das "documents" Array existiert ContentTextBox.Text = result.GetProperty("document")
if (!result.TryGetProperty("documents", out var documents)) .GetProperty("content")
{ .GetString();
ContentTextBox.Text = "Ungültiges Antwortformat";
return;
}
// Sicherstellen, dass das Array mindestens ein Element hat
if (documents.GetArrayLength() == 0)
{
ContentTextBox.Text = "Dokument nicht gefunden";
return;
}
var document = documents[0];
// Sicherstellen, dass alle benötigten Felder existieren
if (!document.TryGetProperty("content", out var contentProp))
{
ContentTextBox.Text = "Dokumentinhalt fehlt";
return;
}
ContentTextBox.Text = contentProp.GetString();
Debug.WriteLine($"API-Antwort: {json}");
} }
catch (Exception ex) catch (Exception ex)
{ {