diff --git a/MyFirstMauiApp/UseRestService/AppShell.xaml b/MyFirstMauiApp/UseRestService/AppShell.xaml
index 2ab84d9..4251948 100644
--- a/MyFirstMauiApp/UseRestService/AppShell.xaml
+++ b/MyFirstMauiApp/UseRestService/AppShell.xaml
@@ -3,12 +3,11 @@
x:Class="UseRestService.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
- xmlns:local="clr-namespace:UseRestService"
+ xmlns:local="clr-namespace:UseRestService.Pages"
Shell.FlyoutBehavior="Disabled">
+ ContentTemplate="{DataTemplate local:PartsPage}"
+ Route="listparts" />
diff --git a/MyFirstMauiApp/UseRestService/AppShell.xaml.cs b/MyFirstMauiApp/UseRestService/AppShell.xaml.cs
index e6fb281..399c4f2 100644
--- a/MyFirstMauiApp/UseRestService/AppShell.xaml.cs
+++ b/MyFirstMauiApp/UseRestService/AppShell.xaml.cs
@@ -1,10 +1,14 @@
-namespace UseRestService
+using UseRestService.Pages;
+
+namespace UseRestService
{
public partial class AppShell : Shell
{
public AppShell()
{
InitializeComponent();
+
+ Routing.RegisterRoute("addpart", typeof(AddPartPage));
}
}
}
diff --git a/MyFirstMauiApp/UseRestService/Data/PartManager.cs b/MyFirstMauiApp/UseRestService/Data/PartManager.cs
index d582cd1..47a4ae2 100644
--- a/MyFirstMauiApp/UseRestService/Data/PartManager.cs
+++ b/MyFirstMauiApp/UseRestService/Data/PartManager.cs
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Net.Http.Json;
using System.Text;
+using System.Text.Json;
using System.Threading.Tasks;
namespace UseRestService.Data
@@ -9,34 +11,99 @@ namespace UseRestService.Data
public static class PartsManager
{
// TODO: Add fields for BaseAddress, Url, and authorizationKey
- static readonly string BaseAddress = "URL GOES HERE";
+ static readonly string BaseAddress = "https://mslearnpartsserver425916999.azurewebsites.net";
static readonly string Url = $"{BaseAddress}/api/";
static HttpClient client;
+ static string authorizationKey;
+
private static async Task GetClient()
{
- throw new NotImplementedException();
+ if (client != null)
+ return client;
+
+ client = new HttpClient();
+
+ if (string.IsNullOrEmpty(authorizationKey))
+ {
+ authorizationKey = await client.GetStringAsync($"{Url}login");
+ authorizationKey = JsonSerializer.Deserialize(authorizationKey);
+ }
+
+ client.DefaultRequestHeaders.Add("Authorization", authorizationKey);
+ client.DefaultRequestHeaders.Add("Accept", "application/json");
+
+ return client;
}
public static async Task> GetAll()
{
- throw new NotImplementedException();
+ if (Connectivity.Current.NetworkAccess != NetworkAccess.Internet)
+ return new List();
+
+ var client = await GetClient();
+ string result = await client.GetStringAsync($"{Url}parts");
+
+ return JsonSerializer.Deserialize>(result, new JsonSerializerOptions
+ {
+ PropertyNameCaseInsensitive = true,
+ });
}
public static async Task Add(string partName, string supplier, string partType)
{
- throw new NotImplementedException();
+ if (Connectivity.Current.NetworkAccess != NetworkAccess.Internet)
+ return new Part();
+
+ var part = new Part()
+ {
+ PartName = partName,
+ Suppliers = new List(new[] { supplier }),
+ PartID = string.Empty,
+ PartType = partType,
+ PartAvailableDate = DateTime.Now.Date
+ };
+
+ var msg = new HttpRequestMessage(HttpMethod.Post, $"{Url}parts");
+ msg.Content = JsonContent.Create(part);
+
+ var response = await client.SendAsync(msg);
+ response.EnsureSuccessStatusCode();
+
+ var returnedJson = await response.Content.ReadAsStringAsync();
+
+ var insertedPart = JsonSerializer.Deserialize(returnedJson, new JsonSerializerOptions
+ {
+ PropertyNameCaseInsensitive = true,
+ });
+
+ return insertedPart;
}
public static async Task Update(Part part)
{
- throw new NotImplementedException();
+ if (Connectivity.Current.NetworkAccess != NetworkAccess.Internet)
+ return;
+
+ HttpRequestMessage msg = new(HttpMethod.Put, $"{Url}parts/{part.PartID}");
+ msg.Content = JsonContent.Create(part);
+
+ var client = await GetClient();
+ var response = await client.SendAsync(msg);
+ response.EnsureSuccessStatusCode();
}
public static async Task Delete(string partID)
{
- throw new NotImplementedException();
+ if (Connectivity.Current.NetworkAccess != NetworkAccess.Internet)
+ return;
+
+ HttpRequestMessage msg = new(HttpMethod.Delete, $"{Url}parts/{partID}");
+
+ var client = await GetClient();
+ var response = await client.SendAsync(msg);
+ response.EnsureSuccessStatusCode();
}
}
}
diff --git a/MyFirstMauiApp/UseRestService/Pages/AddPartPage.xaml b/MyFirstMauiApp/UseRestService/Pages/AddPartPage.xaml
new file mode 100644
index 0000000..7dad2f5
--- /dev/null
+++ b/MyFirstMauiApp/UseRestService/Pages/AddPartPage.xaml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MyFirstMauiApp/UseRestService/Pages/AddPartPage.xaml.cs b/MyFirstMauiApp/UseRestService/Pages/AddPartPage.xaml.cs
new file mode 100644
index 0000000..4b6ddd0
--- /dev/null
+++ b/MyFirstMauiApp/UseRestService/Pages/AddPartPage.xaml.cs
@@ -0,0 +1,35 @@
+using UseRestService.Data;
+using UseRestService.ViewModels;
+
+namespace UseRestService.Pages;
+
+[QueryProperty("PartToDisplay", "part")]
+public partial class AddPartPage : ContentPage
+{
+ AddPartViewModel viewModel;
+ public AddPartPage()
+ {
+ InitializeComponent();
+
+ viewModel = new AddPartViewModel();
+ BindingContext = viewModel;
+ }
+
+ Part _partToDisplay;
+ public Part PartToDisplay
+ {
+ get => _partToDisplay;
+ set
+ {
+ if (_partToDisplay == value)
+ return;
+
+ _partToDisplay = value;
+
+ viewModel.PartID = _partToDisplay.PartID;
+ viewModel.PartName = _partToDisplay.PartName;
+ viewModel.Suppliers = _partToDisplay.SupplierString;
+ viewModel.PartType = _partToDisplay.PartType;
+ }
+ }
+}
\ No newline at end of file
diff --git a/MyFirstMauiApp/UseRestService/Pages/PartsPage.xaml b/MyFirstMauiApp/UseRestService/Pages/PartsPage.xaml
index 819391e..3897aa5 100644
--- a/MyFirstMauiApp/UseRestService/Pages/PartsPage.xaml
+++ b/MyFirstMauiApp/UseRestService/Pages/PartsPage.xaml
@@ -2,11 +2,33 @@
-
-
-
+ Title="Part List"
+ xmlns:viewModel="clr-namespace:UseRestService.ViewModels"
+ xmlns:data="clr-namespace:UseRestService.Data"
+ x:DataType="viewModel:PartsViewModel">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MyFirstMauiApp/UseRestService/Pages/PartsPage.xaml.cs b/MyFirstMauiApp/UseRestService/Pages/PartsPage.xaml.cs
index 118cd53..7c342a1 100644
--- a/MyFirstMauiApp/UseRestService/Pages/PartsPage.xaml.cs
+++ b/MyFirstMauiApp/UseRestService/Pages/PartsPage.xaml.cs
@@ -1,3 +1,5 @@
+using UseRestService.ViewModels;
+
namespace UseRestService.Pages;
public partial class PartsPage : ContentPage
@@ -5,5 +7,6 @@ public partial class PartsPage : ContentPage
public PartsPage()
{
InitializeComponent();
+ BindingContext = new PartsViewModel();
}
}
\ No newline at end of file
diff --git a/MyFirstMauiApp/UseRestService/UseRestService.csproj b/MyFirstMauiApp/UseRestService/UseRestService.csproj
index 16f7252..627dcfc 100644
--- a/MyFirstMauiApp/UseRestService/UseRestService.csproj
+++ b/MyFirstMauiApp/UseRestService/UseRestService.csproj
@@ -54,6 +54,9 @@
+
+ MSBuild:Compile
+
MSBuild:Compile
diff --git a/MyFirstMauiApp/UseRestService/ViewModels/AddPartViewModel.cs b/MyFirstMauiApp/UseRestService/ViewModels/AddPartViewModel.cs
new file mode 100644
index 0000000..3a022df
--- /dev/null
+++ b/MyFirstMauiApp/UseRestService/ViewModels/AddPartViewModel.cs
@@ -0,0 +1,89 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
+using CommunityToolkit.Mvvm.Messaging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using UseRestService.Data;
+
+namespace UseRestService.ViewModels
+{
+ public partial class AddPartViewModel : ObservableObject
+ {
+ [ObservableProperty]
+ string _partID;
+
+ [ObservableProperty]
+ string _partName;
+
+ [ObservableProperty]
+ string _suppliers;
+
+ [ObservableProperty]
+ string _partType;
+
+ public AddPartViewModel()
+ {
+ }
+
+ [RelayCommand]
+ async Task SaveData()
+ {
+ if (string.IsNullOrWhiteSpace(PartID))
+ await InsertPart();
+ else
+ await UpdatePart();
+ }
+
+
+ [RelayCommand]
+ async Task InsertPart()
+ {
+ await PartsManager.Add(PartName, Suppliers, PartType);
+
+ WeakReferenceMessenger.Default.Send(new RefreshMessage(true));
+
+ await Shell.Current.GoToAsync("..");
+ }
+
+
+ [RelayCommand]
+ async Task UpdatePart()
+ {
+ Part partToSave = new()
+ {
+ PartID = PartID,
+ PartName = PartName,
+ PartType = PartType,
+ Suppliers = Suppliers.Split(",").ToList()
+ };
+
+ await PartsManager.Update(partToSave);
+
+ WeakReferenceMessenger.Default.Send(new RefreshMessage(true));
+
+ await Shell.Current.GoToAsync("..");
+ }
+
+ [RelayCommand]
+ async Task DeletePart()
+ {
+ if (string.IsNullOrWhiteSpace(PartID))
+ return;
+
+ await PartsManager.Delete(PartID);
+
+ WeakReferenceMessenger.Default.Send(new RefreshMessage(true));
+
+ await Shell.Current.GoToAsync("..");
+ }
+
+ [RelayCommand]
+ async Task DoneEditing()
+ {
+ await Shell.Current.GoToAsync("..");
+ }
+ }
+}
diff --git a/MyFirstMauiApp/UseRestService/ViewModels/PartsViewModel.cs b/MyFirstMauiApp/UseRestService/ViewModels/PartsViewModel.cs
index f3a1cd9..43491ab 100644
--- a/MyFirstMauiApp/UseRestService/ViewModels/PartsViewModel.cs
+++ b/MyFirstMauiApp/UseRestService/ViewModels/PartsViewModel.cs
@@ -1,13 +1,92 @@
using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
+using CommunityToolkit.Mvvm.Messaging;
using System;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using UseRestService.Data;
namespace UseRestService.ViewModels
{
- internal class PartsViewModel : ObservableObject
+ internal partial class PartsViewModel : ObservableObject
{
+ [ObservableProperty]
+ ObservableCollection _parts;
+
+ [ObservableProperty]
+ bool _isRefreshing = false;
+
+ [ObservableProperty]
+ bool _isBusy = false;
+
+ [ObservableProperty]
+ Part _selectedPart;
+
+ public PartsViewModel()
+ {
+ _parts = new ObservableCollection();
+
+ WeakReferenceMessenger.Default.Register(this, async (r, m) =>
+ {
+ await LoadData();
+ });
+
+ Task.Run(LoadData);
+ }
+
+ [RelayCommand]
+ async Task PartSelected()
+ {
+ if (SelectedPart == null)
+ return;
+
+ var navigationParameter = new Dictionary()
+ {
+ { "part", SelectedPart }
+ };
+
+ await Shell.Current.GoToAsync("addpart", navigationParameter);
+
+ MainThread.BeginInvokeOnMainThread(() => SelectedPart = null);
+ }
+
+ [RelayCommand]
+ async Task LoadData()
+ {
+ if (IsBusy)
+ return;
+
+ try
+ {
+ IsRefreshing = true;
+ IsBusy = true;
+
+ var partsCollection = await PartsManager.GetAll();
+
+ MainThread.BeginInvokeOnMainThread(() =>
+ {
+ Parts.Clear();
+
+ foreach (Part part in partsCollection)
+ {
+ Parts.Add(part);
+ }
+ });
+ }
+ finally
+ {
+ IsRefreshing = false;
+ IsBusy = false;
+ }
+ }
+
+ [RelayCommand]
+ async Task AddNewPart()
+ {
+ await Shell.Current.GoToAsync("addpart");
+ }
}
}