From 89ceccbbcdf297ab9c016e5931fefed367f88df5 Mon Sep 17 00:00:00 2001 From: Joao Rua Date: Tue, 30 Apr 2024 17:36:16 +0100 Subject: [PATCH] Product tree doesnt collapse anymore --- .../SystemRepresentationBodyTestFixture.cs | 200 ++++++++++-------- .../SystemRepresentationBody.razor.cs | 21 +- .../SystemRepresentationTree.razor.cs | 59 +++--- .../SystemRepresentationTree.razor.css | 1 + .../Components/Shared/BaseNodeViewModel.cs | 40 +++- .../ISystemRepresentationBodyViewModel.cs | 19 +- .../SystemNodeViewModel.cs | 31 +-- .../SystemRepresentationBodyViewModel.cs | 74 ++++--- .../SystemRepresentationTreeViewModel.cs | 115 +++++++--- 9 files changed, 345 insertions(+), 215 deletions(-) diff --git a/COMETwebapp.Tests/Components/SystemRepresentation/SystemRepresentationBodyTestFixture.cs b/COMETwebapp.Tests/Components/SystemRepresentation/SystemRepresentationBodyTestFixture.cs index 2c91a1a1..bef3c30a 100644 --- a/COMETwebapp.Tests/Components/SystemRepresentation/SystemRepresentationBodyTestFixture.cs +++ b/COMETwebapp.Tests/Components/SystemRepresentation/SystemRepresentationBodyTestFixture.cs @@ -1,26 +1,26 @@ // -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) 2023-2024 RHEA System S.A. -// -// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Nabil Abbar -// -// This file is part of CDP4-COMET WEB Community Edition -// The CDP4-COMET WEB Community Edition is the RHEA Web Application implementation of ECSS-E-TM-10-25 Annex A and Annex C. -// -// The CDP4-COMET WEB Community Edition is free software; you can redistribute it and/or -// modify it under the terms of the GNU Affero General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// The CDP4-COMET WEB Community Edition is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// +// Copyright (c) 2024 Starion Group S.A. +// +// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, João Rua +// +// This file is part of COMET WEB Community Edition +// The COMET WEB Community Edition is the Starion Group Web Application implementation of ECSS-E-TM-10-25 Annex A and Annex C. +// +// The COMET WEB Community Edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU Affero General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// The COMET WEB Community Edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Affero General Public License for more details. -// +// // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -// -// -------------------------------------------------------------------------------------------------------------------- +// +// -------------------------------------------------------------------------------------------------------------------- namespace COMETwebapp.Tests.Components.SystemRepresentation { @@ -34,7 +34,10 @@ namespace COMETwebapp.Tests.Components.SystemRepresentation using CDP4Dal; using CDP4Dal.DAL; - + using CDP4Dal.Events; + + using CDP4Web.Enumerations; + using COMET.Web.Common.Components.Selectors; using COMET.Web.Common.Model.Configuration; using COMET.Web.Common.Services.ConfigurationService; @@ -123,76 +126,54 @@ public void SetUp() var enumerationValues = new List { "cube", "sphere", "cylinder" }; - this.iteration = new Iteration(Guid.NewGuid(), this.assembler.Cache, this.uri) + var elementDefinition = new ElementDefinition(Guid.NewGuid(), this.assembler.Cache, this.uri) { - Element = + Name = "TestElement", + Owner = this.domain, + ShortName = "TE", + ContainedElement = { - new ElementDefinition(Guid.NewGuid(), this.assembler.Cache, this.uri) + new ElementUsage(Guid.NewGuid(), this.assembler.Cache, this.uri) { - Name = "TestElement", Owner = this.domain, - ShortName = "TE", - ContainedElement = - { - new ElementUsage(Guid.NewGuid(), this.assembler.Cache, this.uri) - { - Owner = this.domain, - ShortName = "TEU", - ElementDefinition = new ElementDefinition(Guid.NewGuid(), this.assembler.Cache, this.uri) - { - Name = "TestElementUsage", - Owner = this.domain, - ShortName = "TEU" - } - } - }, - Parameter = + ShortName = "TEU", + ElementDefinition = new ElementDefinition(Guid.NewGuid(), this.assembler.Cache, this.uri) { - new Parameter(Guid.NewGuid(), this.assembler.Cache, this.uri) - { - Owner = this.domain, - ParameterType = new BooleanParameterType(Guid.NewGuid(), this.assembler.Cache, this.uri) - { - Name = "paramType1", - ShortName = "BPT" - }, - ValueSet = - { - new ParameterValueSet() - { - Published = new ValueArray(enumerationValues), - Manual = new ValueArray(enumerationValues) - } - }, - Scale = new OrdinalScale - { - Iid = Guid.NewGuid(), - ShortName = "m" - } - } + Name = "TestElementUsage", + Owner = this.domain, + ShortName = "TEU" } } }, - TopElement = new ElementDefinition(Guid.NewGuid(), this.assembler.Cache, this.uri) + Parameter = { - Name = "TestElement", - Owner = this.domain, - ShortName = "TE", - ContainedElement = + new Parameter(Guid.NewGuid(), this.assembler.Cache, this.uri) + { + Owner = this.domain, + ParameterType = new BooleanParameterType(Guid.NewGuid(), this.assembler.Cache, this.uri) + { + Name = "paramType1", + ShortName = "BPT" + }, + ValueSet = { - new ElementUsage(Guid.NewGuid(), this.assembler.Cache, this.uri) + new ParameterValueSet { - Owner = this.domain, - ShortName = "TEU", - ElementDefinition = new ElementDefinition(Guid.NewGuid(), this.assembler.Cache, this.uri) - { - Name = "TestElementUsage", - Owner = this.domain, - ShortName = "TEU" - } + Published = new ValueArray(enumerationValues), + Manual = new ValueArray(enumerationValues) } + }, + Scale = new OrdinalScale + { + Iid = Guid.NewGuid(), + ShortName = "m" } - }, + } + } + }; + + this.iteration = new Iteration(Guid.NewGuid(), this.assembler.Cache, this.uri) + { Container = new EngineeringModel(Guid.NewGuid(), this.assembler.Cache, this.uri) { EngineeringModelSetup = new EngineeringModelSetup(Guid.NewGuid(), this.assembler.Cache, this.uri) @@ -230,6 +211,9 @@ public void SetUp() } }; + this.iteration.Element.Add(elementDefinition); + this.iteration.TopElement = this.iteration.Element[0]; + var option1 = new Option(Guid.NewGuid(), this.assembler.Cache, this.uri) { ShortName = "OPT_1", @@ -260,22 +244,22 @@ public void SetUp() this.session.Setup(x => x.Credentials).Returns(new Credentials("admin", "pass", this.uri)); this.session.Setup(x => x.RetrieveSiteDirectory()).Returns(this.siteDirectory); this.session.Setup(x => x.ActivePerson).Returns(this.person); + + this.sessionService.Setup(x => x.GetDomainOfExpertise(this.iteration)).Returns(this.domain); } [TearDown] public void TearDown() { this.context.CleanContext(); + this.viewModel.Dispose(); this.messageBus.ClearSubscriptions(); } [Test] public void VerifyOnInitialized() { - var renderer = this.context.RenderComponent(parameters => - { - parameters.Add(p => p.CurrentThing, this.iteration); - }); + var renderer = this.context.RenderComponent(parameters => { parameters.Add(p => p.CurrentThing, this.iteration); }); var option1 = new Option(Guid.NewGuid(), this.assembler.Cache, this.uri) { @@ -286,24 +270,19 @@ public void VerifyOnInitialized() var optionFilterCombo = renderer.FindComponent(); Assert.That(optionFilterCombo, Is.Not.Null); - - this.viewModel.OptionSelector.SelectedOption = option1; } [Test] public async Task VerifySelectNode() { - this.context.RenderComponent(parameters => - { - parameters.Add(p => p.CurrentThing, this.iteration); - }); + this.context.RenderComponent(parameters => { parameters.Add(p => p.CurrentThing, this.iteration); }); await TaskHelper.WaitWhileAsync(() => this.viewModel.IsLoading); this.viewModel.Elements.Clear(); this.viewModel.Elements.Add(this.iteration.Element[0]); - this.viewModel.SelectElement(new SystemNodeViewModel(this.viewModel.Elements.FirstOrDefault()!.Name)); + this.viewModel.SelectElement(new SystemNodeViewModel(this.viewModel.Elements.FirstOrDefault())); Assert.Multiple(() => { @@ -317,5 +296,50 @@ public async Task VerifySelectNode() Assert.That(this.viewModel.ElementDefinitionDetailsViewModel.Rows.First().SwitchValue, Is.Not.Null); }); } + + [Test] + public void VerifySessionRefresh() + { + this.viewModel.OptionSelector.SelectedOption = this.iteration.DefaultOption; + this.viewModel.CurrentThing = this.iteration; + this.viewModel.ProductTreeViewModel.RootViewModel.SetThing(this.iteration.Element[0]); + + Assert.Multiple(() => + { + Assert.That(this.viewModel.ProductTreeViewModel.RootViewModel.GetChildren(), Has.Count.EqualTo(1)); + Assert.That(this.viewModel.OptionSelector.SelectedOption, Is.EqualTo(this.iteration.DefaultOption)); + }); + + this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); + Assert.That(this.viewModel.ProductTreeViewModel.RootViewModel.GetChildren(), Has.Count.EqualTo(1)); + + var elementUsage = new ElementUsage + { + Iid = Guid.NewGuid(), + Container = this.iteration.TopElement, + ElementDefinition = this.iteration.Element[0] + }; + + this.messageBus.SendObjectChangeEvent(elementUsage, EventKind.Added); + this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); + Assert.That(this.viewModel.ProductTreeViewModel.RootViewModel.GetChildren(), Has.Count.EqualTo(2)); + + elementUsage.Name = "updatedName"; + this.messageBus.SendObjectChangeEvent(elementUsage, EventKind.Updated); + this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); + + Assert.Multiple(() => + { + Assert.That(this.viewModel.ProductTreeViewModel.RootViewModel.GetChildren().ElementAt(1).Title, Is.EqualTo("updatedName")); + Assert.That(this.viewModel.ProductTreeViewModel.RootViewModel.GetChildren(), Has.Count.EqualTo(2)); + }); + + this.messageBus.SendObjectChangeEvent(elementUsage, EventKind.Removed); + this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); + Assert.That(this.viewModel.ProductTreeViewModel.RootViewModel.GetChildren(), Has.Count.EqualTo(1)); + + this.messageBus.SendMessage(new DomainChangedEvent(this.iteration, this.domain)); + Assert.That(this.viewModel.CurrentDomain, Is.EqualTo(this.domain)); + } } } diff --git a/COMETwebapp/Components/SystemRepresentation/SystemRepresentationBody.razor.cs b/COMETwebapp/Components/SystemRepresentation/SystemRepresentationBody.razor.cs index df69c719..daae1fd9 100644 --- a/COMETwebapp/Components/SystemRepresentation/SystemRepresentationBody.razor.cs +++ b/COMETwebapp/Components/SystemRepresentation/SystemRepresentationBody.razor.cs @@ -1,18 +1,18 @@ // -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) 2023-2024 RHEA System S.A. +// +// Copyright (c) 2024 Starion Group S.A. // -// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, Nabil Abbar +// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, João Rua // -// This file is part of CDP4-COMET WEB Community Edition -// The CDP4-COMET WEB Community Edition is the RHEA Web Application implementation of ECSS-E-TM-10-25 Annex A and Annex C. +// This file is part of COMET WEB Community Edition +// The COMET WEB Community Edition is the Starion Group Web Application implementation of ECSS-E-TM-10-25 Annex A and Annex C. // -// The CDP4-COMET WEB Community Edition is free software; you can redistribute it and/or +// The COMET WEB Community Edition is free software; you can redistribute it and/or // modify it under the terms of the GNU Affero General Public // License as published by the Free Software Foundation; either // version 3 of the License, or (at your option) any later version. // -// The CDP4-COMET WEB Community Edition is distributed in the hope that it will be useful, +// The COMET WEB Community Edition is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Affero General Public License for more details. @@ -24,13 +24,13 @@ namespace COMETwebapp.Components.SystemRepresentation { - using Microsoft.AspNetCore.Components; - using COMET.Web.Common.Extensions; using COMET.Web.Common.Utilities; using COMETwebapp.Utilities; + using Microsoft.AspNetCore.Components; + using ReactiveUI; /// @@ -48,6 +48,9 @@ protected override void OnInitialized() this.Disposables.Add(this.WhenAnyValue(x => x.ViewModel.OptionSelector.SelectedOption) .Subscribe(_ => this.UpdateUrl())); + + this.Disposables.Add(this.WhenAnyValue(x => x.ViewModel.IsLoading) + .SubscribeAsync(_ => this.InvokeAsync(this.StateHasChanged))); } /// diff --git a/COMETwebapp/Components/SystemRepresentation/SystemRepresentationTree.razor.cs b/COMETwebapp/Components/SystemRepresentation/SystemRepresentationTree.razor.cs index b0f27e9d..d06a6b77 100644 --- a/COMETwebapp/Components/SystemRepresentation/SystemRepresentationTree.razor.cs +++ b/COMETwebapp/Components/SystemRepresentation/SystemRepresentationTree.razor.cs @@ -1,43 +1,43 @@ // -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) 2023-2024 RHEA System S.A. -// -// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar -// -// This file is part of CDP4-COMET WEB Community Edition -// The CDP4-COMET WEB Community Edition is the RHEA Web Application implementation of ECSS-E-TM-10-25 Annex A and Annex C. -// -// The CDP4-COMET WEB Community Edition is free software; you can redistribute it and/or -// modify it under the terms of the GNU Affero General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// The CDP4-COMET WEB Community Edition is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// +// Copyright (c) 2024 Starion Group S.A. +// +// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, João Rua +// +// This file is part of COMET WEB Community Edition +// The COMET WEB Community Edition is the Starion Group Web Application implementation of ECSS-E-TM-10-25 Annex A and Annex C. +// +// The COMET WEB Community Edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU Affero General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// The COMET WEB Community Edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Affero General Public License for more details. -// +// // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -// -// -------------------------------------------------------------------------------------------------------------------- +// +// -------------------------------------------------------------------------------------------------------------------- namespace COMETwebapp.Components.SystemRepresentation -{ +{ + using COMETwebapp.ViewModels.Components.Shared; + using COMETwebapp.ViewModels.Components.SystemRepresentation; + using Microsoft.AspNetCore.Components; using ReactiveUI; - using COMETwebapp.ViewModels.Components.Shared; - using COMETwebapp.ViewModels.Components.SystemRepresentation; - /// - /// Partial class that represents the + /// Partial class that represents the /// public partial class SystemRepresentationTree { - /// - /// Gets or sets the + /// + /// Gets or sets the /// [Parameter] public SystemRepresentationTreeViewModel ViewModel { get; set; } @@ -50,9 +50,10 @@ protected override void OnInitialized() { base.OnInitialized(); - this.Disposables.Add(this.WhenAnyValue(x => x.ViewModel.RootViewModel, - x => x.ViewModel.SelectedFilter, - x => x.ViewModel.SearchText) + this.Disposables.Add(this.WhenAnyValue( + x => x.ViewModel.RootViewModel, + x => x.ViewModel.SelectedFilter, + x => x.ViewModel.SearchText) .Subscribe(_ => this.InvokeAsync(this.StateHasChanged))); } } diff --git a/COMETwebapp/Components/SystemRepresentation/SystemRepresentationTree.razor.css b/COMETwebapp/Components/SystemRepresentation/SystemRepresentationTree.razor.css index c05ec997..ca40f850 100644 --- a/COMETwebapp/Components/SystemRepresentation/SystemRepresentationTree.razor.css +++ b/COMETwebapp/Components/SystemRepresentation/SystemRepresentationTree.razor.css @@ -8,6 +8,7 @@ margin: 0; padding: 0; height: 100%; + min-width: 15vw; } #product-tree-nodes-section { diff --git a/COMETwebapp/ViewModels/Components/Shared/BaseNodeViewModel.cs b/COMETwebapp/ViewModels/Components/Shared/BaseNodeViewModel.cs index d6a236ca..976a26e6 100644 --- a/COMETwebapp/ViewModels/Components/Shared/BaseNodeViewModel.cs +++ b/COMETwebapp/ViewModels/Components/Shared/BaseNodeViewModel.cs @@ -1,18 +1,18 @@ // -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) 2023-2024 RHEA System S.A. +// +// Copyright (c) 2024 Starion Group S.A. // -// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine +// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, João Rua // -// This file is part of CDP4-COMET WEB Community Edition -// The CDP4-COMET WEB Community Edition is the RHEA Web Application implementation of ECSS-E-TM-10-25 Annex A and Annex C. +// This file is part of COMET WEB Community Edition +// The COMET WEB Community Edition is the Starion Group Web Application implementation of ECSS-E-TM-10-25 Annex A and Annex C. // -// The CDP4-COMET WEB Community Edition is free software; you can redistribute it and/or +// The COMET WEB Community Edition is free software; you can redistribute it and/or // modify it under the terms of the GNU Affero General Public // License as published by the Free Software Foundation; either // version 3 of the License, or (at your option) any later version. // -// The CDP4-COMET WEB Community Edition is distributed in the hope that it will be useful, +// The COMET WEB Community Edition is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Affero General Public License for more details. @@ -24,6 +24,8 @@ namespace COMETwebapp.ViewModels.Components.Shared { + using CDP4Common.CommonData; + using COMET.Web.Common.Utilities.DisposableObject; using DynamicData; @@ -59,11 +61,25 @@ protected BaseNodeViewModel(string title) this.Title = title; } + /// + /// Creates a new instance of type + /// + /// the current thing + protected BaseNodeViewModel(Thing thing) + { + this.SetThing(thing); + } + /// /// Gets or sets the parent of this /// public T Parent { get; set; } + /// + /// Gets or sets the current thing + /// + public Thing Thing { get; private set; } + /// /// Field for containing the children of this /// @@ -287,6 +303,16 @@ public bool IsDescendant(T baseNodeViewModel) return this.GetFlatListOfDescendants().Contains(baseNodeViewModel); } + /// + /// Sets the property value + /// + /// The to be set + public void SetThing(Thing thing) + { + this.Thing = thing; + this.Title = thing.UserFriendlyName; + } + /// /// Callback method for when a node is selected /// diff --git a/COMETwebapp/ViewModels/Components/SystemRepresentation/ISystemRepresentationBodyViewModel.cs b/COMETwebapp/ViewModels/Components/SystemRepresentation/ISystemRepresentationBodyViewModel.cs index 748dff95..2ae541b9 100644 --- a/COMETwebapp/ViewModels/Components/SystemRepresentation/ISystemRepresentationBodyViewModel.cs +++ b/COMETwebapp/ViewModels/Components/SystemRepresentation/ISystemRepresentationBodyViewModel.cs @@ -1,18 +1,18 @@ // -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) 2023-2024 RHEA System S.A. +// +// Copyright (c) 2024 Starion Group S.A. // -// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, Nabil Abbar +// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, João Rua // -// This file is part of CDP4-COMET WEB Community Edition -// The CDP4-COMET WEB Community Edition is the RHEA Web Application implementation of ECSS-E-TM-10-25 Annex A and Annex C. +// This file is part of COMET WEB Community Edition +// The COMET WEB Community Edition is the Starion Group Web Application implementation of ECSS-E-TM-10-25 Annex A and Annex C. // -// The CDP4-COMET WEB Community Edition is free software; you can redistribute it and/or +// The COMET WEB Community Edition is free software; you can redistribute it and/or // modify it under the terms of the GNU Affero General Public // License as published by the Free Software Foundation; either // version 3 of the License, or (at your option) any later version. // -// The CDP4-COMET WEB Community Edition is distributed in the hope that it will be useful, +// The COMET WEB Community Edition is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Affero General Public License for more details. @@ -32,7 +32,7 @@ namespace COMETwebapp.ViewModels.Components.SystemRepresentation /// /// View Model that handle the logic for the System Representation application /// - public interface ISystemRepresentationBodyViewModel: ISingleIterationApplicationBaseViewModel + public interface ISystemRepresentationBodyViewModel : ISingleIterationApplicationBaseViewModel { /// /// Gets the @@ -69,7 +69,6 @@ public interface ISystemRepresentationBodyViewModel: ISingleIterationApplication /// /// Apply all the filters on the /// - /// A - Task ApplyFilters(); + void ApplyFilters(); } } diff --git a/COMETwebapp/ViewModels/Components/SystemRepresentation/SystemNodeViewModel.cs b/COMETwebapp/ViewModels/Components/SystemRepresentation/SystemNodeViewModel.cs index bccfbf0b..5618eda6 100644 --- a/COMETwebapp/ViewModels/Components/SystemRepresentation/SystemNodeViewModel.cs +++ b/COMETwebapp/ViewModels/Components/SystemRepresentation/SystemNodeViewModel.cs @@ -1,18 +1,18 @@ // -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) 2023-2024 RHEA System S.A. +// +// Copyright (c) 2024 Starion Group S.A. // -// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine +// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, João Rua // -// This file is part of CDP4-COMET WEB Community Edition -// The CDP4-COMET WEB Community Edition is the RHEA Web Application implementation of ECSS-E-TM-10-25 Annex A and Annex C. +// This file is part of COMET WEB Community Edition +// The COMET WEB Community Edition is the Starion Group Web Application implementation of ECSS-E-TM-10-25 Annex A and Annex C. // -// The CDP4-COMET WEB Community Edition is free software; you can redistribute it and/or +// The COMET WEB Community Edition is free software; you can redistribute it and/or // modify it under the terms of the GNU Affero General Public // License as published by the Free Software Foundation; either // version 3 of the License, or (at your option) any later version. // -// The CDP4-COMET WEB Community Edition is distributed in the hope that it will be useful, +// The COMET WEB Community Edition is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Affero General Public License for more details. @@ -24,7 +24,10 @@ namespace COMETwebapp.ViewModels.Components.SystemRepresentation { + using CDP4Common.EngineeringModelData; + using COMETwebapp.ViewModels.Components.Shared; + using Microsoft.AspNetCore.Components; /// @@ -33,17 +36,17 @@ namespace COMETwebapp.ViewModels.Components.SystemRepresentation public class SystemNodeViewModel : BaseNodeViewModel { /// - /// The to call on baseNode selection + /// Creates a new instance of type /// - public EventCallback OnSelect { get; set; } + /// the system node view model + public SystemNodeViewModel(ElementBase elementBase) : base(elementBase) + { + } /// - /// Creates a new instance of type + /// The to call on baseNode selection /// - /// the title of the view model - public SystemNodeViewModel(string title) : base(title) - { - } + public EventCallback OnSelect { get; set; } /// /// Callback method for when a node is selected diff --git a/COMETwebapp/ViewModels/Components/SystemRepresentation/SystemRepresentationBodyViewModel.cs b/COMETwebapp/ViewModels/Components/SystemRepresentation/SystemRepresentationBodyViewModel.cs index 15800d6f..41d8fd97 100644 --- a/COMETwebapp/ViewModels/Components/SystemRepresentation/SystemRepresentationBodyViewModel.cs +++ b/COMETwebapp/ViewModels/Components/SystemRepresentation/SystemRepresentationBodyViewModel.cs @@ -1,18 +1,18 @@ // -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) 2023-2024 RHEA System S.A. +// +// Copyright (c) 2024 Starion Group S.A. // -// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, Nabil Abbar +// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, João Rua // -// This file is part of CDP4-COMET WEB Community Edition -// The CDP4-COMET WEB Community Edition is the RHEA Web Application implementation of ECSS-E-TM-10-25 Annex A and Annex C. +// This file is part of COMET WEB Community Edition +// The COMET WEB Community Edition is the Starion Group Web Application implementation of ECSS-E-TM-10-25 Annex A and Annex C. // -// The CDP4-COMET WEB Community Edition is free software; you can redistribute it and/or +// The COMET WEB Community Edition is free software; you can redistribute it and/or // modify it under the terms of the GNU Affero General Public // License as published by the Free Software Foundation; either // version 3 of the License, or (at your option) any later version. // -// The CDP4-COMET WEB Community Edition is distributed in the hope that it will be useful, +// The COMET WEB Community Edition is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Affero General Public License for more details. @@ -29,13 +29,14 @@ namespace COMETwebapp.ViewModels.Components.SystemRepresentation using CDP4Dal; - using COMET.Web.Common.Extensions; using COMET.Web.Common.Services.SessionManagement; using COMET.Web.Common.ViewModels.Components.Applications; using COMET.Web.Common.ViewModels.Components.Selectors; using COMETwebapp.ViewModels.Components.SystemRepresentation.Rows; + using DynamicData; + using Microsoft.AspNetCore.Components; using ReactiveUI; @@ -57,7 +58,8 @@ public SystemRepresentationBodyViewModel(ISessionService sessionService, ICDPMes OnClick = new EventCallbackFactory().Create(this, this.SelectElement) }; - this.Disposables.Add(this.WhenAnyValue(x => x.OptionSelector.SelectedOption).SubscribeAsync(_ => this.ApplyFilters())); + this.Disposables.Add(this.WhenAnyValue(x => x.OptionSelector.SelectedOption).Subscribe(_ => this.ApplyFilters())); + this.InitializeSubscriptions([typeof(ElementUsage)]); } /// @@ -92,8 +94,7 @@ public SystemRepresentationBodyViewModel(ISessionService sessionService, ICDPMes /// A public void SelectElement(SystemNodeViewModel selectedNode) { - // It is preferable to have a selection based on the Iid of the Thing - this.ElementDefinitionDetailsViewModel.SelectedSystemNode = this.Elements.Find(e => e.Name.Equals(selectedNode.Title)); + this.ElementDefinitionDetailsViewModel.SelectedSystemNode = this.Elements.Find(e => e.Iid == selectedNode.Thing.Iid); this.ElementDefinitionDetailsViewModel.Rows = this.ElementDefinitionDetailsViewModel.SelectedSystemNode switch { @@ -106,18 +107,16 @@ public void SelectElement(SystemNodeViewModel selectedNode) /// /// Apply all the filters on the /// - /// A - public async Task ApplyFilters() + public void ApplyFilters() { - if (this.CurrentThing != null) + if (this.CurrentThing == null) { - this.IsLoading = true; - await Task.Delay(1); - - this.OnOptionFilterChange(this.OptionSelector.SelectedOption); - - this.IsLoading = false; + return; } + + this.IsLoading = true; + this.OnOptionFilterChange(this.OptionSelector.SelectedOption); + this.IsLoading = false; } /// @@ -154,11 +153,12 @@ public void OnOptionFilterChange(Option selectedOption) /// A protected override async Task OnThingChanged() { - this.Elements.Clear(); await base.OnThingChanged(); + + this.Elements.Clear(); this.OptionSelector.CurrentIteration = this.CurrentThing; this.InitializeElements(); - await this.ApplyFilters(); + this.ApplyFilters(); this.IsLoading = false; } @@ -173,10 +173,7 @@ protected override async Task OnDomainChanged() if (this.CurrentDomain != null) { this.IsLoading = true; - await Task.Delay(1); - - await this.ApplyFilters(); - + this.ApplyFilters(); this.IsLoading = false; } } @@ -187,7 +184,30 @@ protected override async Task OnDomainChanged() /// A protected override Task OnSessionRefreshed() { - return this.OnThingChanged(); + if (this.AddedThings.Count == 0 && this.UpdatedThings.Count == 0 && this.DeletedThings.Count == 0) + { + return Task.CompletedTask; + } + + this.IsLoading = true; + + var addedElements = this.AddedThings.OfType().ToList(); + var deletedElements = this.DeletedThings.OfType().ToList(); + var updatedElements = this.UpdatedThings.OfType().ToList(); + + this.Elements.AddRange(addedElements); + this.Elements.RemoveMany(deletedElements); + + this.ProductTreeViewModel.AddElementsToTree(addedElements, this.OptionSelector.SelectedOption, []); + this.ProductTreeViewModel.RemoveElementsFromTree(deletedElements); + this.ProductTreeViewModel.UpdateElementsFromTree(updatedElements); + + this.ProductTreeViewModel.RootViewModel.OrderAllDescendantsByShortName(); + + this.ClearRecordedChanges(); + this.IsLoading = false; + + return Task.CompletedTask; } /// diff --git a/COMETwebapp/ViewModels/Components/SystemRepresentation/SystemRepresentationTreeViewModel.cs b/COMETwebapp/ViewModels/Components/SystemRepresentation/SystemRepresentationTreeViewModel.cs index b9ff25f0..46e563fe 100644 --- a/COMETwebapp/ViewModels/Components/SystemRepresentation/SystemRepresentationTreeViewModel.cs +++ b/COMETwebapp/ViewModels/Components/SystemRepresentation/SystemRepresentationTreeViewModel.cs @@ -1,18 +1,18 @@ // -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) 2023-2024 RHEA System S.A. +// +// Copyright (c) 2024 Starion Group S.A. // -// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine +// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, João Rua // -// This file is part of CDP4-COMET WEB Community Edition -// The CDP4-COMET WEB Community Edition is the RHEA Web Application implementation of ECSS-E-TM-10-25 Annex A and Annex C. +// This file is part of COMET WEB Community Edition +// The COMET WEB Community Edition is the Starion Group Web Application implementation of ECSS-E-TM-10-25 Annex A and Annex C. // -// The CDP4-COMET WEB Community Edition is free software; you can redistribute it and/or +// The COMET WEB Community Edition is free software; you can redistribute it and/or // modify it under the terms of the GNU Affero General Public // License as published by the Free Software Foundation; either // version 3 of the License, or (at your option) any later version. // -// The CDP4-COMET WEB Community Edition is distributed in the hope that it will be useful, +// The COMET WEB Community Edition is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Affero General Public License for more details. @@ -39,11 +39,6 @@ namespace COMETwebapp.ViewModels.Components.SystemRepresentation /// public class SystemRepresentationTreeViewModel : ProductTreeViewModel { - /// - /// The to call on baseNode selection - /// - public EventCallback OnClick { get; set; } - /// /// Creates a new instance of type /// @@ -57,6 +52,11 @@ public SystemRepresentationTreeViewModel() this.Disposables.Add(this.WhenAnyValue(x => x.SelectedFilter).Subscribe(_ => this.OnFilterChanged())); } + /// + /// The to call on baseNode selection + /// + public EventCallback OnClick { get; set; } + /// /// Creates the product tree /// @@ -68,21 +68,84 @@ public override SystemNodeViewModel CreateTree(IEnumerable productT { var treeElements = productTreeElements.ToList(); - if (treeElements.Any() && selectedOption != null && selectedActualFiniteStates != null) + if (treeElements.Count == 0 || selectedOption == null || selectedActualFiniteStates == null) + { + return null; + } + + var topElement = treeElements.First(); + + this.RootViewModel = new SystemNodeViewModel(topElement) + { + OnSelect = new EventCallbackFactory().Create(this, this.SelectElement) + }; + + this.CreateTreeRecursively(topElement, this.RootViewModel, null, selectedOption, selectedActualFiniteStates); + this.RootViewModel.OrderAllDescendantsByShortName(); + return this.RootViewModel; + } + + /// + /// Adds a sequence of elements to the tree + /// + /// A collection of element bases + /// The selected option + /// The selected finite state + public void AddElementsToTree(IEnumerable elementBases, Option option, List finiteState) + { + var nodes = this.RootViewModel.GetFlatListOfDescendants(true); + + foreach (var elementBase in elementBases) { - var topElement = treeElements.First(); + var parentNode = nodes.FirstOrDefault(x => x.Thing.Iid == elementBase.Container.Iid); - this.RootViewModel = new SystemNodeViewModel(topElement.Name) + var nodeToAdd = new SystemNodeViewModel(elementBase) { OnSelect = new EventCallbackFactory().Create(this, this.SelectElement) }; - this.CreateTreeRecursively(topElement, this.RootViewModel, null, selectedOption, selectedActualFiniteStates); - this.RootViewModel.OrderAllDescendantsByShortName(); - return this.RootViewModel; + this.CreateTreeRecursively(elementBase, nodeToAdd, parentNode, option, finiteState); } + } - return null; + /// + /// Removes a collection of elements from the tree + /// + /// A collection of element bases + public void RemoveElementsFromTree(IEnumerable elementBases) + { + var nodes = this.RootViewModel.GetFlatListOfDescendants(true); + + foreach (var elementBase in elementBases) + { + var nodeToRemove = nodes.First(x => x.Thing.Iid == elementBase.Iid); + nodeToRemove.Parent.RemoveChild(nodeToRemove); + } + } + + /// + /// Updates a collection of elements from the tree + /// + /// A collection of element bases + public void UpdateElementsFromTree(IEnumerable elementBases) + { + var nodes = this.RootViewModel.GetFlatListOfDescendants(true); + + foreach (var elementBase in elementBases) + { + var nodeToUpdate = nodes.First(x => x.Thing.Iid == elementBase.Iid); + nodeToUpdate.SetThing(elementBase); + } + } + + /// + /// set the selected + /// + /// The selected + /// A + public void SelectElement(SystemNodeViewModel selectedNode) + { + this.OnClick.InvokeAsync(selectedNode); } /// @@ -92,7 +155,7 @@ public override SystemNodeViewModel CreateTree(IEnumerable productT /// the current baseNode /// the parent of the current baseNode. Null if the current baseNode is the root baseNode /// the selected - /// the selected + /// the selected protected override void CreateTreeRecursively(ElementBase elementBase, SystemNodeViewModel current, SystemNodeViewModel parent, Option selectedOption, IEnumerable selectedActualFiniteStates) { var childsOfElementBase = elementBase.QueryElementUsageChildrenFromElementBase(); @@ -101,7 +164,7 @@ protected override void CreateTreeRecursively(ElementBase elementBase, SystemNod foreach (var child in childsOfElementBase) { - var nodeViewModel = new SystemNodeViewModel(child.Name) + var nodeViewModel = new SystemNodeViewModel(child) { OnSelect = new EventCallbackFactory().Create(this, this.SelectElement) }; @@ -109,15 +172,5 @@ protected override void CreateTreeRecursively(ElementBase elementBase, SystemNod this.CreateTreeRecursively(child, nodeViewModel, current, selectedOption, selectedActualFiniteStates); } } - - /// - /// set the selected - /// - /// The selected - /// A - public void SelectElement(SystemNodeViewModel selectedNode) - { - this.OnClick.InvokeAsync(selectedNode); - } } }