[feat:] initial wiki service implementation (basic, no editing, wrong directory- and saving-logic)

This commit is contained in:
2026-01-13 18:31:41 +01:00
parent c760ef0936
commit aeb4092f28
3 changed files with 180 additions and 41 deletions

View File

@@ -25,6 +25,17 @@
<PackageReference Include="PdfSharp" Version="6.1.1" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Markdig" Version="0.30.3" />
<PackageReference Include="AvaloniaEdit" Version="0.10.12" />
</ItemGroup>
<ItemGroup>
<None Include="wiki\**\*.md">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<None Remove="assets\icon.ico" />
<AvaloniaResource Include="assets\icon.ico">

View File

@@ -247,14 +247,42 @@
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem IsEnabled="False">
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<LucideIcon Kind="LibraryBig" Width="32" Height="32" Size="32" />
<Label FontSize="20" Content="Wiki" VerticalContentAlignment="Center" />
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem IsEnabled="True">
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<LucideIcon Kind="LibraryBig" Width="32" Height="32" Size="32" />
<Label FontSize="20" Content="Wiki" VerticalContentAlignment="Center" />
</StackPanel>
</TabItem.Header>
<Grid ColumnDefinitions="300,*">
<Border Grid.Column="0" Background="#FFF" BorderBrush="#DDD" BorderThickness="0,0,1,0">
<StackPanel>
<TextBlock Text="Wiki" FontSize="18" Margin="12" />
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<TreeView Name="NavTree" Margin="8" />
</ScrollViewer>
</StackPanel>
</Border>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Margin="8" Grid.Row="0">
<Button Name="EditButton" Content="Edit" IsEnabled="False" Width="80" Margin="0,0,8,0" />
<Button Name="OpenFolderButton" Content="Open Folder" Width="100" />
</StackPanel>
<Border Grid.Row="1" Margin="8" BorderBrush="#DDD" BorderThickness="1" CornerRadius="4">
<ScrollViewer>
<StackPanel Name="PreviewPanel" Margin="8" />
</ScrollViewer>
</Border>
</Grid>
</Grid>
</TabItem>
<TabItem IsEnabled="True">
<TabItem.Header>
<StackPanel Orientation="Horizontal">
@@ -273,18 +301,29 @@
<StackPanel Orientation="Vertical">
<Grid ColumnDefinitions="400,*">
<Label Grid.Column="0">config-Datei</Label>
<StackPanel Grid.Column="1" Orientation="Horizontal" Spacing="5">
<TextBox x:Name="TbConfigPath" HorizontalAlignment="Stretch"
Watermark="/home/username/.config/logofclient/config.json" />
<Button>
<Button.Content>
<StackPanel Orientation="Horizontal">
<LucideIcon Kind="File" Width="16" Height="16" Size="16" />
<Label Content="Öffnen..." VerticalContentAlignment="Center" />
<StackPanel Grid.Column="1" Orientation="Vertical" Spacing="5">
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBox x:Name="TbConfigPath" HorizontalAlignment="Stretch"
Watermark="/home/username/.config/logofclient/config.json" />
<Button>
<Button.Content>
<StackPanel Orientation="Horizontal">
<LucideIcon Kind="File" Width="16" Height="16" Size="16" />
<Label Content="Öffnen..." VerticalContentAlignment="Center" />
</StackPanel>
</Button.Content>
</Button>
</StackPanel>
<Grid ColumnDefinitions="200,*" Margin="0,6,0,0">
<Label Grid.Column="0" VerticalAlignment="Center">Wiki storage</Label>
<StackPanel Grid.Column="1" Orientation="Horizontal" Spacing="5">
<TextBox x:Name="TbWikiPath" HorizontalAlignment="Stretch"
Watermark="./wiki or /absolute/path/to/wiki" />
<Button x:Name="BtnWikiChoose">Auswählen</Button>
</StackPanel>
</Button.Content>
</Button>
</StackPanel>
</Grid>
</StackPanel>
</Grid>
</StackPanel>
</TabItem>

View File

