From 862adb6a0ea99cf74826753a6275b90660b54a33 Mon Sep 17 00:00:00 2001 From: antoineatstariongroup Date: Wed, 11 Dec 2024 16:40:41 +0100 Subject: [PATCH] Fix #10: Generic Export UI improvement --- .../GenericExporterViewModelTestFixture.cs | 20 +-- .../Exporter/GenericExportSetupViewModel.cs | 6 + .../Exporter/GenericExporterViewModel.cs | 62 ++++++-- .../Exporter/IGenericExportSetupViewModel.cs | 5 + .../Exporter/IGenericExporterViewModel.cs | 12 +- EA-ModelKit/Views/Export/GenericExport.xaml | 135 ++++++------------ .../Views/Export/GenericExport.xaml.cs | 3 +- .../Views/Export/GenericExportSetupView.xaml | 61 ++++++++ .../Export/GenericExportSetupView.xaml.cs | 39 +++++ 9 files changed, 227 insertions(+), 116 deletions(-) create mode 100644 EA-ModelKit/Views/Export/GenericExportSetupView.xaml create mode 100644 EA-ModelKit/Views/Export/GenericExportSetupView.xaml.cs diff --git a/EA-ModelKit.Tests/ViewModels/Exporter/GenericExporterViewModelTestFixture.cs b/EA-ModelKit.Tests/ViewModels/Exporter/GenericExporterViewModelTestFixture.cs index 3ee9c5b..b53026c 100644 --- a/EA-ModelKit.Tests/ViewModels/Exporter/GenericExporterViewModelTestFixture.cs +++ b/EA-ModelKit.Tests/ViewModels/Exporter/GenericExporterViewModelTestFixture.cs @@ -121,7 +121,7 @@ public void VerifyViewModelProperties() { Assert.That(this.exporterViewModel.CanProceed, Is.False); Assert.That(this.exporterViewModel.SelectedFilePath, Is.Null); - Assert.That(this.exporterViewModel.ExportSetups.Items, Is.Empty); + Assert.That(this.exporterViewModel.AvailableExportSetups.Items, Is.Empty); Assert.That(this.exporterViewModel.OutputFileCommand, Is.Null); Assert.That(this.exporterViewModel.ExportCommand, Is.Null); }); @@ -141,22 +141,22 @@ public void VerifyInitializeViewModel() Assert.Multiple(() => { this.cacheService.Verify(x => x.GetTaggedValues(It.IsAny()), Times.Once); - Assert.That(this.exporterViewModel.ExportSetups.Items, Is.Not.Empty); - Assert.That(this.exporterViewModel.ExportSetups, Has.Count.EqualTo(3)); + Assert.That(this.exporterViewModel.AvailableExportSetups.Items, Is.Not.Empty); + Assert.That(this.exporterViewModel.AvailableExportSetups, Has.Count.EqualTo(3)); Assert.That(this.exporterViewModel.OutputFileCommand, Is.Not.Null); Assert.That(this.exporterViewModel.ExportCommand, Is.Not.Null); - Assert.That(this.exporterViewModel.ExportSetups.Items.All(x => x.ShouldBeExported), Is.True); + Assert.That(this.exporterViewModel.AvailableExportSetups.Items.All(x => x.ShouldBeExported), Is.True); - Assert.That(this.exporterViewModel.ExportSetups.Items.Single(x => x.ElementKind == "Requirement").AvailableTaggedValuesForExport + Assert.That(this.exporterViewModel.AvailableExportSetups.Items.Single(x => x.ElementKind == "Requirement").AvailableTaggedValuesForExport .Count(), Is.EqualTo(2)); - Assert.That(this.exporterViewModel.ExportSetups.Items.Single(x => x.ElementKind == "Function").AvailableTaggedValuesForExport + Assert.That(this.exporterViewModel.AvailableExportSetups.Items.Single(x => x.ElementKind == "Function").AvailableTaggedValuesForExport .Count(), Is.EqualTo(2)); - Assert.That(this.exporterViewModel.ExportSetups.Items.Single(x => x.ElementKind == "Product").HaveAnyTaggedValues, + Assert.That(this.exporterViewModel.AvailableExportSetups.Items.Single(x => x.ElementKind == "Product").HaveAnyTaggedValues, Is.False); - Assert.That(this.exporterViewModel.ExportSetups.Items.All(x => x.AvailableTaggedValuesForExport.Count() + Assert.That(this.exporterViewModel.AvailableExportSetups.Items.All(x => x.AvailableTaggedValuesForExport.Count() == x.SelectedTaggedValuesForExport.Count()), Is.True); }); } @@ -193,10 +193,10 @@ public void VerifyCanProceedComputation() this.exporterViewModel.OutputFileCommand.Execute().Subscribe(); Assert.That(this.exporterViewModel.CanProceed, Is.True); - this.exporterViewModel.ExportSetups.Items.ForEach(x => x.ShouldBeExported = false); + this.exporterViewModel.AvailableExportSetups.Items.ForEach(x => x.ShouldBeExported = false); Assert.That(this.exporterViewModel.CanProceed, Is.False); - this.exporterViewModel.ExportSetups.Items[0].ShouldBeExported = true; + this.exporterViewModel.AvailableExportSetups.Items[0].ShouldBeExported = true; Assert.That(this.exporterViewModel.CanProceed, Is.True); } diff --git a/EA-ModelKit/ViewModels/Exporter/GenericExportSetupViewModel.cs b/EA-ModelKit/ViewModels/Exporter/GenericExportSetupViewModel.cs index e406113..4cc4809 100644 --- a/EA-ModelKit/ViewModels/Exporter/GenericExportSetupViewModel.cs +++ b/EA-ModelKit/ViewModels/Exporter/GenericExportSetupViewModel.cs @@ -67,6 +67,7 @@ public GenericExportSetupViewModel(IReadOnlyList elements) } this.ElementKind = elements[0].ElementKind; + this.ElementType = elements[0].ElementType; this.AvailableTaggedValuesForExport = elements .SelectMany(x => x.TaggedValues.Keys) @@ -83,6 +84,11 @@ public GenericExportSetupViewModel(IReadOnlyList elements) this.ExportableElements = elements; } + /// + /// Gets the Type + /// + public string ElementType { get; } + /// /// Gets the collection of available Connectors kind that could be exported /// diff --git a/EA-ModelKit/ViewModels/Exporter/GenericExporterViewModel.cs b/EA-ModelKit/ViewModels/Exporter/GenericExporterViewModel.cs index c43cd23..1530464 100644 --- a/EA-ModelKit/ViewModels/Exporter/GenericExporterViewModel.cs +++ b/EA-ModelKit/ViewModels/Exporter/GenericExporterViewModel.cs @@ -53,6 +53,11 @@ internal class GenericExporterViewModel : BaseDialogViewModel, IGenericExporterV /// private readonly ICacheService cacheService; + /// + /// Gets the injected + /// + private readonly IGenericExporterService exporterService; + /// /// The injected /// @@ -64,14 +69,19 @@ internal class GenericExporterViewModel : BaseDialogViewModel, IGenericExporterV private bool canProceed; /// - /// Backing field for + /// Backing field for /// - private string selectedFilePath; + private bool haveSelectedExportSetup; /// - /// Gets the injected + /// Backing field for /// - private readonly IGenericExporterService exporterService; + private IGenericExportSetupViewModel selectedExportSetup; + + /// + /// Backing field for + /// + private string selectedFilePath; /// /// Initialize a new instance of @@ -79,7 +89,7 @@ internal class GenericExporterViewModel : BaseDialogViewModel, IGenericExporterV /// The /// The injected /// The injected - /// The injected + /// The injected public GenericExporterViewModel(ILoggerService loggerService, ICacheService cacheService, IViewBuilderService viewBuilderService, IGenericExporterService exporterService) : base(loggerService) { @@ -109,7 +119,7 @@ public bool CanProceed /// /// Gets the of /// - public SourceList ExportSetups { get; } = new(); + public SourceList AvailableExportSetups { get; } = new(); /// /// Gets the that allows the selection of the output file @@ -121,6 +131,24 @@ public bool CanProceed /// public ReactiveCommand ExportCommand { get; private set; } + /// + /// Gets or sets the currently selected + /// + public IGenericExportSetupViewModel SelectedExportSetup + { + get => this.selectedExportSetup; + set => this.RaiseAndSetIfChanged(ref this.selectedExportSetup, value); + } + + /// + /// Asserts that the an is selected or not + /// + public bool HaveSelectedExportSetup + { + get => this.haveSelectedExportSetup; + private set => this.RaiseAndSetIfChanged(ref this.haveSelectedExportSetup, value); + } + /// /// Initialies properties of the ViewModel /// @@ -145,9 +173,13 @@ public void InitializeViewModel(IReadOnlyList elements) ? existingTaggedValues : [], this.cacheService.GetAssociatedConnectors(x.ElementID))); - this.ExportSetups.AddRange(slimElements.GroupBy(x => x.ElementKind) - .Select(e => new GenericExportSetupViewModel(e.ToList()))); + this.AvailableExportSetups.AddRange(slimElements + .GroupBy(x => x.ElementKind) + .Select(e => new GenericExportSetupViewModel(e.ToList())) + .OrderBy(x => x.ElementType) + .ThenBy(x => x.ElementKind)); + this.SelectedExportSetup = this.AvailableExportSetups.Items[0]; this.InitializeObservablesAndCommands(); } @@ -158,10 +190,14 @@ private void InitializeObservablesAndCommands() { this.OutputFileCommand = ReactiveCommand.Create(this.OnOutputFileSelect); - this.Disposables.Add(this.ExportSetups.Connect().WhenPropertyChanged(x => x.ShouldBeExported) + this.Disposables.Add(this.AvailableExportSetups.Connect().WhenPropertyChanged(x => x.ShouldBeExported) .Subscribe(_ => this.ComputeCanProceed())); this.Disposables.Add(this.WhenPropertyChanged(x => x.SelectedFilePath).Subscribe(_ => this.ComputeCanProceed())); + + this.Disposables.Add(this.WhenPropertyChanged(x => x.SelectedExportSetup) + .Subscribe(_ => this.HaveSelectedExportSetup = this.SelectedExportSetup != null)); + this.ExportCommand = ReactiveCommand.CreateFromTask(this.OnExportAsync, this.WhenAnyValue(x => x.CanProceed)); } @@ -174,10 +210,10 @@ private async Task OnExportAsync() try { - var exportConfiguration = this.ExportSetups.Items.Where(x => x.ShouldBeExported) - .Select(x => new GenericExportConfiguration(x.ExportableElements, + var exportConfiguration = this.AvailableExportSetups.Items.Where(x => x.ShouldBeExported) + .Select(x => new GenericExportConfiguration(x.ExportableElements, [..x.SelectedTaggedValuesForExport], [..x.SelectedConnectorsForExport])); - + await this.exporterService.ExportElementsAsync(this.selectedFilePath, [..exportConfiguration]); this.CloseWindowBehavior.Close(); } @@ -202,7 +238,7 @@ private void ComputeCanProceed() return; } - this.CanProceed = this.ExportSetups.Items.Any(x => x.ShouldBeExported); + this.CanProceed = this.AvailableExportSetups.Items.Any(x => x.ShouldBeExported); } /// diff --git a/EA-ModelKit/ViewModels/Exporter/IGenericExportSetupViewModel.cs b/EA-ModelKit/ViewModels/Exporter/IGenericExportSetupViewModel.cs index babfcb3..7dd03c7 100644 --- a/EA-ModelKit/ViewModels/Exporter/IGenericExportSetupViewModel.cs +++ b/EA-ModelKit/ViewModels/Exporter/IGenericExportSetupViewModel.cs @@ -76,5 +76,10 @@ internal interface IGenericExportSetupViewModel: INotifyPropertyChanged /// Gets or sets the collection of selected Connectors kind that have to be exported /// IEnumerable SelectedConnectorsForExport { get; set; } + + /// + /// Gets the Type + /// + string ElementType { get; } } } diff --git a/EA-ModelKit/ViewModels/Exporter/IGenericExporterViewModel.cs b/EA-ModelKit/ViewModels/Exporter/IGenericExporterViewModel.cs index 708385e..7527333 100644 --- a/EA-ModelKit/ViewModels/Exporter/IGenericExporterViewModel.cs +++ b/EA-ModelKit/ViewModels/Exporter/IGenericExporterViewModel.cs @@ -39,7 +39,7 @@ internal interface IGenericExporterViewModel : IBaseDialogViewModel /// /// Gets the of /// - SourceList ExportSetups { get; } + SourceList AvailableExportSetups { get; } /// /// Gets the path to the file that should be use for export @@ -61,6 +61,16 @@ internal interface IGenericExporterViewModel : IBaseDialogViewModel /// ReactiveCommand ExportCommand { get; } + /// + /// Gets or sets the currently selected + /// + IGenericExportSetupViewModel SelectedExportSetup { get; set; } + + /// + /// Asserts that the an is selected or not + /// + bool HaveSelectedExportSetup { get; } + /// /// Initialies properties of the ViewModel /// diff --git a/EA-ModelKit/Views/Export/GenericExport.xaml b/EA-ModelKit/Views/Export/GenericExport.xaml index 2a83b49..10f5e2a 100644 --- a/EA-ModelKit/Views/Export/GenericExport.xaml +++ b/EA-ModelKit/Views/Export/GenericExport.xaml @@ -6,14 +6,15 @@ xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core" xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm" xmlns:behaviors="clr-namespace:EAModelKit.Behaviors" - xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors" + xmlns:export="clr-namespace:EAModelKit.Views.Export" + xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid" xmlns:converters="clr-namespace:EAModelKit.Converters" mc:Ignorable="d" Title="Generic Export" MinHeight="100" Height="Auto" + MaxWidth="1000" SizeToContent="Height" - MaxWidth="600" Topmost="{Binding IsTopMost}" WindowStartupLocation="CenterScreen" ResizeMode="NoResize" @@ -24,10 +25,7 @@ - - - - + @@ -44,91 +42,48 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Selected Output File: - - -