From bfb3bd36cce1e058f90df35a40ddbbfbf7c80c3a Mon Sep 17 00:00:00 2001 From: Dennis Beuchler Date: Mon, 8 Nov 2021 13:29:17 +0100 Subject: [PATCH 01/13] Api for filter product properties in product query --- .../Products/ProductQuery.cs | 50 +++++++++++++++++++ .../Implementation/Storage/ProductStorage.cs | 4 +- .../Endpoint/ProductInteraction.cs | 7 +-- .../Modification/IProductConverter.cs | 4 +- .../Model/ProductDefinitionModel.cs | 4 ++ .../Modification/ProductConverter.cs | 13 ++++- 6 files changed, 72 insertions(+), 10 deletions(-) diff --git a/src/Moryx.AbstractionLayer/Products/ProductQuery.cs b/src/Moryx.AbstractionLayer/Products/ProductQuery.cs index eab917a4..d36f7895 100644 --- a/src/Moryx.AbstractionLayer/Products/ProductQuery.cs +++ b/src/Moryx.AbstractionLayer/Products/ProductQuery.cs @@ -1,7 +1,9 @@ // Copyright (c) 2020, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 +using System.Collections.Generic; using System.Runtime.Serialization; +using Moryx.Serialization; namespace Moryx.AbstractionLayer.Products { @@ -65,6 +67,52 @@ public class ProductQuery /// [DataMember] public Selector Selector { get; set; } + + /// + /// List of property filters + /// + [DataMember] + public List PropertyFilters { get; set; } + } + + /// + /// Property filter wrapper for the filtered entry + /// + [DataContract] + public class PropertyFilter + { + /// + /// Entry to filter + /// + [DataMember] + public Entry Entry { get; set; } + + /// + /// Operator for the filter expression + /// + [DataMember] + public PropertyFilterOperator Operator { get; set; } + } + + /// + /// Property filter operator expression + /// + public enum PropertyFilterOperator + { + /// + /// Value equals + /// + Equals, + + /// + /// Value is greater then + /// + GreaterThen, + + /// + /// Value is less then + /// + LessThen } /// @@ -76,10 +124,12 @@ public enum RevisionFilter /// Fetch all revisions, this is the default /// All = 0, + /// /// Fetch only the latest revision /// Latest = 1, + /// /// Fetch only specific revisions /// diff --git a/src/Moryx.Products.Management/Implementation/Storage/ProductStorage.cs b/src/Moryx.Products.Management/Implementation/Storage/ProductStorage.cs index 8a90fd97..40a49e56 100644 --- a/src/Moryx.Products.Management/Implementation/Storage/ProductStorage.cs +++ b/src/Moryx.Products.Management/Implementation/Storage/ProductStorage.cs @@ -664,7 +664,7 @@ public IReadOnlyList LoadWithStrategy(Expression() // Create query : query.Union(repo.Linq.Where(queryFilter).Cast()); // Append query } @@ -673,7 +673,7 @@ public IReadOnlyList LoadWithStrategy(Expression entities; if (query == null || (entities = query.ToList()).Count == 0) return new TInstance[0]; - + var instances = TransformInstances(uow, entities).OfType().ToArray(); // Final check against compiled expression var compiledSelector = selector.Compile(); diff --git a/src/Moryx.Products.Management/Modification/Endpoint/ProductInteraction.cs b/src/Moryx.Products.Management/Modification/Endpoint/ProductInteraction.cs index 67555d5d..bd0dc01c 100644 --- a/src/Moryx.Products.Management/Modification/Endpoint/ProductInteraction.cs +++ b/src/Moryx.Products.Management/Modification/Endpoint/ProductInteraction.cs @@ -62,12 +62,7 @@ public ProductCustomization GetCustomization() { ProductTypes = ReflectionTool .GetPublicClasses(new IsConfiguredFilter(Config.TypeStrategies).IsConfigured) - .Select(pt => new ProductDefinitionModel - { - Name = pt.Name, - DisplayName = pt.GetDisplayName() ?? pt.Name, - BaseDefinition = pt.BaseType?.Name - }).ToArray(), + .Select(Converter.ConvertProductType).ToArray(), RecipeTypes = ReflectionTool .GetPublicClasses(new IsConfiguredFilter(Config.RecipeStrategies).IsConfigured) .Select(rt => new RecipeDefinitionModel diff --git a/src/Moryx.Products.Management/Modification/IProductConverter.cs b/src/Moryx.Products.Management/Modification/IProductConverter.cs index 5ef492f3..f66ba2cc 100644 --- a/src/Moryx.Products.Management/Modification/IProductConverter.cs +++ b/src/Moryx.Products.Management/Modification/IProductConverter.cs @@ -1,7 +1,7 @@ // Copyright (c) 2020, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 -using Moryx.AbstractionLayer; +using System; using Moryx.AbstractionLayer.Products; using Moryx.AbstractionLayer.Recipes; using Moryx.Workflows; @@ -12,6 +12,8 @@ internal interface IProductConverter { ProductModel ConvertProduct(IProductType productType, bool flat); + ProductDefinitionModel ConvertProductType(Type productType); + IProductType ConvertProductBack(ProductModel source, ProductType target); RecipeModel ConvertRecipe(IRecipe recipe); diff --git a/src/Moryx.Products.Management/Modification/Model/ProductDefinitionModel.cs b/src/Moryx.Products.Management/Modification/Model/ProductDefinitionModel.cs index a9b9e9e4..65a19fc0 100644 --- a/src/Moryx.Products.Management/Modification/Model/ProductDefinitionModel.cs +++ b/src/Moryx.Products.Management/Modification/Model/ProductDefinitionModel.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0 using System.Runtime.Serialization; +using Moryx.Serialization; namespace Moryx.Products.Management.Modification { @@ -16,5 +17,8 @@ internal class ProductDefinitionModel [DataMember] public string BaseDefinition { get; set; } + + [DataMember] + public Entry Properties { get; set; } } } diff --git a/src/Moryx.Products.Management/Modification/ProductConverter.cs b/src/Moryx.Products.Management/Modification/ProductConverter.cs index 7d9a3bc3..e9d23e53 100644 --- a/src/Moryx.Products.Management/Modification/ProductConverter.cs +++ b/src/Moryx.Products.Management/Modification/ProductConverter.cs @@ -39,7 +39,7 @@ internal class ProductConverter : IProductConverter #endregion #region To Model - + public ProductModel ConvertProduct(IProductType productType, bool flat) { // Base object @@ -74,6 +74,17 @@ public ProductModel ConvertProduct(IProductType productType, bool flat) return converted; } + public ProductDefinitionModel ConvertProductType(Type productType) + { + return new() + { + Name = productType.Name, + DisplayName = productType.GetDisplayName() ?? productType.Name, + BaseDefinition = productType.BaseType?.Name, + Properties = EntryConvert.EncodeClass(productType, ProductSerialization) + }; + } + private static ProductFile[] ConvertFiles(IProductType productType, IEnumerable properties) { var files = (from property in properties From 8c03d7bc598b37ef61a45ce56088b91771b4012f Mon Sep 17 00:00:00 2001 From: Dennis Beuchler Date: Thu, 11 Nov 2021 11:13:17 +0100 Subject: [PATCH 02/13] Added type filter to ProductsWorkspace and added PropertyFilter view --- ...Products.UI.Interaction.csproj.DotSettings | 2 + .../Filter/PropertyFilterDialogView.xaml | 43 ++++++ .../Filter/PropertyFilterDialogView.xaml.cs | 15 ++ .../Filter/PropertyFilterDialogViewModel.cs | 71 +++++++++ .../Products/ProductsWorkspaceView.xaml | 76 +++++++--- .../Products/ProductsWorkspaceViewModel.cs | 34 ++++- .../ProductService/Reference.cs | 140 ++++++++++++++---- ...ervice.json => dotnet-svcutil.params.json} | 9 +- .../ViewModels/ProductDefinitionViewModel.cs | 47 ++++++ .../ViewModels}/ProductQueryViewModel.cs | 66 +++++++-- src/Moryx.Products.UI/update-service.ps1 | 1 + ...ervice.json => dotnet-svcutil.params.json} | 9 +- src/Moryx.Resources.UI/update-service.ps1 | 1 + 13 files changed, 442 insertions(+), 72 deletions(-) create mode 100644 src/Moryx.Products.UI.Interaction/Products/Filter/PropertyFilterDialogView.xaml create mode 100644 src/Moryx.Products.UI.Interaction/Products/Filter/PropertyFilterDialogView.xaml.cs create mode 100644 src/Moryx.Products.UI.Interaction/Products/Filter/PropertyFilterDialogViewModel.cs rename src/Moryx.Products.UI/Connected Services/ProductService/{ConnectedService.json => dotnet-svcutil.params.json} (70%) create mode 100644 src/Moryx.Products.UI/ViewModels/ProductDefinitionViewModel.cs rename src/{Moryx.Products.UI.Interaction/Products => Moryx.Products.UI/ViewModels}/ProductQueryViewModel.cs (54%) create mode 100644 src/Moryx.Products.UI/update-service.ps1 rename src/Moryx.Resources.UI/Connected Services/ResourceService/{ConnectedService.json => dotnet-svcutil.params.json} (70%) create mode 100644 src/Moryx.Resources.UI/update-service.ps1 diff --git a/src/Moryx.Products.UI.Interaction/Moryx.Products.UI.Interaction.csproj.DotSettings b/src/Moryx.Products.UI.Interaction/Moryx.Products.UI.Interaction.csproj.DotSettings index 78a064f5..b1f67e85 100644 --- a/src/Moryx.Products.UI.Interaction/Moryx.Products.UI.Interaction.csproj.DotSettings +++ b/src/Moryx.Products.UI.Interaction/Moryx.Products.UI.Interaction.csproj.DotSettings @@ -13,7 +13,9 @@ True True True + True True + True True True True diff --git a/src/Moryx.Products.UI.Interaction/Products/Filter/PropertyFilterDialogView.xaml b/src/Moryx.Products.UI.Interaction/Products/Filter/PropertyFilterDialogView.xaml new file mode 100644 index 00000000..e8795429 --- /dev/null +++ b/src/Moryx.Products.UI.Interaction/Products/Filter/PropertyFilterDialogView.xaml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Moryx.Products.UI.Interaction/Products/Filter/PropertyFilterDialogView.xaml.cs b/src/Moryx.Products.UI.Interaction/Products/Filter/PropertyFilterDialogView.xaml.cs new file mode 100644 index 00000000..a13dbe41 --- /dev/null +++ b/src/Moryx.Products.UI.Interaction/Products/Filter/PropertyFilterDialogView.xaml.cs @@ -0,0 +1,15 @@ +using System.Windows.Controls; + +namespace Moryx.Products.UI.Interaction +{ + /// + /// Interaction logic for PropertyFilterDialogView.xaml + /// + public partial class PropertyFilterDialogView : UserControl + { + public PropertyFilterDialogView() + { + InitializeComponent(); + } + } +} diff --git a/src/Moryx.Products.UI.Interaction/Products/Filter/PropertyFilterDialogViewModel.cs b/src/Moryx.Products.UI.Interaction/Products/Filter/PropertyFilterDialogViewModel.cs new file mode 100644 index 00000000..536a430e --- /dev/null +++ b/src/Moryx.Products.UI.Interaction/Products/Filter/PropertyFilterDialogViewModel.cs @@ -0,0 +1,71 @@ +using System.Collections.Generic; +using System.Windows.Input; +using Moryx.ClientFramework.Dialog; +using Moryx.Controls; +using Moryx.WpfToolkit; +using Entry = Moryx.Serialization.Entry; + +namespace Moryx.Products.UI.Interaction +{ + internal class PropertyFilterDialogViewModel : DialogScreen + { + private ProductDefinitionViewModel _selectedProductDefinition; + private EntryViewModel _currentEntryViewModel; + + public ICommand ApplyCmd { get; } + + public ICommand CancelCmd { get; } + + public ProductDefinitionViewModel ProductType + { + get => _selectedProductDefinition; + set + { + _selectedProductDefinition = value; + NotifyOfPropertyChange(); + } + } + + public EntryViewModel CurrentEntryViewModel + { + get => _currentEntryViewModel; + set + { + _currentEntryViewModel = value; + NotifyOfPropertyChange(); + } + } + + public ICommand AddCmd { get; set; } + + public PropertyFilterDialogViewModel(ProductDefinitionViewModel productType) + { + ProductType = productType; + + AddCmd = new RelayCommand(Add); + ApplyCmd = new RelayCommand(Apply); + CancelCmd = new RelayCommand(Cancel); + } + + private void Add(object obj) + { + var entry = ((EntryViewModel) obj).Entry; + + if (CurrentEntryViewModel == null) + CurrentEntryViewModel = new EntryViewModel(new List { entry }); + else + CurrentEntryViewModel.SubEntries.Add(new EntryViewModel(entry)); + + } + + private void Apply(object obj) + { + + } + + private void Cancel(object obj) + { + TryClose(false); + } + } +} diff --git a/src/Moryx.Products.UI.Interaction/Products/ProductsWorkspaceView.xaml b/src/Moryx.Products.UI.Interaction/Products/ProductsWorkspaceView.xaml index b7f68504..ab3cc3fa 100644 --- a/src/Moryx.Products.UI.Interaction/Products/ProductsWorkspaceView.xaml +++ b/src/Moryx.Products.UI.Interaction/Products/ProductsWorkspaceView.xaml @@ -160,33 +160,61 @@ Margin="0,0,0,5" SharedSizeGroupName="ProductQuery"> - - - - - - - - - - - + + + + + + + + + + + - + + + + + + + + + -