diff --git a/.idea/.idea.PSCHelpdesk/.idea/.name b/.idea/.idea.PSCHelpdesk/.idea/.name
deleted file mode 100644
index 6f7d947..0000000
--- a/.idea/.idea.PSCHelpdesk/.idea/.name
+++ /dev/null
@@ -1 +0,0 @@
-PSCHelpdesk
\ No newline at end of file
diff --git a/.idea/.idea.PSCHelpdesk/.idea/workspace.xml b/.idea/.idea.PSCHelpdesk/.idea/workspace.xml
index 678916a..37a5d83 100644
--- a/.idea/.idea.PSCHelpdesk/.idea/workspace.xml
+++ b/.idea/.idea.PSCHelpdesk/.idea/workspace.xml
@@ -11,18 +11,21 @@
-
+
+
+
+
+
+
+
-
-
-
-
+
@@ -34,19 +37,18 @@
-
+
-
-
-
-
-
-
+
+
+
+
+
@@ -56,6 +58,8 @@
+
+
@@ -81,7 +85,7 @@
-
-
+
+
@@ -210,7 +215,6 @@
-
@@ -243,6 +247,9 @@
+
+
+
@@ -274,19 +281,6 @@
-
- file://$PROJECT_DIR$/Shared/Setting/SettingsManager.cs
- 85
-
-
-
-
-
-
-
-
-
-
file://$PROJECT_DIR$/PSCHelpdesk/PSCHelpdesk/Views/SettingsGlobalView.axaml.cs
29
@@ -392,17 +386,56 @@
- file://$PROJECT_DIR$/FastBill/FastBill.cs
- 18
-
+ file://$PROJECT_DIR$/HetznerServer/ViewModels/ServerViewModel.cs
+ 99
+
-
+
-
+
-
+
+
+
+ file://$PROJECT_DIR$/FastBill/Api/Customers.cs
+ 20
+
+
+
+
+
+
+
+
+
+
+
+ file://$PROJECT_DIR$/FastBill/ViewModels/CustomerViewModel.cs
+ 28
+
+
+
+
+
+
+
+
+
+
+
+ file://$PROJECT_DIR$/FastBill/Api/Customers.cs
+ 18
+
+
+
+
+
+
+
+
+
diff --git a/FastBill/Api/Customers.cs b/FastBill/Api/Customers.cs
new file mode 100644
index 0000000..6baf5df
--- /dev/null
+++ b/FastBill/Api/Customers.cs
@@ -0,0 +1,26 @@
+using FastBill.Models;
+using RestSharp;
+using RestSharp.Authenticators;
+
+namespace FastBill.Api;
+
+public class Customers
+{
+ async public Task> SearchCustomer(Settings settings, string term)
+ {
+ var customers = new List();
+
+ var client = new RestClient("https://my.fastbill.com/");
+ var request = new RestRequest("api/1.0/api.php");
+ request.Authenticator = new HttpBasicAuthenticator(settings.EMail, settings.ApiKey);
+ request.RequestFormat = DataFormat.Json;
+ request.AddJsonBody(new { SERVICE = "customer.get", FILTER = new { TERM = term } });
+ var response = await client.ExecuteAsync>(request);
+ if (response.StatusCode == System.Net.HttpStatusCode.OK)
+ {
+ return response.Data;
+ }
+
+ return customers;
+ }
+}
\ No newline at end of file
diff --git a/FastBill/FastBill.cs b/FastBill/FastBill.cs
index b07aa51..67de7d2 100644
--- a/FastBill/FastBill.cs
+++ b/FastBill/FastBill.cs
@@ -1,4 +1,5 @@
using CommunityToolkit.Mvvm.DependencyInjection;
+using FastBill.Services;
using FastBill.ViewModels;
using FastBill.Views;
using PSCHelpdesk.Shared.Plugin;
@@ -16,6 +17,13 @@ public class FastBill: Contract
public void Configure()
{
+ var menuService = Ioc.Default.GetRequiredService();
+ var fastBillTab = new PSCHelpdesk.Shared.Menu.Item()
+ {
+ Header = "Customers",
+ CommandParameter = new CustomerViewModel(new CustomerService())
+ };
+ menuService.AddMenuItem(fastBillTab);
var settingsService = Ioc.Default.GetRequiredService();
var fastbillSettings = new Item()
{
@@ -27,6 +35,6 @@ public class FastBill: Contract
public List LoadViews()
{
- return [typeof(SettingsView)];
+ return [typeof(SettingsView), typeof(CustomerView)];
}
}
\ No newline at end of file
diff --git a/FastBill/FastBill.csproj b/FastBill/FastBill.csproj
index 52945f5..c587c24 100644
--- a/FastBill/FastBill.csproj
+++ b/FastBill/FastBill.csproj
@@ -13,6 +13,7 @@
+
diff --git a/FastBill/Models/Customer.cs b/FastBill/Models/Customer.cs
new file mode 100644
index 0000000..844ad45
--- /dev/null
+++ b/FastBill/Models/Customer.cs
@@ -0,0 +1,7 @@
+namespace FastBill.Models;
+
+public class Customer
+{
+ public string CustomerNr { get; set; }
+ public string CustomerId { get; set; }
+}
\ No newline at end of file
diff --git a/FastBill/Services/CustomerService.cs b/FastBill/Services/CustomerService.cs
new file mode 100644
index 0000000..0273122
--- /dev/null
+++ b/FastBill/Services/CustomerService.cs
@@ -0,0 +1,28 @@
+using CommunityToolkit.Mvvm.DependencyInjection;
+using FastBill.Models;
+using PSCHelpdesk.Shared.Service;
+using PSCHelpdesk.Shared.Setting;
+
+namespace FastBill.Services;
+
+public class CustomerService
+{
+ private readonly SettingsManager? _settingsManager;
+ private readonly Api.Customers _customerApi;
+
+ public CustomerService()
+ {
+ _settingsManager = (SettingsManager)Ioc.Default.GetService();
+ _customerApi = new Api.Customers();
+ }
+
+ public async Task> SearchCustomer(string term)
+ {
+ var settings = new Settings();
+ _settingsManager.LoadPluginSettings("FastbillSettings", settings);
+
+ List customers = new List();
+ customers = await _customerApi.SearchCustomer(settings, term);
+ return customers;
+ }
+}
\ No newline at end of file
diff --git a/FastBill/ViewModels/CustomerViewModel.cs b/FastBill/ViewModels/CustomerViewModel.cs
new file mode 100644
index 0000000..4c00af9
--- /dev/null
+++ b/FastBill/ViewModels/CustomerViewModel.cs
@@ -0,0 +1,31 @@
+using System.Reactive;
+using FastBill.Services;
+using PSCHelpdesk.Shared.ViewModels;
+using ReactiveUI;
+
+namespace FastBill.ViewModels;
+
+public class CustomerViewModel: ViewModelBase, IViewModelBase
+{
+ public string _term;
+
+ public string Term
+ {
+ get => _term;
+ set => SetAndRaisePropertyChanged(ref _term, value);
+ }
+
+ private CustomerService _customerService;
+
+ public ReactiveCommand SearchCustomer { get; }
+
+ public CustomerViewModel(CustomerService customerService)
+ {
+ _customerService = customerService;
+ SearchCustomer = ReactiveCommand.Create(searchTerm);
+ }
+ async void searchTerm()
+ {
+ var list = await _customerService.SearchCustomer(Term);
+ }
+}
\ No newline at end of file
diff --git a/FastBill/Views/CustomerView.axaml b/FastBill/Views/CustomerView.axaml
new file mode 100644
index 0000000..389785c
--- /dev/null
+++ b/FastBill/Views/CustomerView.axaml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
diff --git a/FastBill/Views/CustomerView.axaml.cs b/FastBill/Views/CustomerView.axaml.cs
new file mode 100644
index 0000000..4e718ab
--- /dev/null
+++ b/FastBill/Views/CustomerView.axaml.cs
@@ -0,0 +1,13 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace FastBill.Views;
+
+public partial class CustomerView : UserControl
+{
+ public CustomerView()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/HetznerServer/Controls/ServerDetailView.axaml b/HetznerServer/Controls/ServerDetailView.axaml
new file mode 100644
index 0000000..e582f6c
--- /dev/null
+++ b/HetznerServer/Controls/ServerDetailView.axaml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/HetznerServer/Controls/ServerDetailView.axaml.cs b/HetznerServer/Controls/ServerDetailView.axaml.cs
new file mode 100644
index 0000000..0d1b237
--- /dev/null
+++ b/HetznerServer/Controls/ServerDetailView.axaml.cs
@@ -0,0 +1,9 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.Primitives;
+
+namespace PSCHelpdesk.Plugins.HetznerServer.Controls;
+
+public class ServerDetailView : TemplatedControl
+{
+}
\ No newline at end of file
diff --git a/HetznerServer/HetznerServer.csproj b/HetznerServer/HetznerServer.csproj
index 3215248..9a0bb90 100644
--- a/HetznerServer/HetznerServer.csproj
+++ b/HetznerServer/HetznerServer.csproj
@@ -32,6 +32,7 @@
+
diff --git a/HetznerServer/Models/Server.cs b/HetznerServer/Models/Server.cs
index e15148a..bb63ced 100644
--- a/HetznerServer/Models/Server.cs
+++ b/HetznerServer/Models/Server.cs
@@ -1,15 +1,18 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
+using System.Xml.Linq;
using Avalonia.Media;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Material.Icons;
+using PSCHelpdesk.Shared.Service;
using ReactiveUI;
namespace PSCHelpdesk.Plugins.HetznerServer.Models;
public class Server : ReactiveObject
{
- public long Id { get; set; }
+ public long ServerId { get; set; }
public string Name { get; set; }
private string _pscApiKey;
@@ -90,9 +93,9 @@ public class Server : ReactiveObject
public string Ipv4 { get; set; }
public string Ipv6 { get; set; }
- public Server(long id, string name, string type, string status, string ipv4, string ipv6)
+ public Server(long serverId, string name, string type, string status, string ipv4, string ipv6)
{
- Id = id;
+ ServerId = serverId;
Name = name;
Type = type;
Status = status;
diff --git a/HetznerServer/Models/ServerSetting.cs b/HetznerServer/Models/ServerSetting.cs
index fb3e9fa..71ea3db 100644
--- a/HetznerServer/Models/ServerSetting.cs
+++ b/HetznerServer/Models/ServerSetting.cs
@@ -2,12 +2,14 @@ namespace PSCHelpdesk.Plugins.HetznerServer.Models;
public class ServerSetting
{
- public string Id { get; set; }
- public string ApiKey { get; set; }
+ public long ServerId { get; set; }
+ public string PscApiKey { get; set; }
+ public string FastBillId { get; set; }
- public ServerSetting()
+ public ServerSetting(long serverId, string pscApiKey, string fastBillId)
{
- Id = Guid.NewGuid().ToString();
- ApiKey = string.Empty;
+ ServerId = serverId;
+ PscApiKey = pscApiKey;
+ FastBillId = fastBillId;
}
}
\ No newline at end of file
diff --git a/HetznerServer/Service/ServerService.cs b/HetznerServer/Service/ServerService.cs
index d9d9236..007eac0 100644
--- a/HetznerServer/Service/ServerService.cs
+++ b/HetznerServer/Service/ServerService.cs
@@ -19,7 +19,7 @@ namespace PSCHelpdesk.Plugins.HetznerServer.Service;
public class ServerService: IServerService
{
- public SourceCache SourceCache = new (x => x.Id);
+ public SourceCache SourceCache = new (x => x.ServerId);
private SettingsManager _settingsManager;
private readonly DispatcherTimer _reloadTimer = new DispatcherTimer();
private string _searchText = string.Empty;
@@ -73,8 +73,18 @@ public class ServerService: IServerService
{
_reloadTimer.Stop();
});
+
+ var settings = new Settings();
+ _settingsManager.LoadPluginSettings("HetznerSettings", settings);
+
foreach (Server serv in SourceCache.Items)
{
+ if (settings.ServerSettings.Count(e => e.ServerId == serv.ServerId) > 0)
+ {
+ serv.FastBillId = settings.ServerSettings.First(e => e.ServerId == serv.ServerId).FastBillId;
+ serv.PscApiKey = settings.ServerSettings.First(e => e.ServerId == serv.ServerId).PscApiKey;
+ }
+
var connectionInfo = new ConnectionInfo(serv.Ipv4,
"root",
new PrivateKeyAuthenticationMethod("root", new PrivateKeyFile(this._settingsManager.CoreSettings.PrivateSSHKeyPath)));
@@ -185,4 +195,20 @@ public class ServerService: IServerService
this._reloadTimer.Start();
});
}
+
+ public void SaveSettings(Server selectedServer)
+ {
+ var settings = new Settings();
+ _settingsManager.LoadPluginSettings("HetznerSettings", settings);
+ if (settings.ServerSettings.Count(e => e.ServerId == selectedServer.ServerId) > 0)
+ {
+ settings.ServerSettings.First(e => e.ServerId == selectedServer.ServerId).FastBillId = selectedServer.FastBillId;
+ settings.ServerSettings.First(e => e.ServerId == selectedServer.ServerId).PscApiKey = selectedServer.PscApiKey;
+ }
+ else
+ {
+ settings.ServerSettings.Add(new ServerSetting(selectedServer.ServerId, selectedServer.PscApiKey, selectedServer.FastBillId));
+ }
+ _settingsManager.SavePluginSettings("HetznerSettings", settings);
+ }
}
\ No newline at end of file
diff --git a/HetznerServer/ViewModels/ServerViewModel.cs b/HetznerServer/ViewModels/ServerViewModel.cs
index 613b7b9..09120df 100644
--- a/HetznerServer/ViewModels/ServerViewModel.cs
+++ b/HetznerServer/ViewModels/ServerViewModel.cs
@@ -37,8 +37,8 @@ public partial class ServerViewModel : ViewModelBase, IViewModelBase
ServerService = _serverService;
ServerService.SourceCache.Connect()
// Sort Ascending on the OrderIndex property
- .Sort(SortExpressionComparer.Ascending(t => t.Id))
- .Filter(x => x.Name.Contains(_searchText, StringComparison.OrdinalIgnoreCase) || x.Domains.Count(d => d.Name.Contains(_searchText, StringComparison.OrdinalIgnoreCase)) > 0)
+ .Sort(SortExpressionComparer.Ascending(t => t.ServerId))
+ .Filter(x => x.Name.Contains(_searchText, StringComparison.OrdinalIgnoreCase) || x.ServerId.ToString().Contains(_searchText, StringComparison.OrdinalIgnoreCase) || x.Domains.Count(d => d.Name.Contains(_searchText, StringComparison.OrdinalIgnoreCase)) > 0)
// Bind to our ReadOnlyObservableCollection
.Bind(out _server)
// Subscribe for changes
@@ -97,6 +97,6 @@ public partial class ServerViewModel : ViewModelBase, IViewModelBase
void saveServerSettings()
{
-
+ ServerService.SaveSettings(SelectedServer);
}
}
\ No newline at end of file
diff --git a/HetznerServer/Views/ServerDetailView.axaml b/HetznerServer/Views/ServerDetailView.axaml
index e3b2c40..b3520a3 100644
--- a/HetznerServer/Views/ServerDetailView.axaml
+++ b/HetznerServer/Views/ServerDetailView.axaml
@@ -4,10 +4,8 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
xmlns:vm="clr-namespace:PSCHelpdesk.Plugins.HetznerServer.ViewModels"
+ xmlns:views="clr-namespace:PSCHelpdesk.Plugins.HetznerServer.Views"
x:Class="PSCHelpdesk.Plugins.HetznerServer.Views.ServerDetailView">
-
-
-
diff --git a/HetznerServer/Views/ServerDetailView.axaml.cs b/HetznerServer/Views/ServerDetailView.axaml.cs
index 3b3036e..1c49597 100644
--- a/HetznerServer/Views/ServerDetailView.axaml.cs
+++ b/HetznerServer/Views/ServerDetailView.axaml.cs
@@ -1,6 +1,9 @@
using Avalonia;
using Avalonia.Controls;
+using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
+using PSCHelpdesk.Plugins.HetznerServer.Models;
+using PSCHelpdesk.Plugins.HetznerServer.ViewModels;
namespace PSCHelpdesk.Plugins.HetznerServer.Views;
diff --git a/HetznerServer/Views/ServerView.axaml b/HetznerServer/Views/ServerView.axaml
index e871780..b06163d 100644
--- a/HetznerServer/Views/ServerView.axaml
+++ b/HetznerServer/Views/ServerView.axaml
@@ -49,7 +49,7 @@
-
+
diff --git a/PSCHelpdesk.sln.DotSettings.user b/PSCHelpdesk.sln.DotSettings.user
index 7627a2f..36e4f5a 100644
--- a/PSCHelpdesk.sln.DotSettings.user
+++ b/PSCHelpdesk.sln.DotSettings.user
@@ -32,6 +32,7 @@
ForceIncluded
ForceIncluded
ForceIncluded
+ ForceIncluded
ForceIncluded
ForceIncluded
ForceIncluded
diff --git a/_dist/hetzner/HetznerServer.deps.json b/_dist/hetzner/HetznerServer.deps.json
index 23cebb9..4a78c13 100644
--- a/_dist/hetzner/HetznerServer.deps.json
+++ b/_dist/hetzner/HetznerServer.deps.json
@@ -12,6 +12,7 @@
"Avalonia.ReactiveUI": "11.2.0",
"Avalonia.Xaml.Behaviors": "11.2.0",
"Avalonia.Xaml.Interactions": "11.2.0",
+ "CommunityToolkit.Mvvm": "8.3.2",
"HetznerCloud.API": "1.1.9",
"Material.Icons.Avalonia": "2.1.10",
"Microsoft.Extensions.DependencyInjection": "8.0.1",
@@ -193,6 +194,14 @@
}
}
},
+ "CommunityToolkit.Mvvm/8.3.2": {
+ "runtime": {
+ "lib/net8.0/CommunityToolkit.Mvvm.dll": {
+ "assemblyVersion": "8.3.0.0",
+ "fileVersion": "8.3.2.1"
+ }
+ }
+ },
"DynamicData/8.4.1": {
"dependencies": {
"System.Reactive": "6.0.1"
@@ -400,6 +409,13 @@
"path": "avalonia.xaml.interactivity/11.2.0",
"hashPath": "avalonia.xaml.interactivity.11.2.0.nupkg.sha512"
},
+ "CommunityToolkit.Mvvm/8.3.2": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-m8EolE1A0Updj68WTsZSGI6VWb6mUqHPh7QFo0kt7+JPhYMNXRS1ch8TS/oITAdcxTLrwMOp3ku1KjeG1/Zdpg==",
+ "path": "communitytoolkit.mvvm/8.3.2",
+ "hashPath": "communitytoolkit.mvvm.8.3.2.nupkg.sha512"
+ },
"DynamicData/8.4.1": {
"type": "package",
"serviceable": true,
diff --git a/_dist/hetzner/HetznerServer.dll b/_dist/hetzner/HetznerServer.dll
index 3594c77..dcc5d1f 100644
Binary files a/_dist/hetzner/HetznerServer.dll and b/_dist/hetzner/HetznerServer.dll differ
diff --git a/_dist/hetzner/HetznerServer.pdb b/_dist/hetzner/HetznerServer.pdb
index 0cbd355..a4652b0 100644
Binary files a/_dist/hetzner/HetznerServer.pdb and b/_dist/hetzner/HetznerServer.pdb differ
diff --git a/_dist/nextcloud/Nextcloud.dll b/_dist/nextcloud/Nextcloud.dll
index 1fa624f..92aa3eb 100644
Binary files a/_dist/nextcloud/Nextcloud.dll and b/_dist/nextcloud/Nextcloud.dll differ
diff --git a/_dist/nextcloud/Nextcloud.pdb b/_dist/nextcloud/Nextcloud.pdb
index e2f1d4f..626f8d4 100644
Binary files a/_dist/nextcloud/Nextcloud.pdb and b/_dist/nextcloud/Nextcloud.pdb differ