diff --git a/README.md b/README.md index 631ca844..24d0e702 100644 --- a/README.md +++ b/README.md @@ -35,9 +35,6 @@ Adds support for [OAuth 2.0](https://oauth.net/2/) / [OpenID Connect](https://op [![TypedRest.CommandLine](https://img.shields.io/nuget/v/TypedRest.CommandLine.svg?label=TypedRest.CommandLine)](https://www.nuget.org/packages/TypedRest.CommandLine/) Build command-line interfaces for TypedRest clients. -[![TypedRest.Wpf](https://img.shields.io/nuget/v/TypedRest.Wpf.svg?label=TypedRest.Wpf)](https://www.nuget.org/packages/TypedRest.Wpf/) -Build WPF interfaces for TypedRest clients. - ## Documentation Read an **[Introduction](https://typedrest.net/introduction/)** to TypedRest or jump right in with the **[Getting started](https://typedrest.net/getting-started/dotnet/)** guide. diff --git a/src/TypedRest.Wpf/Events/BlobUploadEvent.cs b/src/TypedRest.Wpf/Events/BlobUploadEvent.cs deleted file mode 100644 index 7e698aa7..00000000 --- a/src/TypedRest.Wpf/Events/BlobUploadEvent.cs +++ /dev/null @@ -1,18 +0,0 @@ -using TypedRest.Endpoints.Raw; - -namespace TypedRest.Wpf.Events -{ - /// - /// Indicates that was called. - /// - public class BlobUploadEvent : EndpointEvent - { - /// - /// Creates a new blob upload event. - /// - /// The endpoint that data was uploaded to. - public BlobUploadEvent(IBlobEndpoint endpoint) - : base(endpoint) - {} - } -} diff --git a/src/TypedRest.Wpf/Events/ClassDiagram.cd b/src/TypedRest.Wpf/Events/ClassDiagram.cd deleted file mode 100644 index b50d7369..00000000 --- a/src/TypedRest.Wpf/Events/ClassDiagram.cd +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= - Events\ElementCreatedEvent.cs - - - - - - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= - Events\ElementEvent.cs - - - - - - - - AAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAQAAAA= - Events\EndpointEvent.cs - - - - - - - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= - Events\ElementUpdatedEvent.cs - - - - - - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= - Events\ElementDeletedEvent.cs - - - - - - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= - Events\BlobUploadEvent.cs - - - - - - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= - Events\InvokeEvent.cs - - - - - - AAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAA= - Events\IEndpointEvent.cs - - - - \ No newline at end of file diff --git a/src/TypedRest.Wpf/Events/ElementCreatedEvent.cs b/src/TypedRest.Wpf/Events/ElementCreatedEvent.cs deleted file mode 100644 index 1ebc074c..00000000 --- a/src/TypedRest.Wpf/Events/ElementCreatedEvent.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Threading; -using TypedRest.Endpoints.Generic; - -namespace TypedRest.Wpf.Events -{ - /// - /// Indicates that a new element was created. - /// - /// The type of entity that was created. - /// - public class ElementCreatedEvent : ElementEvent - { - /// - /// Creates a new element create event. - /// - /// The endpoint representing the newly created entity. - public ElementCreatedEvent(IElementEndpoint endpoint) - : base(endpoint) - {} - } -} diff --git a/src/TypedRest.Wpf/Events/ElementDeletedEvent.cs b/src/TypedRest.Wpf/Events/ElementDeletedEvent.cs deleted file mode 100644 index 43780576..00000000 --- a/src/TypedRest.Wpf/Events/ElementDeletedEvent.cs +++ /dev/null @@ -1,20 +0,0 @@ -using TypedRest.Endpoints.Generic; - -namespace TypedRest.Wpf.Events -{ - /// - /// Indicates that an element was deleted. - /// - /// The type of entity that was deleted. - /// - public class ElementDeletedEvent : ElementEvent - { - /// - /// Creates a new element delete event. - /// - /// The endpoint representing the deleted entity. - public ElementDeletedEvent(IElementEndpoint endpoint) - : base(endpoint) - {} - } -} diff --git a/src/TypedRest.Wpf/Events/ElementEvent.cs b/src/TypedRest.Wpf/Events/ElementEvent.cs deleted file mode 100644 index a0a99742..00000000 --- a/src/TypedRest.Wpf/Events/ElementEvent.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Caliburn.Micro; -using TypedRest.Endpoints.Generic; - -namespace TypedRest.Wpf.Events -{ - /// - /// An event for the that references an . - /// - /// The type of entity the endpoint represents. - public abstract class ElementEvent : EndpointEvent> - { - /// - /// Creates a new element event. - /// - /// The endpoint that raised the event. - protected ElementEvent(IElementEndpoint endpoint) - : base(endpoint) - {} - } -} diff --git a/src/TypedRest.Wpf/Events/ElementUpdatedEvent.cs b/src/TypedRest.Wpf/Events/ElementUpdatedEvent.cs deleted file mode 100644 index d8be5732..00000000 --- a/src/TypedRest.Wpf/Events/ElementUpdatedEvent.cs +++ /dev/null @@ -1,20 +0,0 @@ -using TypedRest.Endpoints.Generic; - -namespace TypedRest.Wpf.Events -{ - /// - /// Indicates that an existing element was updated. - /// - /// The type of entity that was updated. - /// - public class ElementUpdatedEvent : ElementEvent - { - /// - /// Creates a new element update event. - /// - /// The endpoint representing the updated entity. - public ElementUpdatedEvent(IElementEndpoint endpoint) - : base(endpoint) - {} - } -} diff --git a/src/TypedRest.Wpf/Events/EndpointEvent.cs b/src/TypedRest.Wpf/Events/EndpointEvent.cs deleted file mode 100644 index 24ccdbd4..00000000 --- a/src/TypedRest.Wpf/Events/EndpointEvent.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Caliburn.Micro; -using TypedRest.Endpoints; - -namespace TypedRest.Wpf.Events -{ - /// - /// An event for the that references an . - /// - /// The type of endpoint that raised the event. - public abstract class EndpointEvent : IEndpointEvent - where TEndpoint : class, IEndpoint - { - /// - /// The endpoint that raised the event. - /// - public TEndpoint Endpoint { get; } - - IEndpoint IEndpointEvent.Endpoint => Endpoint; - - /// - /// Creates a new endpoint event. - /// - /// The endpoint that raised the event. - protected EndpointEvent(TEndpoint endpoint) - { - Endpoint = endpoint; - } - } -} diff --git a/src/TypedRest.Wpf/Events/IEndpointEvent.cs b/src/TypedRest.Wpf/Events/IEndpointEvent.cs deleted file mode 100644 index f1712378..00000000 --- a/src/TypedRest.Wpf/Events/IEndpointEvent.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Caliburn.Micro; -using TypedRest.Endpoints; - -namespace TypedRest.Wpf.Events -{ - /// - /// An event for the that references an . - /// - public interface IEndpointEvent - { - /// - /// The endpoint that raised the event. - /// - IEndpoint Endpoint { get; } - } -} diff --git a/src/TypedRest.Wpf/Events/InvokeEvent.cs b/src/TypedRest.Wpf/Events/InvokeEvent.cs deleted file mode 100644 index 72909cd9..00000000 --- a/src/TypedRest.Wpf/Events/InvokeEvent.cs +++ /dev/null @@ -1,18 +0,0 @@ -using TypedRest.Endpoints.Rpc; - -namespace TypedRest.Wpf.Events -{ - /// - /// Indicates that .InvokeAsync() was called. - /// - public class InvokeEvent : EndpointEvent - { - /// - /// Creates a new invoke event. - /// - /// The endpoint that was invoked. - public InvokeEvent(IRpcEndpoint endpoint) - : base(endpoint) - {} - } -} diff --git a/src/TypedRest.Wpf/Events/_Namespace.cs b/src/TypedRest.Wpf/Events/_Namespace.cs deleted file mode 100644 index cb7d71cb..00000000 --- a/src/TypedRest.Wpf/Events/_Namespace.cs +++ /dev/null @@ -1,2 +0,0 @@ -//! \namespace TypedRest.Wpf.Events -//! \brief Events triggered by TypedRest WPF View Models. diff --git a/src/TypedRest.Wpf/InputBox.cs b/src/TypedRest.Wpf/InputBox.cs deleted file mode 100644 index 4e17d2ba..00000000 --- a/src/TypedRest.Wpf/InputBox.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System.Reflection; -using System.Windows; -using System.Windows.Controls; - -namespace TypedRest.Wpf -{ - /// - /// Simple text input window. - /// - public static class InputBox - { - /// - /// Asks the user to enter a string. - /// - /// The prompt to show to the user. - /// The parent window. May be null. - /// The string the user entered or null if the user closed the window without pressing OK. - public static string Show(string prompt, Window owner = null) - { - var window = new Window - { - Owner = owner, - Title = Assembly.GetCallingAssembly().GetName().Name, - Height = 150, - Width = 400 - }; - - var promptTextBlock = new TextBlock - { - Text = prompt, - Margin = new Thickness(7), - TextWrapping = TextWrapping.Wrap, - HorizontalAlignment = HorizontalAlignment.Center - }; - - var inputBox = new TextBox - { - TabIndex = 0, - Width = 350, - Margin = new Thickness(7), - HorizontalAlignment = HorizontalAlignment.Center - }; - - var okButton = new Button - { - Content = "OK", - IsDefault = true, - TabIndex = 1, - Width = 70, - Height = 30, - Margin = new Thickness(7), - HorizontalAlignment = HorizontalAlignment.Center - }; - okButton.Click += delegate - { - window.DialogResult = true; - window.Close(); - }; - - window.Content = new StackPanel {Children = {promptTextBlock, inputBox, okButton}}; - return (window.ShowDialog() ?? false) ? inputBox.Text : null; - } - } -} diff --git a/src/TypedRest.Wpf/TypedRest.Wpf.csproj b/src/TypedRest.Wpf/TypedRest.Wpf.csproj deleted file mode 100644 index a471d2ee..00000000 --- a/src/TypedRest.Wpf/TypedRest.Wpf.csproj +++ /dev/null @@ -1,53 +0,0 @@ - - - - 7.3 - True - full - $(NoWarn);1591 - True - False - ..\..\artifacts\$(Configuration)\ - Library - $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb - - - - net45 - True - ..\sgKey.snk - True - - - - Build WPF interfaces for TypedRest clients. - build WPF UIs for TypedRest clients - Typed REST WPF GUI - https://typedrest.net/ - MIT - https://github.com/TypedRest/TypedRest-DotNet - Bastian Eicher - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/TypedRest.Wpf/ViewModels/ActionViewModel.cs b/src/TypedRest.Wpf/ViewModels/ActionViewModel.cs deleted file mode 100644 index d9c6380a..00000000 --- a/src/TypedRest.Wpf/ViewModels/ActionViewModel.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.Threading.Tasks; -using System.Windows; -using Caliburn.Micro; -using TypedRest.Endpoints.Rpc; -using TypedRest.Wpf.Events; - -namespace TypedRest.Wpf.ViewModels -{ - /// - /// View model operating on an . - /// - public class ActionViewModel : RpcViewModelBase - where TEndpoint : class, IActionEndpoint - { - /// - /// Creates a new REST action view model. - /// - /// The endpoint this view model operates on. - /// Used to send refresh notifications. - /// A caption for the invokable action. - public ActionViewModel(TEndpoint endpoint, IEventAggregator eventAggregator, string caption) - : base(endpoint, eventAggregator) - { - DisplayName = caption; - } - - public override async void Invoke() - => await WithErrorHandlingAsync(async () => - { - await OnInvokeAsync(); - EventAggregator.Publish(new InvokeEvent(Endpoint), null); - MessageBox.Show("Successful.", DisplayName, MessageBoxButton.OK, MessageBoxImage.Information); - }); - - private async Task OnInvokeAsync() - => await Endpoint.InvokeAsync(CancellationToken); - } -} diff --git a/src/TypedRest.Wpf/ViewModels/BlobViewModel.cs b/src/TypedRest.Wpf/ViewModels/BlobViewModel.cs deleted file mode 100644 index 3b457349..00000000 --- a/src/TypedRest.Wpf/ViewModels/BlobViewModel.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.Threading.Tasks; -using Caliburn.Micro; -using TypedRest.Endpoints.Raw; -using TypedRest.Wpf.Events; - -namespace TypedRest.Wpf.ViewModels -{ - /// - /// View model operating on an . - /// - public class BlobViewModel : EndpointViewModelBase - { - /// - /// Creates a new REST blob view model. - /// - /// The endpoint this view model operates on. - /// Used to send refresh notifications. - /// A caption for the blob. - public BlobViewModel(IBlobEndpoint endpoint, IEventAggregator eventAggregator, string caption) - : base(endpoint, eventAggregator) - { - DisplayName = caption; - } - - protected override async Task OnLoadAsync() - { - try - { - await Endpoint.ProbeAsync(CancellationToken); - } - catch (Exception) - { - // HTTP OPTIONS server-side implementation is optional - } - - CanDownload = Endpoint.DownloadAllowed.GetValueOrDefault(CanDownload); - NotifyOfPropertyChange(() => CanDownload); - - CanUpload = Endpoint.UploadAllowed.GetValueOrDefault(CanUpload); - NotifyOfPropertyChange(() => CanUpload); - } - - public virtual async void Upload() => await WithErrorHandlingAsync(async () => - { - await Endpoint.UploadFromAsync(null); - EventAggregator.Publish(new BlobUploadEvent(Endpoint), null); - }); - - /// - /// Controls whether a download button is shown. - /// - public bool CanDownload { get; set; } - - /// - /// Controls whether an upload button is shown. - /// - public bool CanUpload { get; set; } - } -} diff --git a/src/TypedRest.Wpf/ViewModels/ClassDiagram.cd b/src/TypedRest.Wpf/ViewModels/ClassDiagram.cd deleted file mode 100644 index b673b5c9..00000000 --- a/src/TypedRest.Wpf/ViewModels/ClassDiagram.cd +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - AAAAAAAAAAAAAAAAABAAAAgAAAAAAAAIAAAAAAAAABA= - ViewModels\BlobViewModel.cs - - - - - - AAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAgA= - ViewModels\CollectionViewModel.cs - - - - - - AACAAABAAAAAAAAAABAQAQCAAAAAAFIAAAAAAAAAAgA= - ViewModels\CollectionViewModelBase.cs - - - - - - - IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= - ViewModels\CreateElementViewModel.cs - - - - - - AAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAgA= - ViewModels\StreamingCollectionViewModel.cs - - - - - - AAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAgA= - ViewModels\PagedCollectionViewModel.cs - - - - - - AAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAA= - ViewModels\PagedCollectionViewModelBase.cs - - - - - - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= - ViewModels\StreamingCollectionViewModelBase.cs - - - - - - MAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= - ViewModels\ElementViewModelBase.cs - - - - - - AAAAAIAAAACAIAAgAFAAAAAgAAAAAAMACAAAAAECAAQ= - ViewModels\EndpointViewModelBase.cs - - - - - - - IAAAAAAAAAAAQAAAABAAAAACAAEAAAAAAAABAAAAAAA= - ViewModels\ElementViewModel.cs - - - - - - AAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAA= - ViewModels\EntryViewModelBase.cs - ViewModels\CollectionViewModelBase.cs - - - - - - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= - ViewModels\CreateElementViewModel.cs - - - - - - AAAAEAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= - ViewModels\ActionViewModel.cs - - - - - - AAAAEAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= - ViewModels\ProducerViewModel.cs - - - - - - AAAAAAAAAAAIAAAAABAAAAAAAAAAAAAAAAAAAAAAAAg= - ViewModels\RpcViewModelBase.cs - - - - - - IAAAAAAAAAAAAAAAABAAAAACAAAAAAAAAAAAAAAAAAA= - ViewModels\PollingViewModel.cs - - - - \ No newline at end of file diff --git a/src/TypedRest.Wpf/ViewModels/CollectionViewModel.cs b/src/TypedRest.Wpf/ViewModels/CollectionViewModel.cs deleted file mode 100644 index 3b16a121..00000000 --- a/src/TypedRest.Wpf/ViewModels/CollectionViewModel.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Caliburn.Micro; -using TypedRest.Endpoints.Generic; - -namespace TypedRest.Wpf.ViewModels -{ - /// - /// View model operating on a . - /// - /// The type of entity the represents. - public class CollectionViewModel : CollectionViewModelBase, IElementEndpoint> - { - /// - /// Creates a new REST collection view model. - /// - /// The endpoint this view model operates on. - /// Used to send refresh notifications. - public CollectionViewModel(ICollectionEndpoint endpoint, IEventAggregator eventAggregator) - : base(endpoint, eventAggregator) - {} - - protected override IScreen BuildElementScreen(IElementEndpoint elementEndpoint) => new ElementViewModel(elementEndpoint, EventAggregator); - - protected override IScreen BuildCreateElementScreen() => new CreateElementViewModel(Endpoint, EventAggregator); - } -} diff --git a/src/TypedRest.Wpf/ViewModels/CollectionViewModelBase.cs b/src/TypedRest.Wpf/ViewModels/CollectionViewModelBase.cs deleted file mode 100644 index 11a27ef3..00000000 --- a/src/TypedRest.Wpf/ViewModels/CollectionViewModelBase.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using Caliburn.Micro; -using TypedRest.Endpoints; -using TypedRest.Endpoints.Generic; -using TypedRest.Wpf.Events; - -namespace TypedRest.Wpf.ViewModels -{ - /// - /// Base class for building view models operating on an . - /// - /// The type of entity the represents. - /// The specific type of to operate on. - /// The specific type of the provides for individual s. - public abstract class CollectionViewModelBase : EndpointViewModelBase, IHandleWithTask> - where TEndpoint : class, ICollectionEndpoint - where TElementEndpoint : class, IEndpoint - { - /// - /// Creates a new REST collection view model. - /// - /// The endpoint this view model operates on. - /// Used to send refresh notifications. - protected CollectionViewModelBase(TEndpoint endpoint, IEventAggregator eventAggregator) - : base(endpoint, eventAggregator) - { - DisplayName = typeof(TEntity).Name; - } - - public List Elements { get; private set; } - - public List SelectedElements { get; set; } - - protected override async Task OnLoadAsync() - { - Elements = await Endpoint.ReadAllAsync(CancellationToken); - NotifyOfPropertyChange(() => Elements); - - CanCreate = Endpoint.CreateAllowed.GetValueOrDefault(CanCreate); - NotifyOfPropertyChange(() => CanCreate); - } - - /// - /// Controls whether selecting individual elements opens an edit view. - /// - public bool CanOpenElement { get; set; } - - /// - /// Handler for opening an existing element in the collection. - /// - protected virtual void OnOpenElement(TEntity entity) => Open(BuildElementScreen(Endpoint[entity])); - - /// - /// Builds a sub- for viewing or editing an existing represented by the given . - /// - protected abstract IScreen BuildElementScreen(TElementEndpoint elementEndpoint); - - /// - /// Controls whether a create button is shown. - /// - public bool CanCreate { get; set; } - - /// - /// Opens a view for creating a new element in the collection. - /// - public virtual void Create() - => Open(BuildCreateElementScreen()); - - /// - /// Builds a sub- for creating a new in the collection endpoint. - /// - protected abstract IScreen BuildCreateElementScreen(); - - // Refresh when child elements are created or updated - public async Task Handle(ElementEvent message) - => await RefreshAsync(); - } -} diff --git a/src/TypedRest.Wpf/ViewModels/CreateElementViewModel.cs b/src/TypedRest.Wpf/ViewModels/CreateElementViewModel.cs deleted file mode 100644 index b0a080ee..00000000 --- a/src/TypedRest.Wpf/ViewModels/CreateElementViewModel.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System.Threading.Tasks; -using Caliburn.Micro; -using TypedRest.Endpoints.Generic; -using TypedRest.Wpf.Events; - -namespace TypedRest.Wpf.ViewModels -{ - /// - /// View model for creating a new element in a . - /// - /// Use the more constrained when possible. - /// The type of entity to create. - /// The specific type of the provides for s. - public class CreateElementViewModel : ElementViewModelBase> - where TElementEndpoint : class, IElementEndpoint - { - /// - /// Creates a new REST element creation view model. - /// - /// The endpoint this view model operates on. - /// Used to send refresh notifications. - public CreateElementViewModel(ICollectionEndpoint endpoint, IEventAggregator eventAggregator) - : base(endpoint, eventAggregator) - { - DisplayName = "New " + typeof(TEntity).Name; - } - - protected override async Task OnSaveAsync() - { - var newEndpoint = await Endpoint.CreateAsync(Entity, CancellationToken); - EventAggregator.Publish(new ElementCreatedEvent(newEndpoint), null); - } - } - - /// - /// View model for creating a new element in a . - /// - /// The type of entity to create. - public class CreateElementViewModel : CreateElementViewModel> - { - /// - /// Creates a new REST element creation view model. - /// - /// The endpoint this view model operates on. - /// Used to send refresh notifications. - public CreateElementViewModel(ICollectionEndpoint> endpoint, IEventAggregator eventAggregator) - : base(endpoint, eventAggregator) - {} - } -} diff --git a/src/TypedRest.Wpf/ViewModels/ElementViewModel.cs b/src/TypedRest.Wpf/ViewModels/ElementViewModel.cs deleted file mode 100644 index e76645f0..00000000 --- a/src/TypedRest.Wpf/ViewModels/ElementViewModel.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System.Threading.Tasks; -using System.Windows; -using Caliburn.Micro; -using TypedRest.Endpoints.Generic; -using TypedRest.Wpf.Events; - -namespace TypedRest.Wpf.ViewModels -{ - /// - /// View model for showing or updating an existing element represented by a . - /// - /// The type of entity to represent. - public class ElementViewModel : ElementViewModelBase> - { - /// - /// Creates a new REST element view model. - /// - /// The endpoint this view model operates on. - /// Used to send refresh notifications. - public ElementViewModel(IElementEndpoint endpoint, IEventAggregator eventAggregator) - : base(endpoint, eventAggregator) - {} - - protected override async Task OnLoadAsync() - { - Entity = await Endpoint.ReadAsync(CancellationToken); - DisplayName = Entity.ToString(); - NotifyOfPropertyChange(() => Entity); - - CanSave = Endpoint.SetAllowed.GetValueOrDefault(CanSave); - NotifyOfPropertyChange(() => CanSave); - - CanDelete = Endpoint.DeleteAllowed.GetValueOrDefault(CanDelete); - NotifyOfPropertyChange(() => CanDelete); - } - - /// - /// Controls whether a save button is shown and fields are editable. - /// - public bool CanSave { get; set; } - - protected override async Task OnSaveAsync() - { - await Endpoint.SetAsync(Entity, CancellationToken); - EventAggregator.Publish(new ElementUpdatedEvent(Endpoint), null); - } - - /// - /// Controls whether a delete button is shown. - /// - public bool CanDelete { get; set; } - - /// - /// Delete all selected elements. - /// - public virtual async void Delete() - { - string question = $"Are you sure you want to delete {DisplayName}?"; - if (MessageBox.Show(question, "Delete element", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes) - { - await WithErrorHandlingAsync(async () => - { - await OnDeleteAsync(); - TryClose(); - }); - } - } - - /// - /// Handler for deleting the element. - /// - protected virtual async Task OnDeleteAsync() - { - await Endpoint.DeleteAsync(CancellationToken); - EventAggregator.Publish(new ElementDeletedEvent(Endpoint), null); - } - } -} diff --git a/src/TypedRest.Wpf/ViewModels/ElementViewModelBase.cs b/src/TypedRest.Wpf/ViewModels/ElementViewModelBase.cs deleted file mode 100644 index 71a0b5b3..00000000 --- a/src/TypedRest.Wpf/ViewModels/ElementViewModelBase.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Threading.Tasks; -using System.Windows; -using Caliburn.Micro; -using TypedRest.Endpoints; - -namespace TypedRest.Wpf.ViewModels -{ - /// - /// Base class for building view models that create or update elements. - /// - /// The type of entity the view model represents. - /// The type of to operate on. - public abstract class ElementViewModelBase : EndpointViewModelBase - where TEndpoint : class, IEndpoint - { - public TEntity Entity { get; protected set; } - - /// - /// Creates a new REST element view model. - /// - /// The endpoint this view model operates on. - /// - protected ElementViewModelBase(TEndpoint endpoint, IEventAggregator eventAggregator) - : base(endpoint, eventAggregator) - {} - - public virtual async void Save() - => await WithErrorHandlingAsync(async () => - { - try - { - await OnSaveAsync(); - TryClose(); - } - catch (InvalidOperationException ex) - { - // This usually indicates a "lost update" - string question = ex.Message + "\nDo you want to refresh this page loosing any changes you have made?"; - if (MessageBox.Show(question, "Refresh element", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes) - await RefreshAsync(); - } - }); - - /// - /// Handler for saving the input. - /// - protected abstract Task OnSaveAsync(); - } -} diff --git a/src/TypedRest.Wpf/ViewModels/EndpointViewModelBase.cs b/src/TypedRest.Wpf/ViewModels/EndpointViewModelBase.cs deleted file mode 100644 index 4835fcb5..00000000 --- a/src/TypedRest.Wpf/ViewModels/EndpointViewModelBase.cs +++ /dev/null @@ -1,120 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using System.Windows; -using Caliburn.Micro; -using TypedRest.Endpoints; -using TypedRest.Links; -using TypedRest.Wpf.Events; - -namespace TypedRest.Wpf.ViewModels -{ - /// - /// Base class for building view models operating on an . - /// - /// The specific type of to operate on. - public abstract class EndpointViewModelBase : Screen, IHandleWithTask - where TEndpoint : class, IEndpoint - { - /// - /// The endpoint this view model operates on. - /// - protected readonly TEndpoint Endpoint; - - /// - /// Used to send refresh notifications. - /// - protected readonly IEventAggregator EventAggregator; - - /// - /// Creates a new endpoint view model. - /// - /// The endpoint this view model operates on. - /// Used to send refresh notifications. - protected EndpointViewModelBase(TEndpoint endpoint, IEventAggregator eventAggregator) - { - Endpoint = endpoint; - EventAggregator = eventAggregator; - } - - private CancellationTokenSource _cancellationTokenSource; - - protected CancellationToken CancellationToken => _cancellationTokenSource.Token; - - protected override async void OnActivate() - { - base.OnActivate(); - - _cancellationTokenSource = new CancellationTokenSource(); - await RefreshAsync(); - EventAggregator.Subscribe(this); - } - - protected override void OnDeactivate(bool close) - { - EventAggregator.Unsubscribe(this); - - base.OnDeactivate(close); - } - - public async Task RefreshAsync() - => await WithErrorHandlingAsync(OnLoadAsync); - - /// - /// Handler for loading data for the endpoint. - /// - protected virtual Task OnLoadAsync() - => Task.FromResult(true); - - protected async Task WithErrorHandlingAsync(Func action) - { - try - { - await action(); - } - catch (InvalidDataException ex) - { - OnError(ex); - } - catch (UnauthorizedAccessException ex) - { - OnError(ex); - } - catch (KeyNotFoundException ex) - { - OnError(ex); - } - catch (InvalidOperationException ex) - { - OnError(ex); - } - } - - /// - /// Handler for errors reported by endpoints. - /// - protected virtual void OnError(Exception ex) - => MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Exclamation); - - /// - /// Opens a child screen in the parent conductor. - /// - protected void Open(IScreen screen) - => (Parent as IConductor)?.ActivateItem(screen); - - /// - /// The Link relation type used by the server to send refresh notifications. - /// - public string NotifyRel { get; set; } = "notify"; - - // Refresh when notifications are sent from the server - public async Task Handle(IEndpointEvent message) - { - if (message.Endpoint.GetLinks(NotifyRel).Contains(new Link(Endpoint.Uri))) - await RefreshAsync(); - } - } -} diff --git a/src/TypedRest.Wpf/ViewModels/EntryViewModelBase.cs b/src/TypedRest.Wpf/ViewModels/EntryViewModelBase.cs deleted file mode 100644 index 3b515810..00000000 --- a/src/TypedRest.Wpf/ViewModels/EntryViewModelBase.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Threading.Tasks; -using Caliburn.Micro; -using TypedRest.Endpoints; - -namespace TypedRest.Wpf.ViewModels -{ - /// - /// Base class for building view models operating on an . - /// Use this to build a UI that provides access to an API's top-level functionality. - /// - /// The specific type of to operate on. - public abstract class EntryViewModelBase : EndpointViewModelBase - where TEndpoint : EntryEndpoint - { - /// - /// Creates a new REST entry view model. - /// - /// The endpoint this view model operates on. - protected EntryViewModelBase(TEndpoint endpoint) - : base(endpoint, new EventAggregator()) - {} - - protected override async Task OnLoadAsync() - => await Endpoint.ReadMetaAsync(CancellationToken); - } -} diff --git a/src/TypedRest.Wpf/ViewModels/PagedCollectionViewModel.cs b/src/TypedRest.Wpf/ViewModels/PagedCollectionViewModel.cs deleted file mode 100644 index dd221402..00000000 --- a/src/TypedRest.Wpf/ViewModels/PagedCollectionViewModel.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Caliburn.Micro; -using TypedRest.Endpoints.Generic; - -namespace TypedRest.Wpf.ViewModels -{ - /// - /// View model operating on a using pagination. - /// - /// The type of entity the represents. - public class PagedCollectionViewModel : PagedCollectionViewModelBase, IElementEndpoint> - { - /// - /// Creates a new REST paged collection view model. - /// - /// The endpoint this view model operates on. - /// Used to send refresh notifications. - public PagedCollectionViewModel(ICollectionEndpoint endpoint, IEventAggregator eventAggregator) - : base(endpoint, eventAggregator) - {} - - protected override IScreen BuildElementScreen(IElementEndpoint elementEndpoint) - => new ElementViewModel(elementEndpoint, EventAggregator); - - protected override IScreen BuildCreateElementScreen() - => new CreateElementViewModel(Endpoint, EventAggregator); - } -} diff --git a/src/TypedRest.Wpf/ViewModels/PagedCollectionViewModelBase.cs b/src/TypedRest.Wpf/ViewModels/PagedCollectionViewModelBase.cs deleted file mode 100644 index a2ebf0f9..00000000 --- a/src/TypedRest.Wpf/ViewModels/PagedCollectionViewModelBase.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Net.Http.Headers; -using System.Threading.Tasks; -using Caliburn.Micro; -using TypedRest.Endpoints; -using TypedRest.Endpoints.Generic; - -namespace TypedRest.Wpf.ViewModels -{ - /// - /// Base class for building view models operatingon an using pagination. - /// - /// The type of entity the represents. - /// The specific type of to operate on. - /// The specific type of the provides for individual s. - public abstract class PagedCollectionViewModelBase : CollectionViewModelBase - where TEndpoint : class, ICollectionEndpoint - where TElementEndpoint : class, IEndpoint - { - /// - /// Creates a new REST paged collection view model. - /// - /// The endpoint this view model operates on. - /// Used to send refresh notifications. - protected PagedCollectionViewModelBase(TEndpoint endpoint, IEventAggregator eventAggregator) - : base(endpoint, eventAggregator) - {} - - protected override async Task OnLoadAsync() - { - // TODO - await Endpoint.ReadRangeAsync(new RangeItemHeaderValue(0, 0), CancellationToken); - - CanCreate = Endpoint.CreateAllowed.GetValueOrDefault(CanCreate); - NotifyOfPropertyChange(() => CanCreate); - } - } -} diff --git a/src/TypedRest.Wpf/ViewModels/PollingViewModel.cs b/src/TypedRest.Wpf/ViewModels/PollingViewModel.cs deleted file mode 100644 index 35025b51..00000000 --- a/src/TypedRest.Wpf/ViewModels/PollingViewModel.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Threading.Tasks; -using Caliburn.Micro; -using TypedRest.Endpoints.Reactive; - -namespace TypedRest.Wpf.ViewModels -{ - /// - /// View model for tracking the state of an entity represented by a . - /// - /// The type of entity to represent. - public class PollingViewModel : ElementViewModelBase> - { - public PollingViewModel(IPollingEndpoint endpoint, IEventAggregator eventAggregator) - : base(endpoint, eventAggregator) - {} - - protected override async Task OnLoadAsync() - { - Entity = await Endpoint.ReadAsync(CancellationToken); - DisplayName = Entity.ToString(); - NotifyOfPropertyChange(() => Entity); - } - - /// - /// Controls whether a save button is shown and fields are editable. - /// - public bool CanSave - => false; - - protected override Task OnSaveAsync() - => throw new NotImplementedException(); - } -} diff --git a/src/TypedRest.Wpf/ViewModels/ProducerViewModel.cs b/src/TypedRest.Wpf/ViewModels/ProducerViewModel.cs deleted file mode 100644 index cebd8712..00000000 --- a/src/TypedRest.Wpf/ViewModels/ProducerViewModel.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.Threading.Tasks; -using System.Windows; -using Caliburn.Micro; -using TypedRest.Endpoints.Rpc; -using TypedRest.Wpf.Events; - -namespace TypedRest.Wpf.ViewModels -{ - /// - /// View model operating on an . - /// - public class ProducerViewModel : RpcViewModelBase - where TEndpoint : class, IProducerEndpoint - { - /// - /// Creates a new REST function view model. - /// - /// The endpoint this view model operates on. - /// Used to send refresh notifications. - /// A caption for the invokable function. - public ProducerViewModel(TEndpoint endpoint, IEventAggregator eventAggregator, string caption) - : base(endpoint, eventAggregator) - { - DisplayName = caption; - } - - public override async void Invoke() - => await WithErrorHandlingAsync(async () => - { - var result = await OnInvokeAsync(); - EventAggregator.Publish(new InvokeEvent(Endpoint), null); - MessageBox.Show(result.ToString(), DisplayName, MessageBoxButton.OK, MessageBoxImage.Information); - }); - - private async Task OnInvokeAsync() - => await Endpoint.InvokeAsync(CancellationToken); - } -} diff --git a/src/TypedRest.Wpf/ViewModels/RpcViewModelBase.cs b/src/TypedRest.Wpf/ViewModels/RpcViewModelBase.cs deleted file mode 100644 index 3aff82c9..00000000 --- a/src/TypedRest.Wpf/ViewModels/RpcViewModelBase.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Threading.Tasks; -using Caliburn.Micro; -using TypedRest.Endpoints.Rpc; - -namespace TypedRest.Wpf.ViewModels -{ - /// - /// Base class for building view models operating on an . - /// - /// The specific type of to operate on. - public abstract class RpcViewModelBase : EndpointViewModelBase - where TEndpoint : class, IRpcEndpoint - { - /// - /// Creates a new RPC view model. - /// - /// The endpoint this view model operates on. - /// Used to send refresh notifications. - protected RpcViewModelBase(TEndpoint endpoint, IEventAggregator eventAggregator) - : base(endpoint, eventAggregator) - {} - - public bool CanInvoke { get; set; } - - protected override async Task OnLoadAsync() - { - try - { - await Endpoint.ProbeAsync(CancellationToken); - } - catch (Exception) - { - // HTTP OPTIONS server-side implementation is optional - } - - CanInvoke = Endpoint.InvokeAllowed.GetValueOrDefault(CanInvoke); - NotifyOfPropertyChange(() => CanInvoke); - } - - public abstract void Invoke(); - } -} diff --git a/src/TypedRest.Wpf/ViewModels/StreamingCollectionViewModel.cs b/src/TypedRest.Wpf/ViewModels/StreamingCollectionViewModel.cs deleted file mode 100644 index 6bafd92a..00000000 --- a/src/TypedRest.Wpf/ViewModels/StreamingCollectionViewModel.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Caliburn.Micro; -using TypedRest.Endpoints.Generic; -using TypedRest.Endpoints.Reactive; - -namespace TypedRest.Wpf.ViewModels -{ - /// - /// View model operating on a . - /// - /// The type of entity the represents. - public class StreamingCollectionViewModel : StreamingCollectionViewModelBase, IElementEndpoint> - { - /// - /// Creates a new REST paged collection view model. - /// - /// The endpoint this view model operates on. - /// Used to send refresh notifications. - public StreamingCollectionViewModel(IStreamingCollectionEndpoint endpoint, IEventAggregator eventAggregator) - : base(endpoint, eventAggregator) - {} - - protected override IScreen BuildElementScreen(IElementEndpoint elementEndpoint) - => new ElementViewModel(elementEndpoint, EventAggregator); - - protected override IScreen BuildCreateElementScreen() - => new CreateElementViewModel(Endpoint, EventAggregator); - } -} diff --git a/src/TypedRest.Wpf/ViewModels/StreamingCollectionViewModelBase.cs b/src/TypedRest.Wpf/ViewModels/StreamingCollectionViewModelBase.cs deleted file mode 100644 index 96a1a2bb..00000000 --- a/src/TypedRest.Wpf/ViewModels/StreamingCollectionViewModelBase.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Caliburn.Micro; -using TypedRest.Endpoints; -using TypedRest.Endpoints.Generic; -using TypedRest.Endpoints.Reactive; - -namespace TypedRest.Wpf.ViewModels -{ - /// - /// Base class for building view models operating on an . - /// - /// The type of entity the represents. - /// The specific type of to operate on. - /// The specific type of the provides for individual s. - public abstract class StreamingCollectionViewModelBase : CollectionViewModelBase - where TEndpoint : class, IStreamingCollectionEndpoint - where TElementEndpoint : class, IEndpoint - { - /// - /// Creates a new REST paged collection view model. - /// - /// The endpoint this view model operates on. - /// Used to send refresh notifications. - protected StreamingCollectionViewModelBase(TEndpoint endpoint, IEventAggregator eventAggregator) - : base(endpoint, eventAggregator) - { - CanCreate = false; - CanOpenElement = false; - } - } -} diff --git a/src/TypedRest.Wpf/ViewModels/_Namespace.cs b/src/TypedRest.Wpf/ViewModels/_Namespace.cs deleted file mode 100644 index d3a4c332..00000000 --- a/src/TypedRest.Wpf/ViewModels/_Namespace.cs +++ /dev/null @@ -1,2 +0,0 @@ -//! \namespace TypedRest.Wpf.ViewModels -//! \brief WPF View Models that wrap TypedRest endpoints for binding to WPF Views. diff --git a/src/TypedRest.Wpf/Views/ActionView.xaml b/src/TypedRest.Wpf/Views/ActionView.xaml deleted file mode 100644 index 268cc220..00000000 --- a/src/TypedRest.Wpf/Views/ActionView.xaml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/TypedRest.Wpf/Views/CollectionView.xaml b/src/TypedRest.Wpf/Views/CollectionView.xaml deleted file mode 100644 index 7dde9ec8..00000000 --- a/src/TypedRest.Wpf/Views/CollectionView.xaml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - diff --git a/src/TypedRest.Wpf/Views/ElementView.xaml b/src/TypedRest.Wpf/Views/ElementView.xaml deleted file mode 100644 index 9f48e1bf..00000000 --- a/src/TypedRest.Wpf/Views/ElementView.xaml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/src/TypedRest.Wpf/Views/PagedCollectionView.xaml b/src/TypedRest.Wpf/Views/PagedCollectionView.xaml deleted file mode 100644 index 723a74b9..00000000 --- a/src/TypedRest.Wpf/Views/PagedCollectionView.xaml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - diff --git a/src/TypedRest.Wpf/Views/ProducerView.xaml b/src/TypedRest.Wpf/Views/ProducerView.xaml deleted file mode 100644 index b75f81d2..00000000 --- a/src/TypedRest.Wpf/Views/ProducerView.xaml +++ /dev/null @@ -1,5 +0,0 @@ - -