@@ -5,6 +5,7 @@ using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Platform.Storage;
using Logof_Client.Wiki;
namespace Logof_Client;
@@ -12,6 +13,8 @@ public partial class MainWindow : Window
{
public static MainWindow _instance;
private WikiService _wikiService;
private Country _selectedCountry;
private bool _suppressCountryRefresh;
public Uri filePath;
@@ -31,6 +34,31 @@ public partial class MainWindow : Window
RefreshCountryView();
// Initialize wiki integration
_wikiService = new WikiService();
try
{
PopulateNavTree();
NavTree.SelectionChanged += NavTree_SelectionChanged;
OpenFolderButton.Click += OpenFolderButton_Click;
EditButton.Click += EditButton_Click;
// populate wiki settings UI if present
try
{
if (!string.IsNullOrWhiteSpace(Global._instance.wiki_storage_path))
TbWikiPath.Text = Global._instance.wiki_storage_path;
}
catch { }
try
{
BtnWikiChoose.Click += BtnWikiChoose_Click;
}
catch { }
}
catch { }
//Thread.Sleep(3000);
//Show();
}
@@ -120,7 +148,6 @@ public partial class MainWindow : Window
new FilePickerFileType(".csv-Datei")
{
Patterns = new[] { "*.csv" }
//Patterns = new[] { "*" }
}
}
});
@@ -139,23 +166,7 @@ public partial class MainWindow : Window
return;
}
//var set = new KasAddressList("");
//foreach (var adset in Settings._instance.addressSets.addresses)
//if (adset.ID == KasAddressList.GetIDByAddressSetListItem(LstCustomerAdressSets.SelectedItem.ToString()))
StartAddressCheck(KasAddressList.GetIDByAddressSetListItem(LstCustomerAdressSets.SelectedItem.ToString()));
// var result = DataImport.ImportKasAddressList(filePath);
// if (result.Item1)
// {
// var check_result = new AddressCheck().Perform(result.Item2);
// foreach (var item in check_result.Result)
// {
// Console.WriteLine();
// Console.Write(item.Item1 + " ");
// foreach (var error in item.Item2) Console.Write(error + ", ");
// }
// }
}
private void BtnCombine_OnClick(object? sender, RoutedEventArgs e)
@@ -197,7 +208,6 @@ public partial class MainWindow : Window
//filePath = file[0].Path;
foreach (var f in file) address_list.Add(DataImport.ImportKasAddressList(f.Path).Item2);
progressWindow.Show(_instance);
var processor = new CombineAddresses(progressWindow);
@@ -205,10 +215,85 @@ public partial class MainWindow : Window
progressWindow.Close();
//File.WriteAllText(OpenSettingsSaveAsDialog().Result,
//new CsvBuilder(
//"refsid,anrede,titel,vorname,adel,name,namezus,anredzus,strasse,strasse2,plz,ort,land,pplz,postfach,name1,name2,name3,name4,name5,funktion,funktion2,abteilung,funktionad,lastupdate",
//result).BuildKas());
}
private async void NavTree_SelectionChanged(object? sender, SelectionChangedEventArgs e)
{
if (NavTree.SelectedItem is TreeViewItem t && t.Tag is WikiItem item && !item.IsFolder)
{
var text = await _wikiService.LoadFileContentAsync(item.Path);
try
{
PreviewPanel.Children.Clear();
var rendered = MarkdownRenderer.Render(text ?? string.Empty);
PreviewPanel.Children.Add(rendered);
}
catch
{
// fallback: plain text
PreviewPanel.Children.Clear();
PreviewPanel.Children.Add(new TextBlock { Text = text ?? string.Empty });
}
EditButton.IsEnabled = true;
}
}
private void PopulateNavTree()
{
var roots = _wikiService.GetRootItems();
var nodes = new List<TreeViewItem>();
foreach (var r in roots) nodes.Add(BuildNode(r));
NavTree.ItemsSource = nodes;
}
private TreeViewItem BuildNode(WikiItem item)
{
var node = new TreeViewItem { Header = item.Name, Tag = item };
if (item.IsFolder)
{
foreach (var c in item.Children)
{
node.Items.Add(BuildNode(c));
}
}
return node;
}
private void OpenFolderButton_Click(object? sender, RoutedEventArgs e)
{
var path = _wikiService.WikiRootFullPath;
if (!System.IO.Directory.Exists(path)) return;
try
{
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
{
FileName = path,
UseShellExecute = true
});
}
catch { }
}
private async void BtnWikiChoose_Click(object? sender, RoutedEventArgs e)
{
var top = GetTopLevel(this);
var folder = await top.StorageProvider.OpenFolderPickerAsync(new Avalonia.Platform.Storage.FolderPickerOpenOptions
{
Title = "Choose wiki folder",
AllowMultiple = false
});
if (folder == null || folder.Count == 0) return;
var chosen = folder[0].Path;
TbWikiPath.Text = chosen.ToString();
Global._instance.wiki_storage_path = chosen.ToString();
Global.Save();
// reinit wiki service and reload tree
_wikiService = new WikiService();
PopulateNavTree();
}
private async Task<string> OpenSettingsSaveAsDialog()
@@ -317,6 +402,10 @@ public partial class MainWindow : Window
}
}
private async void EditButton_Click(object? sender, RoutedEventArgs e)
{
await MessageBox.Show(this, "Edit feature is currently disabled.", "Edit Disabled");
}
public void RefreshCustomerItems(int index = 0)
{
if (LstCustomers.Items.Count > 0)