From dac2b88e3de5a389538284def9bce2834058b34e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Rua?= <140734849+joao4all@users.noreply.github.com> Date: Mon, 3 Jun 2024 10:52:28 +0100 Subject: [PATCH] Feat #612 [Server Administration] Refactor Models page to be inline with Measurement Scale page (#652) --- .../ActiveDomainsTableTestFixture.cs | 100 ++++----- .../EngineeringModelsTableTestFixture.cs | 110 +++++----- .../IterationsTableTestFixture.cs | 60 +++--- ...anizationalParticipantsTableTestFixture.cs | 109 +++++----- .../ParticipantsTableTestFixture.cs | 4 +- .../ActiveDomainsTableViewModelTestFixture.cs | 194 ------------------ ...ineeringModelsTableViewModelTestFixture.cs | 149 +++++++------- .../IterationsTableViewModelTestFixture.cs | 173 ---------------- ...alParticipantsTableViewModelTestFixture.cs | 58 +----- .../ParticipantsTableViewModelTestFixture.cs | 7 +- .../Components/Common/FormButtons.razor | 9 + .../Components/Common/FormButtons.razor.cs | 14 +- .../Common/SelectedDataItemBase.razor.cs | 21 ++ .../SelectedDeprecatableDataItemBase.razor.cs | 21 -- .../EngineeringModel/ActiveDomainsTable.razor | 100 ++++----- .../ActiveDomainsTable.razor.cs | 78 +++---- .../EngineeringModelsForm.razor | 88 ++++++++ .../EngineeringModelsForm.razor.cs | 61 ++++++ .../EngineeringModelsTable.razor | 152 +------------- .../EngineeringModelsTable.razor.cs | 80 ++------ .../EngineeringModel/IterationsTable.razor | 24 +-- .../EngineeringModel/IterationsTable.razor.cs | 59 +++--- .../OrganizationalParticipantsTable.razor | 123 ++++++----- .../OrganizationalParticipantsTable.razor.cs | 82 +++----- .../EngineeringModel/ParticipantsTable.razor | 8 +- .../ParticipantsTable.razor.cs | 77 +++---- .../Extensions/ServiceCollectionExtensions.cs | 2 - .../BaseDataItemTableViewModel.cs | 2 +- .../DeletableDataItemTableViewModel.cs | 15 +- .../IDeletableDataItemTableViewModel.cs | 2 +- .../ActiveDomainsTableViewModel.cs | 131 ------------ .../EngineeringModelsTableViewModel.cs | 189 +++++++++++------ .../IActiveDomainsTableViewModel.cs | 64 ------ .../IEngineeringModelsTableViewModel.cs | 25 +-- .../IIterationsTableViewModel.cs | 44 ---- ...rganizationalParticipantsTableViewModel.cs | 5 + .../IterationsTableViewModel.cs | 77 ------- ...rganizationalParticipantsTableViewModel.cs | 103 +++++++--- .../ParticipantsTableViewModel.cs | 134 +++++++----- 39 files changed, 1015 insertions(+), 1739 deletions(-) delete mode 100644 COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/ActiveDomainsTableViewModelTestFixture.cs delete mode 100644 COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/IterationsTableViewModelTestFixture.cs create mode 100644 COMETwebapp/Components/SiteDirectory/EngineeringModel/EngineeringModelsForm.razor create mode 100644 COMETwebapp/Components/SiteDirectory/EngineeringModel/EngineeringModelsForm.razor.cs delete mode 100644 COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/ActiveDomainsTableViewModel.cs delete mode 100644 COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/IActiveDomainsTableViewModel.cs delete mode 100644 COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/IIterationsTableViewModel.cs delete mode 100644 COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/IterationsTableViewModel.cs diff --git a/COMETwebapp.Tests/Components/SiteDirectory/EngineeringModels/ActiveDomainsTableTestFixture.cs b/COMETwebapp.Tests/Components/SiteDirectory/EngineeringModels/ActiveDomainsTableTestFixture.cs index 3f6e1991..a8f29807 100644 --- a/COMETwebapp.Tests/Components/SiteDirectory/EngineeringModels/ActiveDomainsTableTestFixture.cs +++ b/COMETwebapp.Tests/Components/SiteDirectory/EngineeringModels/ActiveDomainsTableTestFixture.cs @@ -1,32 +1,29 @@ // -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) 2023-2024 Starion Group S.A. -// -// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Antoine Théate, João Rua -// -// This file is part of CDP4-COMET WEB Community Edition -// The CDP4-COMET WEB Community Edition is the Starion 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.SiteDirectory.EngineeringModels { - using System.Linq; - using System.Threading.Tasks; - using Bunit; using CDP4Common.SiteDirectoryData; @@ -34,17 +31,9 @@ namespace COMETwebapp.Tests.Components.SiteDirectory.EngineeringModels using COMET.Web.Common.Test.Helpers; using COMETwebapp.Components.SiteDirectory.EngineeringModel; - using COMETwebapp.ViewModels.Components.SiteDirectory.EngineeringModels; - using COMETwebapp.ViewModels.Components.SiteDirectory.Rows; using DevExpress.Blazor; - using DynamicData; - - using Microsoft.Extensions.DependencyInjection; - - using Moq; - using NUnit.Framework; using TestContext = Bunit.TestContext; @@ -54,7 +43,6 @@ public class ActiveDomainsTableTestFixture { private TestContext context; private IRenderedComponent renderer; - private Mock viewModel; private EngineeringModelSetup model; private DomainOfExpertise domain1; private DomainOfExpertise domain2; @@ -63,37 +51,26 @@ public class ActiveDomainsTableTestFixture public void SetUp() { this.context = new TestContext(); - this.viewModel = new Mock(); this.model = new EngineeringModelSetup(); - this.domain1 = new DomainOfExpertise() + this.domain1 = new DomainOfExpertise { Name = "domain A", ShortName = "domainA", - Container = new EngineeringModelSetup(){ ShortName = "model" }, + Container = new EngineeringModelSetup { ShortName = "model" } }; - this.domain2 = new DomainOfExpertise() + this.domain2 = new DomainOfExpertise { Name = "domain B", ShortName = "domainB", - Container = new EngineeringModelSetup() { ShortName = "model" }, + Container = new EngineeringModelSetup { ShortName = "model" } }; - var rows = new SourceList(); - rows.Add(new DomainOfExpertiseRowViewModel(this.domain1)); - rows.Add(new DomainOfExpertiseRowViewModel(this.domain2)); - - this.viewModel.Setup(x => x.Rows).Returns(rows); - this.viewModel.Setup(x => x.CurrentThing).Returns(new DomainOfExpertise()); - - this.context.Services.AddSingleton(this.viewModel.Object); + this.model.ActiveDomain = [this.domain1, this.domain2]; this.context.ConfigureDevExpressBlazor(); - this.renderer = this.context.RenderComponent(p => - { - p.Add(parameter => parameter.EngineeringModelSetup, this.model); - }); + this.renderer = this.context.RenderComponent(p => { p.Add(parameter => parameter.EngineeringModelSetup, this.model); }); } [TearDown] @@ -103,20 +80,6 @@ public void Teardown() this.context.Dispose(); } - [Test] - public void VerifyOnInitialized() - { - Assert.Multiple(() => - { - Assert.That(this.renderer.Instance.ShouldCreateThing, Is.EqualTo(false)); - Assert.That(this.renderer.Instance.ViewModel, Is.Not.Null); - Assert.That(this.renderer.Instance.EngineeringModelSetup, Is.EqualTo(this.model)); - Assert.That(this.renderer.Markup, Does.Contain(this.domain1.Name)); - Assert.That(this.renderer.Markup, Does.Contain(this.domain2.Name)); - this.viewModel.Verify(x => x.InitializeViewModel(It.IsAny()), Times.Once); - }); - } - [Test] public async Task VerifyEditActiveDomains() { @@ -129,7 +92,6 @@ public async Task VerifyEditActiveDomains() var saveActiveDomainsButton = this.renderer.FindComponents().First(x => x.Instance.Id == "saveActiveDomainsButton"); await this.renderer.InvokeAsync(saveActiveDomainsButton.Instance.Click.InvokeAsync); - this.viewModel.Verify(x => x.EditActiveDomains(), Times.Once); // Opens the popup again await this.renderer.InvokeAsync(editActiveDomainsClickableItem.Instance.Click.InvokeAsync); @@ -137,10 +99,18 @@ public async Task VerifyEditActiveDomains() var cancelActiveDomainsButton = this.renderer.FindComponents().First(x => x.Instance.Id == "cancelActiveDomainsButton"); await this.renderer.InvokeAsync(cancelActiveDomainsButton.Instance.Click.InvokeAsync); + Assert.That(this.renderer.Instance.IsOnEditMode, Is.EqualTo(false)); + } + + [Test] + public void VerifyOnInitialized() + { Assert.Multiple(() => { - this.viewModel.Verify(x => x.ResetSelectedDomainsOfExpertise(), Times.Once); - Assert.That(this.renderer.Instance.IsOnEditMode, Is.EqualTo(false)); + Assert.That(this.renderer.Instance.ShouldCreateThing, Is.EqualTo(false)); + Assert.That(this.renderer.Instance.EngineeringModelSetup, Is.EqualTo(this.model)); + Assert.That(this.renderer.Markup, Does.Contain(this.domain1.Name)); + Assert.That(this.renderer.Markup, Does.Contain(this.domain2.Name)); }); } } diff --git a/COMETwebapp.Tests/Components/SiteDirectory/EngineeringModels/EngineeringModelsTableTestFixture.cs b/COMETwebapp.Tests/Components/SiteDirectory/EngineeringModels/EngineeringModelsTableTestFixture.cs index 6ff18a22..a9d9fb0d 100644 --- a/COMETwebapp.Tests/Components/SiteDirectory/EngineeringModels/EngineeringModelsTableTestFixture.cs +++ b/COMETwebapp.Tests/Components/SiteDirectory/EngineeringModels/EngineeringModelsTableTestFixture.cs @@ -1,32 +1,29 @@ // -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) 2023-2024 Starion Group S.A. -// -// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Antoine Théate, João Rua -// -// This file is part of CDP4-COMET WEB Community Edition -// The CDP4-COMET WEB Community Edition is the Starion 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.SiteDirectory.EngineeringModels { - using System.Linq; - using System.Threading.Tasks; - using Bunit; using CDP4Common.SiteDirectoryData; @@ -41,6 +38,7 @@ namespace COMETwebapp.Tests.Components.SiteDirectory.EngineeringModels using DynamicData; + using Microsoft.AspNetCore.Components.Forms; using Microsoft.Extensions.DependencyInjection; using Moq; @@ -65,18 +63,18 @@ public void SetUp() this.viewModel = new Mock(); - this.engineeringModel1 = new EngineeringModelSetup() + this.engineeringModel1 = new EngineeringModelSetup { Name = "A name", ShortName = "AName", - Container = new SiteDirectory(){ ShortName = "siteDir" }, + Container = new SiteDirectory { ShortName = "siteDir" } }; - this.engineeringModel2 = new EngineeringModelSetup() + this.engineeringModel2 = new EngineeringModelSetup { Name = "B name", ShortName = "BName", - Container = new SiteDirectory() { ShortName = "siteDir" }, + Container = new SiteDirectory { ShortName = "siteDir" } }; var rows = new SourceList(); @@ -100,42 +98,58 @@ public void Teardown() } [Test] - public void VerifyOnInitialized() + public async Task VerifyAddOrEditEngineeringModel() { + var addEngineeringModelButton = this.renderer.FindComponents().First(x => x.Instance.Id == "dataItemDetailsButton"); + await this.renderer.InvokeAsync(addEngineeringModelButton.Instance.Click.InvokeAsync); + Assert.Multiple(() => { - Assert.That(this.renderer.Instance.ShouldCreateThing, Is.EqualTo(false)); - Assert.That(this.renderer.Instance.ViewModel, Is.Not.Null); - Assert.That(this.renderer.Markup, Does.Contain(this.engineeringModel1.Name)); - Assert.That(this.renderer.Markup, Does.Contain(this.engineeringModel2.Name)); - this.viewModel.Verify(x => x.InitializeViewModel(), Times.Once); + Assert.That(this.renderer.Instance.ShouldCreateThing, Is.EqualTo(true)); + Assert.That(this.viewModel.Object.CurrentThing, Is.InstanceOf(typeof(EngineeringModelSetup))); + }); + + var engineeringModelsGrid = this.renderer.FindComponent(); + await this.renderer.InvokeAsync(() => engineeringModelsGrid.Instance.SelectedDataItemChanged.InvokeAsync(new EngineeringModelRowViewModel(this.engineeringModel1))); + Assert.That(this.renderer.Instance.IsOnEditMode, Is.EqualTo(true)); + + var engineeringModelsForm = this.renderer.FindComponent(); + var engineeringModelsEditForm = engineeringModelsForm.FindComponent(); + await engineeringModelsForm.InvokeAsync(engineeringModelsEditForm.Instance.OnValidSubmit.InvokeAsync); + + Assert.Multiple(() => + { + this.viewModel.Verify(x => x.CreateOrEditEngineeringModel(false), Times.Once); + Assert.That(this.viewModel.Object.CurrentThing, Is.InstanceOf(typeof(EngineeringModelSetup))); }); + + var form = this.renderer.FindComponent(); + await this.renderer.InvokeAsync(form.Instance.EditModelSaving.InvokeAsync); + this.viewModel.Verify(x => x.CreateOrEditEngineeringModel(false), Times.Once); } [Test] public async Task VerifyDeleteEngineeringModel() { - var deleteButton = this.renderer.FindComponents().First(x => x.Instance.Id == "deleteEngineeringModelButton"); + var engineeringModelsGrid = this.renderer.FindComponent(); + await this.renderer.InvokeAsync(() => engineeringModelsGrid.Instance.SelectedDataItemChanged.InvokeAsync(new EngineeringModelRowViewModel(this.engineeringModel1))); + + var deleteButton = this.renderer.FindComponents().First(x => x.Instance.Id == "deleteItemButton"); await this.renderer.InvokeAsync(deleteButton.Instance.Click.InvokeAsync); - this.viewModel.Verify(x => x.OnDeleteButtonClick(It.IsAny()), Times.Once); + this.viewModel.VerifySet(x => x.IsOnDeletionMode = true, Times.Once); } [Test] - public async Task VerifyAddEngineeringModel() + public void VerifyOnInitialized() { - var addEngineeringModelButton = this.renderer.FindComponents().First(x => x.Instance.Id == "addEngineeringModelButton"); - await this.renderer.InvokeAsync(addEngineeringModelButton.Instance.Click.InvokeAsync); - var grid = this.renderer.FindComponent(); - Assert.That(grid.Instance.IsEditing(), Is.EqualTo(true)); - - var cancelEngineeringModelButton = this.renderer.FindComponents().First(x => x.Instance.Id == "cancelEngineeringModelButton"); - await this.renderer.InvokeAsync(cancelEngineeringModelButton.Instance.Click.InvokeAsync); - Assert.That(grid.Instance.IsEditing(), Is.EqualTo(false)); - - await this.renderer.InvokeAsync(addEngineeringModelButton.Instance.Click.InvokeAsync); - var saveEngineeringModelButton = this.renderer.FindComponents().First(x => x.Instance.Id == "saveEngineeringModelButton"); - await this.renderer.InvokeAsync(saveEngineeringModelButton.Instance.Click.InvokeAsync); - this.viewModel.Verify(x => x.CreateEngineeringModel(), Times.Once); + Assert.Multiple(() => + { + Assert.That(this.renderer.Instance.ShouldCreateThing, Is.EqualTo(false)); + Assert.That(this.renderer.Instance.ViewModel, Is.Not.Null); + Assert.That(this.renderer.Markup, Does.Contain(this.engineeringModel1.Name)); + Assert.That(this.renderer.Markup, Does.Contain(this.engineeringModel2.Name)); + this.viewModel.Verify(x => x.InitializeViewModel(), Times.Once); + }); } [Test] diff --git a/COMETwebapp.Tests/Components/SiteDirectory/EngineeringModels/IterationsTableTestFixture.cs b/COMETwebapp.Tests/Components/SiteDirectory/EngineeringModels/IterationsTableTestFixture.cs index c1d263b9..f732b1b3 100644 --- a/COMETwebapp.Tests/Components/SiteDirectory/EngineeringModels/IterationsTableTestFixture.cs +++ b/COMETwebapp.Tests/Components/SiteDirectory/EngineeringModels/IterationsTableTestFixture.cs @@ -1,26 +1,26 @@ // -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) 2023-2024 Starion Group S.A. -// -// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Antoine Théate, João Rua -// -// This file is part of CDP4-COMET WEB Community Edition -// The CDP4-COMET WEB Community Edition is the Starion 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.SiteDirectory.EngineeringModels { @@ -32,15 +32,10 @@ namespace COMETwebapp.Tests.Components.SiteDirectory.EngineeringModels using COMET.Web.Common.Test.Helpers; using COMETwebapp.Components.SiteDirectory.EngineeringModel; - using COMETwebapp.ViewModels.Components.SiteDirectory.EngineeringModels; using COMETwebapp.ViewModels.Components.SiteDirectory.Rows; using DynamicData; - using Microsoft.Extensions.DependencyInjection; - - using Moq; - using NUnit.Framework; using TestContext = Bunit.TestContext; @@ -50,7 +45,6 @@ public class IterationsTableTestFixture { private TestContext context; private IRenderedComponent renderer; - private Mock viewModel; private EngineeringModelSetup model; private Iteration iteration1; @@ -58,31 +52,27 @@ public class IterationsTableTestFixture public void SetUp() { this.context = new TestContext(); - this.viewModel = new Mock(); - this.model = new EngineeringModelSetup() + this.model = new EngineeringModelSetup { Name = "model", ShortName = "model" }; - this.iteration1 = new Iteration() + this.iteration1 = new Iteration { - IterationSetup = new IterationSetup(){ Container = this.model }, - Container = new EngineeringModel(){ EngineeringModelSetup = this.model }, + IterationSetup = new IterationSetup { Container = this.model }, + Container = new EngineeringModel { EngineeringModelSetup = this.model } }; var rows = new SourceList(); rows.Add(new IterationRowViewModel(this.iteration1)); - - this.viewModel.Setup(x => x.Rows).Returns(rows); - - this.context.Services.AddSingleton(this.viewModel.Object); this.context.ConfigureDevExpressBlazor(); this.renderer = this.context.RenderComponent(p => { p.Add(parameter => parameter.EngineeringModelSetup, this.model); + p.Add(parameter => parameter.IterationRows, rows.Items); }); } @@ -99,10 +89,8 @@ public void VerifyOnInitialized() Assert.Multiple(() => { Assert.That(this.renderer.Instance.ShouldCreateThing, Is.EqualTo(false)); - Assert.That(this.renderer.Instance.ViewModel, Is.Not.Null); Assert.That(this.renderer.Instance.EngineeringModelSetup, Is.EqualTo(this.model)); Assert.That(this.renderer.Markup, Does.Contain(this.model.ShortName)); - this.viewModel.Verify(x => x.InitializeViewModel(It.IsAny()), Times.Once); }); } } diff --git a/COMETwebapp.Tests/Components/SiteDirectory/EngineeringModels/OrganizationalParticipantsTableTestFixture.cs b/COMETwebapp.Tests/Components/SiteDirectory/EngineeringModels/OrganizationalParticipantsTableTestFixture.cs index 8959df29..4da8920f 100644 --- a/COMETwebapp.Tests/Components/SiteDirectory/EngineeringModels/OrganizationalParticipantsTableTestFixture.cs +++ b/COMETwebapp.Tests/Components/SiteDirectory/EngineeringModels/OrganizationalParticipantsTableTestFixture.cs @@ -1,32 +1,29 @@ // -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) 2023-2024 Starion Group S.A. -// -// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Antoine Théate, João Rua -// -// This file is part of CDP4-COMET WEB Community Edition -// The CDP4-COMET WEB Community Edition is the Starion 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.SiteDirectory.EngineeringModels { - using System.Linq; - using System.Threading.Tasks; - using Bunit; using CDP4Common.SiteDirectoryData; @@ -57,49 +54,51 @@ public class OrganizationalParticipantsTableTestFixture private Mock viewModel; private EngineeringModelSetup model; private OrganizationalParticipant organizationalParticipant1; - private OrganizationalParticipant organizationParticipant2; + private OrganizationalParticipant organizationalParticipant2; [SetUp] public void SetUp() { this.context = new TestContext(); this.viewModel = new Mock(); - this.model = new EngineeringModelSetup(); - this.organizationalParticipant1 = new OrganizationalParticipant() + this.model = new EngineeringModelSetup + { + ShortName = "model" + }; + + this.organizationalParticipant1 = new OrganizationalParticipant { - Organization = new Organization() + Organization = new Organization { Name = "org A", ShortName = "orgA" - }, - Container = new EngineeringModelSetup(){ ShortName = "model" }, + } }; - this.organizationParticipant2 = new OrganizationalParticipant() + this.organizationalParticipant2 = new OrganizationalParticipant { - Organization = new Organization() + Organization = new Organization { Name = "org B", ShortName = "orgB" - }, - Container = new EngineeringModelSetup() { ShortName = "model" }, + } }; + this.model.OrganizationalParticipant.AddRange([this.organizationalParticipant1, this.organizationalParticipant2]); + var rows = new SourceList(); rows.Add(new OrganizationalParticipantRowViewModel(this.organizationalParticipant1)); - rows.Add(new OrganizationalParticipantRowViewModel(this.organizationParticipant2)); + rows.Add(new OrganizationalParticipantRowViewModel(this.organizationalParticipant2)); this.viewModel.Setup(x => x.Rows).Returns(rows); this.viewModel.Setup(x => x.CurrentThing).Returns(new OrganizationalParticipant()); + this.viewModel.Setup(x => x.CurrentModel).Returns(this.model); this.context.Services.AddSingleton(this.viewModel.Object); this.context.ConfigureDevExpressBlazor(); - this.renderer = this.context.RenderComponent(p => - { - p.Add(parameter => parameter.EngineeringModelSetup, this.model); - }); + this.renderer = this.context.RenderComponent(p => { p.Add(parameter => parameter.ViewModel, this.viewModel.Object); }); } [TearDown] @@ -110,41 +109,31 @@ public void Teardown() } [Test] - public void VerifyOnInitialized() + public async Task VerifyEditingOrganizationalParticipant() { + var editOrganizationalParticipantsClickableItem = this.renderer.FindComponent(); + await this.renderer.InvokeAsync(editOrganizationalParticipantsClickableItem.Instance.Click.InvokeAsync); + Assert.Multiple(() => { - Assert.That(this.renderer.Instance.ShouldCreateThing, Is.EqualTo(false)); - Assert.That(this.renderer.Instance.ViewModel, Is.Not.Null); - Assert.That(this.renderer.Instance.EngineeringModelSetup, Is.EqualTo(this.model)); - Assert.That(this.renderer.Markup, Does.Contain(this.organizationalParticipant1.Organization.Name)); - Assert.That(this.renderer.Markup, Does.Contain(this.organizationParticipant2.Organization.ShortName)); - this.viewModel.Verify(x => x.InitializeViewModel(It.IsAny()), Times.Once); + Assert.That(this.renderer.Instance.IsOnEditMode, Is.EqualTo(true)); + Assert.That(this.viewModel.Object.CurrentThing, Is.InstanceOf(typeof(OrganizationalParticipant))); }); - } - [Test] - public async Task VerifyDeleteOrganizationalParticipant() - { - var deleteOrganizationalParticipantButton = this.renderer.FindComponents().First(x => x.Instance.Id == "deleteOrganizationalParticipantButton"); - await this.renderer.InvokeAsync(deleteOrganizationalParticipantButton.Instance.Click.InvokeAsync); - this.viewModel.Verify(x => x.OnDeleteButtonClick(It.IsAny()), Times.Once); + var form = this.renderer.FindComponent(); + await this.renderer.InvokeAsync(form.Instance.EditModelSaving.InvokeAsync); } [Test] - public async Task VerifyEditingOrganizationalParticipant() + public void VerifyOnInitialized() { - var editOrganizationalParticipantsButton = this.renderer.FindComponents().First(x => x.Instance.Id == "editOrganizationalParticipantsButton"); - await this.renderer.InvokeAsync(editOrganizationalParticipantsButton.Instance.Click.InvokeAsync); - Assert.Multiple(() => { - Assert.That(this.renderer.Instance.ShouldCreateThing, Is.EqualTo(true)); - Assert.That(this.viewModel.Object.CurrentThing, Is.InstanceOf(typeof(OrganizationalParticipant))); + Assert.That(this.renderer.Instance.ShouldCreateThing, Is.EqualTo(false)); + Assert.That(this.renderer.Instance.ViewModel, Is.Not.Null); + Assert.That(this.renderer.Markup, Does.Contain(this.organizationalParticipant1.Organization.Name)); + Assert.That(this.renderer.Markup, Does.Contain(this.organizationalParticipant2.Organization.ShortName)); }); - - var form = this.renderer.FindComponent(); - await this.renderer.InvokeAsync(form.Instance.EditModelSaving.InvokeAsync); } } } diff --git a/COMETwebapp.Tests/Components/SiteDirectory/EngineeringModels/ParticipantsTableTestFixture.cs b/COMETwebapp.Tests/Components/SiteDirectory/EngineeringModels/ParticipantsTableTestFixture.cs index 97b9f60e..a2339203 100644 --- a/COMETwebapp.Tests/Components/SiteDirectory/EngineeringModels/ParticipantsTableTestFixture.cs +++ b/COMETwebapp.Tests/Components/SiteDirectory/EngineeringModels/ParticipantsTableTestFixture.cs @@ -106,7 +106,7 @@ public void SetUp() this.renderer = this.context.RenderComponent(p => { - p.Add(parameter => parameter.EngineeringModelSetup, this.model); + p.Add(parameter => parameter.ViewModel, this.viewModel.Object); }); } @@ -124,10 +124,8 @@ public void VerifyOnInitialized() { Assert.That(this.renderer.Instance.ShouldCreateThing, Is.EqualTo(false)); Assert.That(this.renderer.Instance.ViewModel, Is.Not.Null); - Assert.That(this.renderer.Instance.EngineeringModelSetup, Is.EqualTo(this.model)); Assert.That(this.renderer.Markup, Does.Contain(this.participant1.Person.Name)); Assert.That(this.renderer.Markup, Does.Contain(this.participant2.Person.Name)); - this.viewModel.Verify(x => x.InitializeViewModel(It.IsAny()), Times.Once); }); var details = this.renderer.Find("a"); diff --git a/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/ActiveDomainsTableViewModelTestFixture.cs b/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/ActiveDomainsTableViewModelTestFixture.cs deleted file mode 100644 index ef75bd9b..00000000 --- a/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/ActiveDomainsTableViewModelTestFixture.cs +++ /dev/null @@ -1,194 +0,0 @@ -// -------------------------------------------------------------------------------------------------------------------- -// -// 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.ViewModels.Components.SiteDirectory.EngineeringModels -{ - using CDP4Common.CommonData; - using CDP4Common.SiteDirectoryData; - - using CDP4Dal; - using CDP4Dal.Events; - using CDP4Dal.Permission; - - using CDP4Web.Enumerations; - - using COMET.Web.Common.Model; - using COMET.Web.Common.Services.SessionManagement; - using COMET.Web.Common.Test.Helpers; - - using COMETwebapp.ViewModels.Components.SiteDirectory.EngineeringModels; - - using Microsoft.Extensions.Logging; - - using Moq; - - using NUnit.Framework; - - [TestFixture] - public class ActiveDomainsTableViewModelTestFixture - { - private ActiveDomainsTableViewModel viewModel; - private Mock sessionService; - private Mock permissionService; - private Mock> loggerMock; - private CDPMessageBus messageBus; - private DomainOfExpertise domain; - private EngineeringModelSetup model; - - [SetUp] - public void Setup() - { - this.sessionService = new Mock(); - this.permissionService = new Mock(); - this.messageBus = new CDPMessageBus(); - this.loggerMock = new Mock>(); - - this.domain = new DomainOfExpertise - { - Name = "domain A", - ShortName = "domainA" - }; - - this.model = new EngineeringModelSetup - { - Name = "model", - ShortName = "model", - ActiveDomain = { this.domain } - }; - - var siteDirectory = new SiteDirectory - { - ShortName = "siteDirectory", - Domain = { new DomainOfExpertise() } - }; - - siteDirectory.Domain.Add(this.domain); - siteDirectory.Model.Add(this.model); - - this.permissionService.Setup(x => x.CanWrite(this.domain.ClassKind, this.domain.Container)).Returns(true); - var session = new Mock(); - session.Setup(x => x.PermissionService).Returns(this.permissionService.Object); - session.Setup(x => x.RetrieveSiteDirectory()).Returns(siteDirectory); - this.sessionService.Setup(x => x.Session).Returns(session.Object); - this.sessionService.Setup(x => x.GetSiteDirectory()).Returns(siteDirectory); - - this.viewModel = new ActiveDomainsTableViewModel(this.sessionService.Object, this.messageBus, this.loggerMock.Object); - } - - [TearDown] - public void Teardown() - { - this.messageBus.ClearSubscriptions(); - this.viewModel.Dispose(); - } - - [Test] - public void VerifyActiveDomainRowProperties() - { - this.viewModel.InitializeViewModel(this.model); - var activeDomainRow = this.viewModel.Rows.Items.First(); - - Assert.Multiple(() => - { - Assert.That(activeDomainRow.ContainerName, Is.EqualTo("siteDirectory")); - Assert.That(activeDomainRow.Name, Is.EqualTo(this.domain.Name)); - Assert.That(activeDomainRow.ShortName, Is.EqualTo(this.domain.ShortName)); - Assert.That(activeDomainRow.Thing, Is.EqualTo(this.domain)); - Assert.That(activeDomainRow.IsAllowedToWrite, Is.EqualTo(true)); - }); - } - - [Test] - public async Task VerifyActiveDomainsEdit() - { - this.viewModel.InitializeViewModel(this.model); - - await this.viewModel.EditActiveDomains(); - this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>(), It.IsAny()), Times.Never); - - this.viewModel.SelectedDomainsOfExpertise = [this.domain, this.domain.Clone(true)]; - await this.viewModel.EditActiveDomains(); - - Assert.Multiple(() => { this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>(), It.IsAny()), Times.Once); }); - - this.sessionService.Setup(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>(), It.IsAny())).Throws(new Exception()); - await this.viewModel.EditActiveDomains(); - this.loggerMock.Verify(LogLevel.Error, x => !string.IsNullOrWhiteSpace(x.ToString()), Times.Once()); - } - - [Test] - public void VerifyInitializeViewModel() - { - this.viewModel.InitializeViewModel(this.model); - - Assert.Multiple(() => - { - Assert.That(this.viewModel.Rows.Count, Is.EqualTo(1)); - Assert.That(this.viewModel.Rows.Items.First().Thing, Is.EqualTo(this.domain)); - Assert.That(this.viewModel.DomainsOfExpertise, Has.Count.EqualTo(2)); - Assert.That(this.viewModel.SelectedDomainsOfExpertise, Is.Not.Null); - }); - } - - [Test] - public void VerifySessionRefresh() - { - this.viewModel.InitializeViewModel(this.model); - - this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); - Assert.That(this.viewModel.Rows, Has.Count.EqualTo(1)); - - var domainTest = new DomainOfExpertise - { - Iid = Guid.NewGuid(), - Name = "domain A", - ShortName = "domainA", - Container = new SiteDirectory { Name = "newSite" } - }; - - this.messageBus.SendObjectChangeEvent(domainTest, EventKind.Added); - this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); - - this.messageBus.SendObjectChangeEvent(this.viewModel.Rows.Items.First().Thing, EventKind.Removed); - this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); - - this.messageBus.SendObjectChangeEvent(this.viewModel.Rows.Items.First().Thing, EventKind.Updated); - this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); - - Assert.That(this.viewModel.Rows, Has.Count.EqualTo(1)); - } - - [Test] - public void VerifySetEngineeringModel() - { - this.viewModel.InitializeViewModel(this.model); - - Assert.Multiple(() => - { - Assert.That(this.viewModel.Rows, Has.Count.EqualTo(1)); - Assert.That(this.viewModel.SelectedDomainsOfExpertise.ToList(), Has.Count.EqualTo(1)); - }); - } - } -} diff --git a/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/EngineeringModelsTableViewModelTestFixture.cs b/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/EngineeringModelsTableViewModelTestFixture.cs index 62dcaa18..e97aad99 100644 --- a/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/EngineeringModelsTableViewModelTestFixture.cs +++ b/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/EngineeringModelsTableViewModelTestFixture.cs @@ -1,18 +1,18 @@ // -------------------------------------------------------------------------------------------------------------------- // -// Copyright (c) 2023-2024 Starion Group S.A. +// Copyright (c) 2024 Starion Group S.A. // -// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Antoine Théate, João Rua +// 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 Starion 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. @@ -25,8 +25,8 @@ namespace COMETwebapp.Tests.ViewModels.Components.SiteDirectory.EngineeringModels { using CDP4Common.CommonData; + using CDP4Common.EngineeringModelData; using CDP4Common.SiteDirectoryData; - using CDP4Common.Types; using CDP4Dal; using CDP4Dal.Events; @@ -34,20 +34,19 @@ namespace COMETwebapp.Tests.ViewModels.Components.SiteDirectory.EngineeringModel using CDP4Web.Enumerations; - using COMET.Web.Common.Enumerations; + using COMET.Web.Common.Model; using COMET.Web.Common.Services.SessionManagement; + using COMET.Web.Common.Test.Helpers; using COMETwebapp.ViewModels.Components.SiteDirectory.EngineeringModels; + using DynamicData; + using Microsoft.Extensions.Logging; using Moq; using NUnit.Framework; - using System.Collections.Generic; - - using COMET.Web.Common.Test.Helpers; - using COMET.Web.Common.Model; [TestFixture] public class EngineeringModelsTableViewModelTestFixture @@ -55,7 +54,8 @@ public class EngineeringModelsTableViewModelTestFixture private EngineeringModelsTableViewModel viewModel; private Mock sessionService; private Mock permissionService; - private Assembler assembler; + private Mock organizationalParticipantsTableViewModel; + private Mock participantsTableViewModel; private Mock> loggerMock; private CDPMessageBus messageBus; private EngineeringModelSetup engineeringModel; @@ -69,13 +69,18 @@ public void Setup() this.messageBus = new CDPMessageBus(); this.loggerMock = new Mock>(); - this.engineeringModel = new EngineeringModelSetup() + this.engineeringModel = new EngineeringModelSetup { + Iid = Guid.NewGuid(), ShortName = "model1", Name = "model 1", + OrganizationalParticipant = + { + new OrganizationalParticipant { Organization = new Organization() } + } }; - this.siteDirectory = new SiteDirectory() + this.siteDirectory = new SiteDirectory { ShortName = "siteDirectory", SiteReferenceDataLibrary = { new SiteReferenceDataLibrary() }, @@ -85,19 +90,29 @@ public void Setup() this.siteDirectory.Model.Add(this.engineeringModel); - this.assembler = new Assembler(new Uri("http://localhost:5000/"), this.messageBus); - var lazyModel = new Lazy(this.engineeringModel); - this.assembler.Cache.TryAdd(new CacheKey(), lazyModel); + var iteration = new Iteration + { + Container = new EngineeringModel + { + EngineeringModelSetup = this.engineeringModel + } + }; + + var openIterations = new SourceList(); + openIterations.Add(iteration); this.permissionService.Setup(x => x.CanWrite(this.engineeringModel.ClassKind, this.engineeringModel.Container)).Returns(true); var session = new Mock(); session.Setup(x => x.PermissionService).Returns(this.permissionService.Object); - session.Setup(x => x.Assembler).Returns(this.assembler); session.Setup(x => x.RetrieveSiteDirectory()).Returns(this.siteDirectory); this.sessionService.Setup(x => x.Session).Returns(session.Object); this.sessionService.Setup(x => x.GetSiteDirectory()).Returns(this.siteDirectory); + this.sessionService.Setup(x => x.OpenIterations).Returns(openIterations); - this.viewModel = new EngineeringModelsTableViewModel(this.sessionService.Object, this.messageBus, this.loggerMock.Object); + this.organizationalParticipantsTableViewModel = new Mock(); + this.participantsTableViewModel = new Mock(); + + this.viewModel = new EngineeringModelsTableViewModel(this.sessionService.Object, this.messageBus, this.loggerMock.Object, this.organizationalParticipantsTableViewModel.Object, this.participantsTableViewModel.Object); } [TearDown] @@ -126,54 +141,42 @@ public void VerifyInitializeViewModel() } [Test] - public void VerifyModelRowProperties() + public async Task VerifyModelCreation() { this.viewModel.InitializeViewModel(); - var modelRow = this.viewModel.Rows.Items.First(); + this.viewModel.CurrentThing = this.engineeringModel.Clone(true); + this.viewModel.SelectedSourceModel = new EngineeringModelSetup(); + + await this.viewModel.CreateOrEditEngineeringModel(true); + this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>(), It.IsAny()), Times.Once); Assert.Multiple(() => { - Assert.That(modelRow.ContainerName, Is.EqualTo("siteDirectory")); - Assert.That(modelRow.Name, Is.EqualTo(this.engineeringModel.Name)); - Assert.That(modelRow.ShortName, Is.EqualTo(this.engineeringModel.ShortName)); - Assert.That(modelRow.Thing, Is.EqualTo(this.engineeringModel)); - Assert.That(modelRow.IsAllowedToWrite, Is.EqualTo(true)); + Assert.That(this.viewModel.SelectedSiteRdl, Is.Null); + Assert.That(this.viewModel.SelectedSourceModel, Is.Null); + Assert.That(this.viewModel.CurrentThing.Original, Is.Not.Null); }); + + this.viewModel.SelectedSourceModel = null; + this.viewModel.SelectedSiteRdl = new SiteReferenceDataLibrary(); + this.sessionService.Setup(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>(), It.IsAny())).Throws(new Exception()); + await this.viewModel.CreateOrEditEngineeringModel(true); + this.loggerMock.Verify(LogLevel.Error, x => !string.IsNullOrWhiteSpace(x.ToString()), Times.Once()); } [Test] - public void VerifySessionRefresh() + public void VerifyModelRowProperties() { this.viewModel.InitializeViewModel(); - - this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); - Assert.That(this.viewModel.Rows, Has.Count.EqualTo(1)); - - var engineeringModelTest = new EngineeringModelSetup() - { - Iid = Guid.NewGuid(), - Container = this.siteDirectory, - }; - - this.messageBus.SendObjectChangeEvent(engineeringModelTest, EventKind.Added); - this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); - - this.messageBus.SendObjectChangeEvent(this.viewModel.Rows.Items.First().Thing, EventKind.Removed); - this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); - - this.messageBus.SendObjectChangeEvent(this.viewModel.Rows.Items.First().Thing, EventKind.Updated); - this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); - - Assert.That(this.viewModel.Rows, Has.Count.EqualTo(1)); - - this.messageBus.SendObjectChangeEvent(this.siteDirectory, EventKind.Updated); - this.messageBus.SendObjectChangeEvent(new PersonRole(), EventKind.Updated); - this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); + var modelRow = this.viewModel.Rows.Items.First(); Assert.Multiple(() => { - Assert.That(this.viewModel.Rows.Items.First().ContainerName, Is.EqualTo(this.siteDirectory.ShortName)); - this.permissionService.Verify(x => x.CanWrite(engineeringModelTest.ClassKind, It.IsAny()), Times.AtLeast(this.viewModel.Rows.Count)); + Assert.That(modelRow.ContainerName, Is.EqualTo("siteDirectory")); + Assert.That(modelRow.Name, Is.EqualTo(this.engineeringModel.Name)); + Assert.That(modelRow.ShortName, Is.EqualTo(this.engineeringModel.ShortName)); + Assert.That(modelRow.Thing, Is.EqualTo(this.engineeringModel)); + Assert.That(modelRow.IsAllowedToWrite, Is.EqualTo(true)); }); } @@ -205,32 +208,38 @@ public async Task VerifyRowOperations() } [Test] - public async Task VerifyModelCreation() + public void VerifySessionRefresh() { this.viewModel.InitializeViewModel(); - var testOrganization = this.siteDirectory.Organization.First(); - this.viewModel.SelectedOrganizations = [testOrganization]; - this.viewModel.SelectedModelAdminOrganization = testOrganization; + this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); + Assert.That(this.viewModel.Rows, Has.Count.EqualTo(1)); - this.viewModel.SelectedActiveDomains = [this.siteDirectory.Domain.First()]; - this.viewModel.SelectedSiteRdl = this.siteDirectory.SiteReferenceDataLibrary.First(); - this.viewModel.SelectedSourceModel = this.siteDirectory.Model.First(); + var engineeringModelTest = new EngineeringModelSetup + { + Iid = Guid.NewGuid(), + Container = this.siteDirectory + }; - this.viewModel.SetupEngineeringModelWithSelectedValues(); - await this.viewModel.CreateEngineeringModel(); + this.messageBus.SendObjectChangeEvent(engineeringModelTest, EventKind.Added); + this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); - this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.Is>(c => c.Count == 4), It.IsAny()), Times.Once); + this.messageBus.SendObjectChangeEvent(this.viewModel.Rows.Items.First().Thing, EventKind.Removed); + this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); - this.viewModel.ResetSelectedValues(); + this.messageBus.SendObjectChangeEvent(this.viewModel.Rows.Items.First().Thing, EventKind.Updated); + this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); + + Assert.That(this.viewModel.Rows, Has.Count.EqualTo(1)); + + this.messageBus.SendObjectChangeEvent(this.siteDirectory, EventKind.Updated); + this.messageBus.SendObjectChangeEvent(new PersonRole(), EventKind.Updated); + this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); Assert.Multiple(() => { - Assert.That(this.viewModel.SelectedActiveDomains, Has.Count.EqualTo(0)); - Assert.That(this.viewModel.SelectedOrganizations, Has.Count.EqualTo(0)); - Assert.That(this.viewModel.SelectedModelAdminOrganization, Is.Null); - Assert.That(this.viewModel.SelectedSiteRdl, Is.Null); - Assert.That(this.viewModel.SelectedSourceModel, Is.Null); + Assert.That(this.viewModel.Rows.Items.First().ContainerName, Is.EqualTo(this.siteDirectory.ShortName)); + this.permissionService.Verify(x => x.CanWrite(engineeringModelTest.ClassKind, It.IsAny()), Times.AtLeast(this.viewModel.Rows.Count)); }); } } diff --git a/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/IterationsTableViewModelTestFixture.cs b/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/IterationsTableViewModelTestFixture.cs deleted file mode 100644 index 095f2ee9..00000000 --- a/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/IterationsTableViewModelTestFixture.cs +++ /dev/null @@ -1,173 +0,0 @@ -// -------------------------------------------------------------------------------------------------------------------- -// -// 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.ViewModels.Components.SiteDirectory.EngineeringModels -{ - using CDP4Common.EngineeringModelData; - using CDP4Common.SiteDirectoryData; - - using CDP4Dal; - using CDP4Dal.Events; - using CDP4Dal.Permission; - - using CDP4Web.Enumerations; - - using COMET.Web.Common.Extensions; - using COMET.Web.Common.Services.SessionManagement; - - using COMETwebapp.ViewModels.Components.SiteDirectory.EngineeringModels; - - using DynamicData; - - using Microsoft.Extensions.Logging; - - using Moq; - - using NUnit.Framework; - - [TestFixture] - public class IterationsTableViewModelTestFixture - { - private IterationsTableViewModel viewModel; - private Mock sessionService; - private Mock permissionService; - private Mock> loggerMock; - private CDPMessageBus messageBus; - private Iteration iteration; - private EngineeringModelSetup model; - - [SetUp] - public void Setup() - { - this.sessionService = new Mock(); - this.permissionService = new Mock(); - this.messageBus = new CDPMessageBus(); - this.loggerMock = new Mock>(); - - this.model = new EngineeringModelSetup - { - Iid = Guid.NewGuid(), - Name = "model", - ShortName = "model" - }; - - this.iteration = new Iteration - { - Container = new EngineeringModel - { - EngineeringModelSetup = this.model - }, - IterationSetup = new IterationSetup - { - Container = this.model - } - }; - - this.permissionService.Setup(x => x.CanWrite(this.iteration.ClassKind, this.iteration.Container)).Returns(true); - var session = new Mock(); - session.Setup(x => x.PermissionService).Returns(this.permissionService.Object); - this.sessionService.Setup(x => x.Session).Returns(session.Object); - - var openIterations = new SourceList(); - openIterations.Add(this.iteration); - this.sessionService.Setup(x => x.OpenIterations).Returns(openIterations); - - this.viewModel = new IterationsTableViewModel(this.sessionService.Object, this.messageBus, this.loggerMock.Object); - } - - [TearDown] - public void Teardown() - { - this.messageBus.ClearSubscriptions(); - this.viewModel.Dispose(); - } - - [Test] - public void VerifyInitializeViewModel() - { - this.viewModel.InitializeViewModel(this.model); - - Assert.Multiple(() => - { - Assert.That(this.viewModel.Rows.Count, Is.EqualTo(1)); - Assert.That(this.viewModel.Rows.Items.First().Thing, Is.EqualTo(this.iteration)); - }); - } - - [Test] - public void VerifyIterationRowProperties() - { - this.viewModel.InitializeViewModel(this.model); - var participantRow = this.viewModel.Rows.Items.First(); - - Assert.Multiple(() => - { - Assert.That(participantRow.Name, Is.EqualTo(this.iteration.GetName())); - Assert.That(participantRow.Number, Is.EqualTo(this.iteration.IterationSetup.IterationNumber.ToString())); - Assert.That(participantRow.Thing, Is.EqualTo(this.iteration)); - }); - } - - [Test] - public void VerifySessionRefresh() - { - this.viewModel.InitializeViewModel(this.model); - - this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); - Assert.That(this.viewModel.Rows, Has.Count.EqualTo(1)); - - var iterationTest = new Iteration - { - Iid = Guid.NewGuid(), - Container = new EngineeringModel - { - EngineeringModelSetup = this.model - }, - IterationSetup = new IterationSetup - { - Container = this.model - } - }; - - this.messageBus.SendObjectChangeEvent(iterationTest, EventKind.Added); - this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); - - this.messageBus.SendObjectChangeEvent(this.viewModel.Rows.Items.First().Thing, EventKind.Removed); - this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); - - this.messageBus.SendObjectChangeEvent(this.viewModel.Rows.Items.First().Thing, EventKind.Updated); - this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); - - Assert.That(this.viewModel.Rows, Has.Count.EqualTo(1)); - } - - [Test] - public void VerifySetEngineeringModel() - { - this.viewModel.InitializeViewModel(this.model); - - Assert.That(this.viewModel.Rows, Has.Count.EqualTo(1)); - } - } -} diff --git a/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/OrganizationalParticipantsTableViewModelTestFixture.cs b/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/OrganizationalParticipantsTableViewModelTestFixture.cs index 6388e679..3a4e8df8 100644 --- a/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/OrganizationalParticipantsTableViewModelTestFixture.cs +++ b/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/OrganizationalParticipantsTableViewModelTestFixture.cs @@ -28,15 +28,13 @@ namespace COMETwebapp.Tests.ViewModels.Components.SiteDirectory.EngineeringModel using CDP4Common.SiteDirectoryData; using CDP4Dal; - using CDP4Dal.Events; using CDP4Dal.Permission; - using CDP4Web.Enumerations; - using COMET.Web.Common.Model; using COMET.Web.Common.Services.SessionManagement; using COMETwebapp.ViewModels.Components.SiteDirectory.EngineeringModels; + using COMETwebapp.ViewModels.Components.SiteDirectory.Rows; using Microsoft.Extensions.Logging; @@ -112,9 +110,9 @@ public void VerifyInitializeViewModel() Assert.Multiple(() => { - Assert.That(this.viewModel.Rows.Count, Is.EqualTo(1)); - Assert.That(this.viewModel.Rows.Items.First().Thing, Is.EqualTo(this.organizationalParticipant)); - Assert.That(this.viewModel.Organizations, Has.Count.EqualTo(1)); + Assert.That(this.viewModel.CurrentModel.OrganizationalParticipant, Has.Count.EqualTo(1)); + Assert.That(this.viewModel.CurrentModel.OrganizationalParticipant.First(), Is.EqualTo(this.organizationalParticipant)); + Assert.That(this.viewModel.Organizations.Count(), Is.EqualTo(1)); Assert.That(this.viewModel.ParticipatingOrganizations, Is.Not.Null); }); } @@ -123,7 +121,7 @@ public void VerifyInitializeViewModel() public void VerifyOrganizationalParticipantRowProperties() { this.viewModel.InitializeViewModel(this.model); - var participantRow = this.viewModel.Rows.Items.First(); + var participantRow = new OrganizationalParticipantRowViewModel(this.viewModel.CurrentModel.OrganizationalParticipant.First()); Assert.Multiple(() => { @@ -131,7 +129,6 @@ public void VerifyOrganizationalParticipantRowProperties() Assert.That(participantRow.Name, Is.EqualTo(this.organizationalParticipant.Organization.Name)); Assert.That(participantRow.ShortName, Is.EqualTo(this.organizationalParticipant.Organization.ShortName)); Assert.That(participantRow.Thing, Is.EqualTo(this.organizationalParticipant)); - Assert.That(participantRow.IsAllowedToWrite, Is.EqualTo(true)); }); } @@ -139,7 +136,7 @@ public void VerifyOrganizationalParticipantRowProperties() public async Task VerifyRowOperations() { this.viewModel.InitializeViewModel(this.model); - var organizationalParticipantRow = this.viewModel.Rows.Items.First(); + var organizationalParticipantRow = new OrganizationalParticipantRowViewModel(this.viewModel.CurrentModel.OrganizationalParticipant.First()); Assert.That(organizationalParticipantRow, Is.Not.Null); @@ -157,48 +154,5 @@ public async Task VerifyRowOperations() await this.viewModel.OnConfirmPopupButtonClick(); this.sessionService.Verify(x => x.DeleteThingsWithNotification(It.IsAny(), It.IsAny>(), It.IsAny()), Times.Once); } - - [Test] - public void VerifySessionRefresh() - { - this.viewModel.InitializeViewModel(this.model); - - this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); - Assert.That(this.viewModel.Rows, Has.Count.EqualTo(1)); - - var organizationalParticipantTest = new OrganizationalParticipant - { - Iid = Guid.NewGuid(), - Organization = new Organization - { - Name = "org B", - ShortName = "orgB" - }, - Container = this.model - }; - - this.messageBus.SendObjectChangeEvent(organizationalParticipantTest, EventKind.Added); - this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); - - this.messageBus.SendObjectChangeEvent(this.viewModel.Rows.Items.First().Thing, EventKind.Removed); - this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); - - this.messageBus.SendObjectChangeEvent(this.viewModel.Rows.Items.First().Thing, EventKind.Updated); - this.messageBus.SendMessage(SessionServiceEvent.SessionRefreshed, this.sessionService.Object.Session); - - Assert.That(this.viewModel.Rows, Has.Count.EqualTo(1)); - } - - [Test] - public void VerifySetEngineeringModel() - { - this.viewModel.InitializeViewModel(this.model); - - Assert.Multiple(() => - { - Assert.That(this.viewModel.Rows, Has.Count.EqualTo(1)); - Assert.That(this.viewModel.ParticipatingOrganizations.ToList(), Has.Count.EqualTo(1)); - }); - } } } diff --git a/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/ParticipantsTableViewModelTestFixture.cs b/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/ParticipantsTableViewModelTestFixture.cs index c6f1ed08..b0bb5f2a 100644 --- a/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/ParticipantsTableViewModelTestFixture.cs +++ b/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/ParticipantsTableViewModelTestFixture.cs @@ -150,13 +150,14 @@ public void VerifyOrganizationalParticipantRowProperties() public async Task VerifyParticipantsActions() { this.viewModel.InitializeViewModel(this.model); + this.viewModel.CurrentThing = this.participant.Clone(true); this.viewModel.SelectedDomains = [this.participant.Domain.First(), this.participant.Domain.First().Clone(true)]; await this.viewModel.CreateOrEditParticipant(false); - this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.Is>(c => c.Count == 1), It.IsAny()), Times.Once); - + this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>(), It.IsAny()), Times.Once); + await this.viewModel.CreateOrEditParticipant(true); - this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.Is>(c => c.Count == 2), It.IsAny()), Times.Once); + this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>(), It.IsAny()), Times.Exactly(2)); this.sessionService.Setup(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>(), It.IsAny())).Throws(new Exception()); await this.viewModel.CreateOrEditParticipant(false); diff --git a/COMETwebapp/Components/Common/FormButtons.razor b/COMETwebapp/Components/Common/FormButtons.razor index e6aac81d..51546379 100644 --- a/COMETwebapp/Components/Common/FormButtons.razor +++ b/COMETwebapp/Components/Common/FormButtons.razor @@ -17,6 +17,15 @@ Copyright (c) 2023-2024 Starion Group S.A. @inherits DisposableComponent
+ @if (this.DeleteButtonVisible) + { + + Delete + + } + diff --git a/COMETwebapp/Components/Common/FormButtons.razor.cs b/COMETwebapp/Components/Common/FormButtons.razor.cs index f183476a..62ddaa64 100644 --- a/COMETwebapp/Components/Common/FormButtons.razor.cs +++ b/COMETwebapp/Components/Common/FormButtons.razor.cs @@ -1,5 +1,5 @@ // -------------------------------------------------------------------------------------------------------------------- -// +// // Copyright (c) 2024 Starion Group S.A. // // Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, João Rua @@ -58,5 +58,17 @@ public partial class FormButtons : DisposableComponent /// [Parameter] public bool IsLoading { get; set; } + + /// + /// Gets or sets the callback for when the delete button is clicked + /// + [Parameter] + public EventCallback OnDelete { get; set; } + + /// + /// Gets or sets the value to check if the delete button should be displayed + /// + [Parameter] + public bool DeleteButtonVisible { get; set; } } } diff --git a/COMETwebapp/Components/Common/SelectedDataItemBase.razor.cs b/COMETwebapp/Components/Common/SelectedDataItemBase.razor.cs index 08d26b10..734ec80c 100644 --- a/COMETwebapp/Components/Common/SelectedDataItemBase.razor.cs +++ b/COMETwebapp/Components/Common/SelectedDataItemBase.razor.cs @@ -105,5 +105,26 @@ protected virtual void OnSelectedDataItemChanged(TRow row) { this.IsOnEditMode = true; } + + /// + /// Method invoked whenever a form is saved + /// + protected void OnSaved() + { + if (!this.ShouldCreateThing) + { + return; + } + + this.ShouldCreateThing = false; + var createdRow = this.ViewModel.Rows.Items.FirstOrDefault(x => x.Thing.Iid == this.ViewModel.CurrentThing.Iid); + + if (createdRow is null) + { + return; + } + + this.OnSelectedDataItemChanged(createdRow); + } } } diff --git a/COMETwebapp/Components/Common/SelectedDeprecatableDataItemBase.razor.cs b/COMETwebapp/Components/Common/SelectedDeprecatableDataItemBase.razor.cs index fd1a73ba..42fe3326 100644 --- a/COMETwebapp/Components/Common/SelectedDeprecatableDataItemBase.razor.cs +++ b/COMETwebapp/Components/Common/SelectedDeprecatableDataItemBase.razor.cs @@ -107,26 +107,5 @@ protected static void DisableDeprecatedThing(GridCustomizeElementEventArgs e) e.CssClass = "highlighted-item"; } } - - /// - /// Method invoked whenever a form is saved - /// - protected void OnSaved() - { - if (!this.ShouldCreateThing) - { - return; - } - - this.ShouldCreateThing = false; - var createdRow = this.ViewModel.Rows.Items.FirstOrDefault(x => x.Thing.Iid == this.ViewModel.CurrentThing.Iid); - - if (createdRow is null) - { - return; - } - - this.OnSelectedDataItemChanged(createdRow); - } } } diff --git a/COMETwebapp/Components/SiteDirectory/EngineeringModel/ActiveDomainsTable.razor b/COMETwebapp/Components/SiteDirectory/EngineeringModel/ActiveDomainsTable.razor index c021ece0..3ca5446e 100644 --- a/COMETwebapp/Components/SiteDirectory/EngineeringModel/ActiveDomainsTable.razor +++ b/COMETwebapp/Components/SiteDirectory/EngineeringModel/ActiveDomainsTable.razor @@ -14,62 +14,52 @@ Copyright (c) 2023-2024 Starion Group S.A. You should have received a copy of the GNU Affero General Public License along with this program. If not, see http://www.gnu.org/licenses/. -------------------------------------------------------------------------------> -@using CDP4Common.SiteDirectoryData -@using COMETwebapp.ViewModels.Components.SiteDirectory.Rows -@inherits COMETwebapp.Components.Common.SelectedDataItemBase +@inherits SelectedDataItemBase - - - - - - - - + + + + + + + + + + + - - - - + - - - + - - - - - - -
- - Save - - - Cancel - -
-
- -
+
+ + Save + + + Cancel + +
+ \ No newline at end of file diff --git a/COMETwebapp/Components/SiteDirectory/EngineeringModel/ActiveDomainsTable.razor.cs b/COMETwebapp/Components/SiteDirectory/EngineeringModel/ActiveDomainsTable.razor.cs index 1076d68b..f2b3236a 100644 --- a/COMETwebapp/Components/SiteDirectory/EngineeringModel/ActiveDomainsTable.razor.cs +++ b/COMETwebapp/Components/SiteDirectory/EngineeringModel/ActiveDomainsTable.razor.cs @@ -1,63 +1,52 @@ // -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) 2023-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 CDP4-COMET WEB Community Edition -// The CDP4-COMET WEB Community Edition is the Starion 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.SiteDirectory.EngineeringModel { using CDP4Common.SiteDirectoryData; using COMETwebapp.Components.Common; - using COMETwebapp.ViewModels.Components.SiteDirectory.EngineeringModels; using COMETwebapp.ViewModels.Components.SiteDirectory.Rows; using Microsoft.AspNetCore.Components; /// - /// Support class for the + /// Support class for the /// public partial class ActiveDomainsTable : SelectedDataItemBase { /// - /// The for this component - /// - [Inject] - public IActiveDomainsTableViewModel ViewModel { get; set; } - - /// - /// Gets or sets the + /// Gets or sets the /// [Parameter] public EngineeringModelSetup EngineeringModelSetup { get; set; } /// - /// Method invoked when the component has received parameters from its parent in - /// the render tree, and the incoming values have been assigned to properties. + /// Gets or sets a collection of /// - protected override void OnParametersSet() - { - base.OnParametersSet(); - this.ViewModel.InitializeViewModel(this.EngineeringModelSetup); - } + [Parameter] + public IEnumerable DomainsOfExpertise { get; set; } /// /// Sets the edit active domains popup visibility @@ -67,24 +56,5 @@ private void SetEditPopupVisibility(bool visible) { this.IsOnEditMode = visible; } - - /// - /// Saves the active domains changes - /// - /// A - private async Task SaveChanges() - { - await this.ViewModel.EditActiveDomains(); - this.SetEditPopupVisibility(false); - } - - /// - /// Cancels the active domains changes - /// - private void CancelChanges() - { - this.ViewModel.ResetSelectedDomainsOfExpertise(); - this.SetEditPopupVisibility(false); - } } } diff --git a/COMETwebapp/Components/SiteDirectory/EngineeringModel/EngineeringModelsForm.razor b/COMETwebapp/Components/SiteDirectory/EngineeringModel/EngineeringModelsForm.razor new file mode 100644 index 00000000..a12be4a1 --- /dev/null +++ b/COMETwebapp/Components/SiteDirectory/EngineeringModel/EngineeringModelsForm.razor @@ -0,0 +1,88 @@ + +@inherits SelectedDataItemForm + + + + + + + + + + + + + + + + + + + + + + + + + + + @if (!this.ShouldCreate) + { + + + + + + + + } + + + + + + + + + + + \ No newline at end of file diff --git a/COMETwebapp/Components/SiteDirectory/EngineeringModel/EngineeringModelsForm.razor.cs b/COMETwebapp/Components/SiteDirectory/EngineeringModel/EngineeringModelsForm.razor.cs new file mode 100644 index 00000000..15208ea6 --- /dev/null +++ b/COMETwebapp/Components/SiteDirectory/EngineeringModel/EngineeringModelsForm.razor.cs @@ -0,0 +1,61 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// 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.SiteDirectory.EngineeringModel +{ + using System.ComponentModel.DataAnnotations; + + using COMETwebapp.Components.Common; + using COMETwebapp.ViewModels.Components.SiteDirectory.EngineeringModels; + + using Microsoft.AspNetCore.Components; + + /// + /// Support class for the + /// + public partial class EngineeringModelsForm : SelectedDataItemForm + { + /// + /// The for this component + /// + [Parameter] + [Required] + public IEngineeringModelsTableViewModel ViewModel { get; set; } + + /// + /// Gets the condition to check if the source model was selected in creation form + /// + private bool IsSourceModelSelected => this.ViewModel.CurrentThing.SourceEngineeringModelSetupIid != null && this.ViewModel.CurrentThing.SourceEngineeringModelSetupIid != Guid.Empty; + + /// + /// Method that is executed when there is a valid submit + /// + /// A + protected override async Task OnValidSubmit() + { + await this.ViewModel.CreateOrEditEngineeringModel(this.ShouldCreate); + await base.OnValidSubmit(); + } + } +} diff --git a/COMETwebapp/Components/SiteDirectory/EngineeringModel/EngineeringModelsTable.razor b/COMETwebapp/Components/SiteDirectory/EngineeringModel/EngineeringModelsTable.razor index 841be087..067f79e6 100644 --- a/COMETwebapp/Components/SiteDirectory/EngineeringModel/EngineeringModelsTable.razor +++ b/COMETwebapp/Components/SiteDirectory/EngineeringModel/EngineeringModelsTable.razor @@ -22,170 +22,40 @@ Copyright (c) 2023-2024 Starion Group S.A. Data="this.ViewModel.Rows.Items" ColumnResizeMode="GridColumnResizeMode.ColumnsContainer" ShowSearchBox="true" - SearchBoxNullText="Search for a model..." + SearchBoxNullText="Search for a model ..." AllowSelectRowByClick="true" + SelectionMode="GridSelectionMode.Single" SelectedDataItemChanged="@(row => this.OnSelectedDataItemChanged((EngineeringModelRowViewModel)row))" - PopupEditFormCssClass="pw-800" - PopupEditFormHeaderText="Engineering Model" - CustomizeEditModel="this.CustomizeEditThing" - EditMode="GridEditMode.PopupEditForm" - EditModelSaving="@(() => this.OnEditThingSaving())" EditFormButtonsVisible="false" PageSize="20" PagerNavigationMode="PagerNavigationMode.Auto" PageSizeSelectorVisible="true" PageSizeSelectorItems="@(new[] { 20, 35, 50 })" PageSizeSelectorAllRowsItemVisible="true" - CssClass="d-inline height-fit-content"> + FilterMenuButtonDisplayMode="GridFilterMenuButtonDisplayMode.Always" + CssClass="height-fit-content"> - - - - - - @{ - var row = (EngineeringModelRowViewModel)context.DataItem; - - - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - Save - - - Cancel - -
-
- - - - - - - - - - @foreach (var mappedValue in this.mapOfComponentsAndNames) - { - - } - - - @if (this.SelectedComponent != null) - { - - } + +
-
@(this.ViewModel.PopupDialog)
- +
\ No newline at end of file diff --git a/COMETwebapp/Components/SiteDirectory/EngineeringModel/EngineeringModelsTable.razor.cs b/COMETwebapp/Components/SiteDirectory/EngineeringModel/EngineeringModelsTable.razor.cs index 7e72e4d2..c12790ed 100644 --- a/COMETwebapp/Components/SiteDirectory/EngineeringModel/EngineeringModelsTable.razor.cs +++ b/COMETwebapp/Components/SiteDirectory/EngineeringModel/EngineeringModelsTable.razor.cs @@ -26,14 +26,16 @@ namespace COMETwebapp.Components.SiteDirectory.EngineeringModel { using CDP4Common.SiteDirectoryData; + using COMET.Web.Common.Extensions; + using COMETwebapp.Components.Common; using COMETwebapp.ViewModels.Components.SiteDirectory.EngineeringModels; using COMETwebapp.ViewModels.Components.SiteDirectory.Rows; - using DevExpress.Blazor; - using Microsoft.AspNetCore.Components; + using ReactiveUI; + /// /// Support class for the /// @@ -45,32 +47,6 @@ public partial class EngineeringModelsTable : SelectedDataItemBase - /// Gets the condition to check if the source model was selected in creation form - /// - private bool IsSourceModelSelected => this.ViewModel.SelectedSourceModel is not null; - - /// - /// The selected component type - /// - private Type SelectedComponent { get; set; } - - /// - /// A for the - /// - private readonly Dictionary parameters = []; - - /// - /// A map with all the available components and their names - /// - private readonly Dictionary mapOfComponentsAndNames = new() - { - {typeof(ParticipantsTable), "Participants"}, - {typeof(OrganizationalParticipantsTable), "Organizations"}, - {typeof(IterationsTable), "Iterations"}, - {typeof(ActiveDomainsTable), "Active Domains"}, - }; - /// /// Method invoked when the component is ready to start, having received its /// initial parameters from its parent in the render tree. @@ -79,59 +55,39 @@ protected override void OnInitialized() { base.OnInitialized(); this.Initialize(this.ViewModel); - this.SelectedComponent = this.mapOfComponentsAndNames.First().Key; - } - - /// - /// Method that is invoked when the edit/add thing form is being saved - /// - /// A - protected override async Task OnEditThingSaving() - { - await this.ViewModel.CreateEngineeringModel(); - } - - /// - /// Method invoked when creating a new thing - /// - /// A - protected override void CustomizeEditThing(GridCustomizeEditModelEventArgs e) - { - base.CustomizeEditThing(e); - - this.ViewModel.CurrentThing = new EngineeringModelSetup(); - this.ViewModel.ResetSelectedValues(); - e.EditModel = this.ViewModel.CurrentThing; + this.Disposables.Add(this.WhenAnyValue(x => x.ViewModel.IsOnDeletionMode).SubscribeAsync(_ => this.InvokeAsync(this.StateHasChanged))); } /// - /// Metgid invoked everytime a row is selected + /// Method invoked every time a row is selected /// /// The selected row protected override void OnSelectedDataItemChanged(EngineeringModelRowViewModel row) { base.OnSelectedDataItemChanged(row); - this.ViewModel.CurrentThing = row.Thing; - this.parameters[nameof(EngineeringModelSetup)] = row.Thing; + this.ShouldCreateThing = false; + this.ViewModel.CurrentThing = row.Thing.Clone(true); } /// - /// Method invoked to set the selected component from toolbar + /// Method invoked before creating a new thing /// - /// The - private void OnDetailsItemClick(ToolbarItemClickEventArgs e) + private void OnAddThingClick() { - this.SelectedComponent = this.mapOfComponentsAndNames.First(x => x.Value == e.ItemName).Key; + this.ShouldCreateThing = true; + this.IsOnEditMode = true; + this.ViewModel.CurrentThing = new EngineeringModelSetup(); + this.InvokeAsync(this.StateHasChanged); } /// - /// Sets the selected values for the creation and submits the form + /// Method invoked when the deletion of a thing is confirmed /// /// A - private async Task SetSelectedValuesAndSubmit() + private async Task OnDeletionConfirmed() { - this.ViewModel.SetupEngineeringModelWithSelectedValues(); - await this.Grid.SaveChangesAsync(); + await this.ViewModel.OnConfirmPopupButtonClick(); + this.IsOnEditMode = false; } } } diff --git a/COMETwebapp/Components/SiteDirectory/EngineeringModel/IterationsTable.razor b/COMETwebapp/Components/SiteDirectory/EngineeringModel/IterationsTable.razor index 4f1e7966..551ee611 100644 --- a/COMETwebapp/Components/SiteDirectory/EngineeringModel/IterationsTable.razor +++ b/COMETwebapp/Components/SiteDirectory/EngineeringModel/IterationsTable.razor @@ -17,16 +17,14 @@ Copyright (c) 2023-2024 Starion Group S.A. @using COMETwebapp.ViewModels.Components.SiteDirectory.Rows @inherits COMETwebapp.Components.Common.SelectedDataItemBase - - - - - - - - \ No newline at end of file + + + + + + diff --git a/COMETwebapp/Components/SiteDirectory/EngineeringModel/IterationsTable.razor.cs b/COMETwebapp/Components/SiteDirectory/EngineeringModel/IterationsTable.razor.cs index 6f167212..c6650be2 100644 --- a/COMETwebapp/Components/SiteDirectory/EngineeringModel/IterationsTable.razor.cs +++ b/COMETwebapp/Components/SiteDirectory/EngineeringModel/IterationsTable.razor.cs @@ -1,26 +1,26 @@ // -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) 2023-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 CDP4-COMET WEB Community Edition -// The CDP4-COMET WEB Community Edition is the Starion 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.SiteDirectory.EngineeringModel { @@ -28,36 +28,25 @@ namespace COMETwebapp.Components.SiteDirectory.EngineeringModel using CDP4Common.SiteDirectoryData; using COMETwebapp.Components.Common; - using COMETwebapp.ViewModels.Components.SiteDirectory.EngineeringModels; using COMETwebapp.ViewModels.Components.SiteDirectory.Rows; using Microsoft.AspNetCore.Components; /// - /// Support class for the + /// Support class for the /// public partial class IterationsTable : SelectedDataItemBase { /// - /// The for this component + /// The collection of s /// - [Inject] - public IIterationsTableViewModel ViewModel { get; set; } + [Parameter] + public IEnumerable IterationRows { get; set; } /// - /// Gets or sets the + /// Gets or sets the /// [Parameter] public EngineeringModelSetup EngineeringModelSetup { get; set; } - - /// - /// Method invoked when the component has received parameters from its parent in - /// the render tree, and the incoming values have been assigned to properties. - /// - protected override void OnParametersSet() - { - base.OnParametersSet(); - this.ViewModel.InitializeViewModel(this.EngineeringModelSetup); - } } } diff --git a/COMETwebapp/Components/SiteDirectory/EngineeringModel/OrganizationalParticipantsTable.razor b/COMETwebapp/Components/SiteDirectory/EngineeringModel/OrganizationalParticipantsTable.razor index 1740adbf..c8da529e 100644 --- a/COMETwebapp/Components/SiteDirectory/EngineeringModel/OrganizationalParticipantsTable.razor +++ b/COMETwebapp/Components/SiteDirectory/EngineeringModel/OrganizationalParticipantsTable.razor @@ -14,72 +14,65 @@ Copyright (c) 2023-2024 Starion Group S.A. You should have received a copy of the GNU Affero General Public License along with this program. If not, see http://www.gnu.org/licenses/. -------------------------------------------------------------------------------> -@using COMETwebapp.ViewModels.Components.SiteDirectory.Rows -@using CDP4Common.SiteDirectoryData -@inherits COMETwebapp.Components.Common.SelectedDataItemBase +@inherits SelectedDataItemBase - - - - - - - - - - - @{ - var row = (OrganizationalParticipantRowViewModel)context.DataItem; + + + + + + + + + + + - - } - - - + + + + + + + + @organizationalParticipant?.Organization.Name + @organizationalParticipant.Organization.Name + + + - - - - - - - - - - - - - - - - - - - @this.ViewModel.PopupDialog -
- - +
+ + Save + + + Cancel +
- + \ No newline at end of file diff --git a/COMETwebapp/Components/SiteDirectory/EngineeringModel/OrganizationalParticipantsTable.razor.cs b/COMETwebapp/Components/SiteDirectory/EngineeringModel/OrganizationalParticipantsTable.razor.cs index 2c1a34b4..f2ced2ee 100644 --- a/COMETwebapp/Components/SiteDirectory/EngineeringModel/OrganizationalParticipantsTable.razor.cs +++ b/COMETwebapp/Components/SiteDirectory/EngineeringModel/OrganizationalParticipantsTable.razor.cs @@ -1,32 +1,33 @@ // -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) 2023-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 CDP4-COMET WEB Community Edition -// The CDP4-COMET WEB Community Edition is the Starion 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.SiteDirectory.EngineeringModel { using CDP4Common.SiteDirectoryData; using COMETwebapp.Components.Common; + using COMETwebapp.ViewModels.Components.EngineeringModel.Rows; using COMETwebapp.ViewModels.Components.SiteDirectory.EngineeringModels; using COMETwebapp.ViewModels.Components.SiteDirectory.Rows; @@ -35,52 +36,33 @@ namespace COMETwebapp.Components.SiteDirectory.EngineeringModel using Microsoft.AspNetCore.Components; /// - /// Support class for the + /// Support class for the /// public partial class OrganizationalParticipantsTable : SelectedDataItemBase { /// /// The for this component /// - [Inject] - public IOrganizationalParticipantsTableViewModel ViewModel { get; set; } - - /// - /// Gets or sets the - /// [Parameter] - public EngineeringModelSetup EngineeringModelSetup { get; set; } - - /// - /// Method invoked when the component has received parameters from its parent in - /// the render tree, and the incoming values have been assigned to properties. - /// - protected override void OnParametersSet() - { - base.OnParametersSet(); - this.ViewModel.InitializeViewModel(this.EngineeringModelSetup); - } + public IOrganizationalParticipantsTableViewModel ViewModel { get; set; } /// - /// Method invoked when creating a new thing + /// Method invoked to "Show/Hide Deprecated Items" /// - /// A - protected override void CustomizeEditThing(GridCustomizeEditModelEventArgs e) + /// The + private void HighlightDefaultOrganizationRow(GridCustomizeElementEventArgs e) { - base.CustomizeEditThing(e); - - var dataItem = (OrganizationalParticipantRowViewModel)e.DataItem; - this.ShouldCreateThing = e.IsNew; - - if (dataItem == null) + if (e.ElementType != GridElementType.DataRow) { - this.ViewModel.CurrentThing = new OrganizationalParticipant(); - e.EditModel = this.ViewModel.CurrentThing; return; } - e.EditModel = dataItem; - this.ViewModel.CurrentThing = dataItem.Thing.Clone(true); + var row = (OrganizationalParticipantRowViewModel)e.Grid.GetDataItem(e.VisibleIndex); + + if (row.Thing.Organization == this.ViewModel.CurrentModel.DefaultOrganizationalParticipant?.Organization) + { + e.CssClass = "fw-bold"; + } } } } diff --git a/COMETwebapp/Components/SiteDirectory/EngineeringModel/ParticipantsTable.razor b/COMETwebapp/Components/SiteDirectory/EngineeringModel/ParticipantsTable.razor index 1ff564ac..ed9e0c04 100644 --- a/COMETwebapp/Components/SiteDirectory/EngineeringModel/ParticipantsTable.razor +++ b/COMETwebapp/Components/SiteDirectory/EngineeringModel/ParticipantsTable.razor @@ -41,21 +41,21 @@ Copyright (c) 2023-2024 Starion Group S.A. - + - + @{ var row = (ParticipantRowViewModel)context.DataItem; } diff --git a/COMETwebapp/Components/SiteDirectory/EngineeringModel/ParticipantsTable.razor.cs b/COMETwebapp/Components/SiteDirectory/EngineeringModel/ParticipantsTable.razor.cs index 1e218b33..2877ef17 100644 --- a/COMETwebapp/Components/SiteDirectory/EngineeringModel/ParticipantsTable.razor.cs +++ b/COMETwebapp/Components/SiteDirectory/EngineeringModel/ParticipantsTable.razor.cs @@ -1,26 +1,26 @@ // -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) 2023-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 CDP4-COMET WEB Community Edition -// The CDP4-COMET WEB Community Edition is the Starion 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.SiteDirectory.EngineeringModel { @@ -35,21 +35,15 @@ namespace COMETwebapp.Components.SiteDirectory.EngineeringModel using Microsoft.AspNetCore.Components; /// - /// Support class for the + /// Support class for the /// public partial class ParticipantsTable : SelectedDataItemBase { /// /// The for this component /// - [Inject] - public IParticipantsTableViewModel ViewModel { get; set; } - - /// - /// Gets or sets the - /// [Parameter] - public EngineeringModelSetup EngineeringModelSetup { get; set; } + public IParticipantsTableViewModel ViewModel { get; set; } /// /// Gets or sets the active domains details text @@ -57,20 +51,11 @@ public partial class ParticipantsTable : SelectedDataItemBase - /// Gets the available persons. If the user is editing an existing participant, only the selected person should be retrieved + /// Gets the available persons. If the user is editing an existing participant, only the selected person should be + /// retrieved /// private IEnumerable Persons => this.ShouldCreateThing ? this.ViewModel.Persons : [this.ViewModel.CurrentThing.Person]; - /// - /// Method invoked when the component has received parameters from its parent in - /// the render tree, and the incoming values have been assigned to properties. - /// - protected override void OnParametersSet() - { - base.OnParametersSet(); - this.ViewModel.InitializeViewModel(this.EngineeringModelSetup); - } - /// /// Method that is invoked when the edit/add thing form is being saved /// @@ -90,15 +75,7 @@ protected override void CustomizeEditThing(GridCustomizeEditModelEventArgs e) var dataItem = (ParticipantRowViewModel)e.DataItem; this.ShouldCreateThing = e.IsNew; - - if (dataItem == null) - { - this.ViewModel.CurrentThing = new Participant(); - e.EditModel = this.ViewModel.CurrentThing; - return; - } - - this.ViewModel.CurrentThing = dataItem.Thing; + this.ViewModel.CurrentThing = dataItem == null ? new Participant() : dataItem.Thing.Clone(true); e.EditModel = this.ViewModel.CurrentThing; } @@ -108,14 +85,14 @@ protected override void CustomizeEditThing(GridCustomizeEditModelEventArgs e) /// The text to show inside the popup private void OpenAssignedDomainDetailsPopup(string text) { - this.AssignedDomainsPopupText = text; + this.AssignedDomainsPopupText = text; this.IsOnEditMode = true; } /// - /// Sets the selected values for the creation and submits the form + /// Sets the selected values for the creation and submits the form /// - /// A + /// A private async Task SetSelectedValuesAndSubmit() { this.ViewModel.UpdateSelectedDomains(); diff --git a/COMETwebapp/Extensions/ServiceCollectionExtensions.cs b/COMETwebapp/Extensions/ServiceCollectionExtensions.cs index 4d658feb..e78c5b4c 100644 --- a/COMETwebapp/Extensions/ServiceCollectionExtensions.cs +++ b/COMETwebapp/Extensions/ServiceCollectionExtensions.cs @@ -107,8 +107,6 @@ public static void RegisterViewModels(this IServiceCollection serviceCollection) serviceCollection.AddTransient(); serviceCollection.AddTransient(); serviceCollection.AddTransient(); - serviceCollection.AddTransient(); - serviceCollection.AddTransient(); serviceCollection.AddTransient(); serviceCollection.AddTransient(); serviceCollection.AddTransient(); diff --git a/COMETwebapp/ViewModels/Components/Common/BaseDataItemTable/BaseDataItemTableViewModel.cs b/COMETwebapp/ViewModels/Components/Common/BaseDataItemTable/BaseDataItemTableViewModel.cs index 9db1ea53..25e50152 100644 --- a/COMETwebapp/ViewModels/Components/Common/BaseDataItemTable/BaseDataItemTableViewModel.cs +++ b/COMETwebapp/ViewModels/Components/Common/BaseDataItemTable/BaseDataItemTableViewModel.cs @@ -168,7 +168,7 @@ protected override Task OnThingChanged() ///
/// The value to check if the thing was created /// The message - protected NotificationDescription GetNotificationDescription(bool created) + protected virtual NotificationDescription GetNotificationDescription(bool created) { var notificationDescription = new NotificationDescription { diff --git a/COMETwebapp/ViewModels/Components/Common/DeletableDataItemTable/DeletableDataItemTableViewModel.cs b/COMETwebapp/ViewModels/Components/Common/DeletableDataItemTable/DeletableDataItemTableViewModel.cs index 5722bee3..279a6875 100644 --- a/COMETwebapp/ViewModels/Components/Common/DeletableDataItemTable/DeletableDataItemTableViewModel.cs +++ b/COMETwebapp/ViewModels/Components/Common/DeletableDataItemTable/DeletableDataItemTableViewModel.cs @@ -24,8 +24,6 @@ namespace COMETwebapp.ViewModels.Components.Common.DeletableDataItemTable { - using AntDesign; - using CDP4Common.CommonData; using CDP4Dal; @@ -72,7 +70,7 @@ public bool IsOnDeletionMode /// /// Gets or sets the popup message dialog /// - public string PopupDialog { get; set; } + public string PopupDialog => $"You are about to delete the {typeof(T).Name}: {this.CurrentThing.GetShortNameOrName()}"; /// /// Method invoked when confirming the deletion of the current thing @@ -99,7 +97,6 @@ public void OnCancelPopupButtonClick() public void OnDeleteButtonClick(TRow thingRow) { this.CurrentThing = thingRow.Thing; - this.PopupDialog = $"You are about to delete the {typeof(T).Name}: {thingRow.Name}"; this.IsOnDeletionMode = true; } @@ -109,23 +106,27 @@ public void OnDeleteButtonClick(TRow thingRow) /// A public async Task DeleteThing() { - var clonedContainer = this.CurrentThing.Container.Clone(false); - try { + this.IsLoading = true; + var clonedContainer = this.CurrentThing.Container.Clone(false); await this.SessionService.DeleteThingsWithNotification(clonedContainer, [this.CurrentThing.Clone(false)], this.GetDeletionNotificationDescription()); } catch (Exception exception) { this.Logger.LogError(exception, "An error has occurred while trying to delete the {thingType} with iid {thingIid}", typeof(T), this.CurrentThing.Iid); } + finally + { + this.IsLoading = false; + } } /// /// Gets the message for the success notification /// /// The message - protected NotificationDescription GetDeletionNotificationDescription() + protected virtual NotificationDescription GetDeletionNotificationDescription() { var notificationDescription = new NotificationDescription() { diff --git a/COMETwebapp/ViewModels/Components/Common/DeletableDataItemTable/IDeletableDataItemTableViewModel.cs b/COMETwebapp/ViewModels/Components/Common/DeletableDataItemTable/IDeletableDataItemTableViewModel.cs index cd3ed083..fa63eae2 100644 --- a/COMETwebapp/ViewModels/Components/Common/DeletableDataItemTable/IDeletableDataItemTableViewModel.cs +++ b/COMETwebapp/ViewModels/Components/Common/DeletableDataItemTable/IDeletableDataItemTableViewModel.cs @@ -39,7 +39,7 @@ public interface IDeletableDataItemTableViewModel : IBaseDataItemTableV /// /// Gets or sets the popup message dialog /// - string PopupDialog { get; set; } + string PopupDialog { get; } /// /// Method invoked when confirming the deletion of the diff --git a/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/ActiveDomainsTableViewModel.cs b/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/ActiveDomainsTableViewModel.cs deleted file mode 100644 index 176119c2..00000000 --- a/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/ActiveDomainsTableViewModel.cs +++ /dev/null @@ -1,131 +0,0 @@ -// -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) 2023-2024 Starion Group S.A. -// -// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Antoine Théate, João Rua -// -// This file is part of CDP4-COMET WEB Community Edition -// The CDP4-COMET WEB Community Edition is the Starion 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 -// 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.ViewModels.Components.SiteDirectory.EngineeringModels -{ - using CDP4Common.EngineeringModelData; - using CDP4Common.SiteDirectoryData; - - using CDP4Dal; - - using COMET.Web.Common.Model; - using COMET.Web.Common.Services.SessionManagement; - - using COMETwebapp.ViewModels.Components.Common.BaseDataItemTable; - using COMETwebapp.ViewModels.Components.SiteDirectory.Rows; - - /// - /// View model used to manage active related to an engineering model - /// - public class ActiveDomainsTableViewModel : BaseDataItemTableViewModel, IActiveDomainsTableViewModel - { - /// - /// Gets or sets the current - /// - private EngineeringModelSetup CurrentModel { get; set; } - - /// - /// Initializes a new instance of the class. - /// - /// The - /// The - /// The - public ActiveDomainsTableViewModel(ISessionService sessionService, ICDPMessageBus messageBus, ILogger logger) - : base(sessionService, messageBus, logger) - { - } - - /// - /// Gets a collection of all the available s - /// - public IEnumerable DomainsOfExpertise => this.SessionService.GetSiteDirectory().Domain; - - /// - /// Gets or sets a collection of all the selected active s for the engineering model - /// - public IEnumerable SelectedDomainsOfExpertise { get; set; } - - /// - /// Initializes the - /// - /// The to get its active domains - public void InitializeViewModel(EngineeringModelSetup model) - { - this.CurrentModel = model; - this.ResetSelectedDomainsOfExpertise(); - base.InitializeViewModel(); - } - - /// - /// Queries a list of things of the current type - /// - /// A list of things - protected override List QueryListOfThings() - { - return this.CurrentModel?.ActiveDomain; - } - - /// - /// Resets the value based on the - /// - public void ResetSelectedDomainsOfExpertise() - { - this.SelectedDomainsOfExpertise = this.CurrentModel.ActiveDomain; - } - - /// - /// Edit the active domains related with the , using the - /// - /// A - public async Task EditActiveDomains() - { - if (this.CurrentModel.ActiveDomain.SequenceEqual(this.SelectedDomainsOfExpertise)) - { - return; - } - - this.IsLoading = true; - - try - { - var modelClone = this.CurrentModel.Clone(false); - modelClone.ActiveDomain = this.SelectedDomainsOfExpertise.ToList(); - - var notificationDescription = new NotificationDescription() - { - OnSuccess = $"The ActiveDomains from {nameof(EngineeringModel)} {this.CurrentModel.ShortName} were updated", - OnError = $"Error while updating the ActiveDomains from {nameof(EngineeringModel)}" - }; - - await this.SessionService.CreateOrUpdateThingsWithNotification(modelClone.Container.Clone(false), [modelClone], notificationDescription); - } - catch (Exception ex) - { - this.Logger.LogError(ex, "An error has occurred while saving the active domains"); - } - - this.IsLoading = false; - } - } -} diff --git a/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/EngineeringModelsTableViewModel.cs b/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/EngineeringModelsTableViewModel.cs index f1e76ec1..22c0b7c0 100644 --- a/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/EngineeringModelsTableViewModel.cs +++ b/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/EngineeringModelsTableViewModel.cs @@ -25,39 +25,75 @@ namespace COMETwebapp.ViewModels.Components.SiteDirectory.EngineeringModels { using CDP4Common.CommonData; + using CDP4Common.EngineeringModelData; using CDP4Common.SiteDirectoryData; using CDP4Dal; using COMET.Web.Common.Services.SessionManagement; + using COMET.Web.Common.ViewModels.Components.Applications; using COMETwebapp.ViewModels.Components.Common.BaseDataItemTable; using COMETwebapp.ViewModels.Components.Common.DeletableDataItemTable; using COMETwebapp.ViewModels.Components.ReferenceData.ParameterTypes; using COMETwebapp.ViewModels.Components.SiteDirectory.Rows; + using ReactiveUI; + /// /// View model used to manage /// public class EngineeringModelsTableViewModel : DeletableDataItemTableViewModel, IEngineeringModelsTableViewModel { + /// + /// Backing field for the property + /// + private SiteReferenceDataLibrary selectedSiteRdl; + + /// + /// Backing field for the property + /// + private EngineeringModelSetup selectedSourceModel; + /// /// Initializes a new instance of the class. /// /// The /// The /// The - public EngineeringModelsTableViewModel(ISessionService sessionService, ICDPMessageBus messageBus, ILogger logger) - : base(sessionService, messageBus, logger) + /// The + /// The + public EngineeringModelsTableViewModel(ISessionService sessionService, ICDPMessageBus messageBus, ILogger logger, IOrganizationalParticipantsTableViewModel organizationalParticipantsTableViewModel, + IParticipantsTableViewModel participantsTableViewModel) : base(sessionService, messageBus, logger) { + this.OrganizationalParticipantsTableViewModel = organizationalParticipantsTableViewModel; + this.ParticipantsTableViewModel = participantsTableViewModel; this.CurrentThing = new EngineeringModelSetup(); + + this.Disposables.Add(this.WhenAnyValue(x => x.SelectedSiteRdl).Subscribe(this.OnSelectedSiteRdlChanged)); + this.Disposables.Add(this.WhenAnyValue(x => x.SelectedSourceModel).Subscribe(this.OnSelectedSourceModelChanged)); } + /// + /// Gets the + /// + public IOrganizationalParticipantsTableViewModel OrganizationalParticipantsTableViewModel { get; } + + /// + /// Gets the + /// + public IParticipantsTableViewModel ParticipantsTableViewModel { get; } + /// /// Gets a collection of the available engineering models /// public IEnumerable EngineeringModels { get; private set; } + /// + /// Gets a collection of the available s + /// + public IEnumerable IterationRows { get; private set; } + /// /// Gets a collection of all the possible model kinds /// @@ -86,12 +122,11 @@ public EngineeringModelsTableViewModel(ISessionService sessionService, ICDPMessa /// /// Gets or sets the selected site reference data library /// - public SiteReferenceDataLibrary SelectedSiteRdl { get; set; } - - /// - /// Gets or sets the collection of selected active domains - /// - public IEnumerable SelectedActiveDomains { get; set; } = Enumerable.Empty(); + public SiteReferenceDataLibrary SelectedSiteRdl + { + get => this.selectedSiteRdl; + set => this.RaiseAndSetIfChanged(ref this.selectedSiteRdl, value); + } /// /// Gets or sets the collection of selected organizations @@ -106,7 +141,11 @@ public EngineeringModelsTableViewModel(ISessionService sessionService, ICDPMessa /// /// Gets or sets the selected source /// - public EngineeringModelSetup SelectedSourceModel { get; set; } + public EngineeringModelSetup SelectedSourceModel + { + get => this.selectedSourceModel; + set => this.RaiseAndSetIfChanged(ref this.selectedSourceModel, value); + } /// /// Initializes the @@ -116,10 +155,14 @@ public override void InitializeViewModel() base.InitializeViewModel(); var siteDirectory = this.SessionService.GetSiteDirectory(); - this.EngineeringModels = siteDirectory.Model.OrderBy(x => x.Name); - this.SiteRdls = siteDirectory.SiteReferenceDataLibrary.OrderBy(x => x.Name); - this.DomainsOfExpertise = siteDirectory.Domain.OrderBy(x => x.Name); - this.Organizations = siteDirectory.Organization.OrderBy(x => x.Name); + this.EngineeringModels = siteDirectory.Model.OrderBy(x => x.Name, StringComparer.InvariantCultureIgnoreCase); + this.SiteRdls = siteDirectory.SiteReferenceDataLibrary.OrderBy(x => x.Name, StringComparer.InvariantCultureIgnoreCase); + this.DomainsOfExpertise = siteDirectory.Domain.OrderBy(x => x.Name, StringComparer.InvariantCultureIgnoreCase); + this.Organizations = siteDirectory.Organization.OrderBy(x => x.Name, StringComparer.InvariantCultureIgnoreCase); + + this.IterationRows = this.SessionService.OpenIterations.Items + .Where(x => ((EngineeringModel)x.Container).EngineeringModelSetup.Iid == this.CurrentThing?.Iid) + .Select(x => new IterationRowViewModel(x)); } /// @@ -132,42 +175,86 @@ protected override List QueryListOfThings() } /// - /// Resets the selected values + /// Creates a new /// - public void ResetSelectedValues() + /// The value to check if a new should be created + /// A + public async Task CreateOrEditEngineeringModel(bool shouldCreate) { - this.SelectedActiveDomains = Enumerable.Empty(); - this.SelectedOrganizations = Enumerable.Empty(); - this.SelectedModelAdminOrganization = null; - this.SelectedSiteRdl = null; - this.SelectedSourceModel = null; + try + { + this.IsLoading = true; + + var siteDirectoryClone = this.SessionService.GetSiteDirectory().Clone(false); + var thingsToCreate = new List(); + this.CurrentThing.EngineeringModelIid = Guid.NewGuid(); + + if (shouldCreate) + { + siteDirectoryClone.Model.Add(this.CurrentThing); + thingsToCreate.Add(siteDirectoryClone); + + if (this.CurrentThing.SourceEngineeringModelSetupIid != null) + { + this.CurrentThing.RequiredRdl.Clear(); + } + else + { + thingsToCreate.AddRange(this.CurrentThing.RequiredRdl); + } + } + + if (this.CurrentThing.OrganizationalParticipant.Count > 0) + { + thingsToCreate.AddRange(this.CurrentThing.OrganizationalParticipant); + } + + thingsToCreate.Add(this.CurrentThing); + await this.SessionService.CreateOrUpdateThingsWithNotification(siteDirectoryClone, thingsToCreate, this.GetNotificationDescription(shouldCreate)); + + if (this.CurrentThing.Original is EngineeringModelSetup originalModel) + { + this.CurrentThing = originalModel.Clone(true); + } + } + catch (Exception ex) + { + this.Logger.LogError(ex, "Create or Update EngineeringModelSetup failed"); + } + finally + { + this.IsLoading = false; + } } /// - /// Updates the current thing with the selected properties + /// Update this view model properties when the has + /// changed /// - public void SetupEngineeringModelWithSelectedValues() + /// A + protected override Task OnThingChanged() { - this.CurrentThing.ActiveDomain = this.SelectedActiveDomains?.ToList(); - this.CurrentThing.SourceEngineeringModelSetupIid = this.SelectedSourceModel?.Iid; - this.CurrentThing.OrganizationalParticipant.Clear(); - this.CurrentThing.RequiredRdl.Clear(); + this.SelectedSiteRdl = this.CurrentThing.RequiredRdl.FirstOrDefault()?.RequiredRdl; + this.SelectedSourceModel = this.Rows.Items.FirstOrDefault(x => x.Thing.Iid == this.CurrentThing.SourceEngineeringModelSetupIid)?.Thing; + this.OrganizationalParticipantsTableViewModel.InitializeViewModel(this.CurrentThing); + this.ParticipantsTableViewModel.InitializeViewModel(this.CurrentThing); - if (this.SelectedOrganizations != null) - { - this.CurrentThing.OrganizationalParticipant.AddRange(this.SelectedOrganizations.Select(org => new OrganizationalParticipant() - { - Organization = org - })); + return Task.CompletedTask; + } - this.CurrentThing.DefaultOrganizationalParticipant = this.CurrentThing.OrganizationalParticipant.FirstOrDefault(x => x.Organization == this.SelectedModelAdminOrganization); - } + /// + /// Method invoked every time the property has changed, synchronizing with the + /// + /// The updated + private void OnSelectedSiteRdlChanged(SiteReferenceDataLibrary siteRdl) + { + this.CurrentThing.RequiredRdl.Clear(); - if (this.SelectedSiteRdl != null) + if (siteRdl != null) { this.CurrentThing.RequiredRdl.Add(new ModelReferenceDataLibrary() { - RequiredRdl = this.SelectedSiteRdl, + RequiredRdl = siteRdl, Name = $"{this.CurrentThing.Name} Model RDL", ShortName = $"{this.CurrentThing.ShortName}MRDL" }); @@ -175,34 +262,12 @@ public void SetupEngineeringModelWithSelectedValues() } /// - /// Creates a new + /// Method invoked every time the property has changed, synchronizing with the /// - /// A - public async Task CreateEngineeringModel() + /// The updated + private void OnSelectedSourceModelChanged(EngineeringModelSetup sourceModel) { - this.IsLoading = true; - - var siteDirectoryClone = this.SessionService.GetSiteDirectory().Clone(false); - var thingsToCreate = new List(); - this.CurrentThing.EngineeringModelIid = Guid.NewGuid(); - - if (this.CurrentThing.OrganizationalParticipant.Count > 0) - { - thingsToCreate.AddRange(this.CurrentThing.OrganizationalParticipant); - } - - if (this.CurrentThing.RequiredRdl.Count > 0) - { - thingsToCreate.AddRange(this.CurrentThing.RequiredRdl); - } - - siteDirectoryClone.Model.Add(this.CurrentThing); - thingsToCreate.Add(siteDirectoryClone); - thingsToCreate.Add(this.CurrentThing); - - await this.SessionService.CreateOrUpdateThingsWithNotification(siteDirectoryClone, thingsToCreate, this.GetNotificationDescription(true)); - - this.IsLoading = false; + this.CurrentThing.SourceEngineeringModelSetupIid = sourceModel?.Iid; } } } diff --git a/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/IActiveDomainsTableViewModel.cs b/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/IActiveDomainsTableViewModel.cs deleted file mode 100644 index 451e4c77..00000000 --- a/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/IActiveDomainsTableViewModel.cs +++ /dev/null @@ -1,64 +0,0 @@ -// -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) 2023-2024 Starion Group S.A. -// -// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Antoine Théate, João Rua -// -// This file is part of CDP4-COMET WEB Community Edition -// The CDP4-COMET WEB Community Edition is the Starion 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 -// 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.ViewModels.Components.SiteDirectory.EngineeringModels -{ - using CDP4Common.SiteDirectoryData; - - using COMETwebapp.ViewModels.Components.Common.BaseDataItemTable; - using COMETwebapp.ViewModels.Components.SiteDirectory.Rows; - - /// - /// View model used to manage active related to an engineering model - /// - public interface IActiveDomainsTableViewModel : IBaseDataItemTableViewModel - { - /// - /// Gets a collection of all the available s - /// - IEnumerable DomainsOfExpertise { get; } - - /// - /// Gets or sets a collection of all the selected active s for the engineering model - /// - IEnumerable SelectedDomainsOfExpertise { get; set; } - - /// - /// Edit the active domains related with the , using the - /// - /// A - Task EditActiveDomains(); - - /// - /// Resets the value based on the - /// - void ResetSelectedDomainsOfExpertise(); - - /// - /// Initializes the - /// - /// The to get its active domains - void InitializeViewModel(EngineeringModelSetup model); - } -} diff --git a/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/IEngineeringModelsTableViewModel.cs b/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/IEngineeringModelsTableViewModel.cs index 9cb0aa4d..38d26e9f 100644 --- a/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/IEngineeringModelsTableViewModel.cs +++ b/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/IEngineeringModelsTableViewModel.cs @@ -74,11 +74,6 @@ public interface IEngineeringModelsTableViewModel : IDeletableDataItemTableViewM /// Organization SelectedModelAdminOrganization { get; set; } - /// - /// Gets or sets the collection of selected active domains - /// - IEnumerable SelectedActiveDomains { get; set; } - /// /// Gets or sets the selected site reference data library /// @@ -90,19 +85,25 @@ public interface IEngineeringModelsTableViewModel : IDeletableDataItemTableViewM EngineeringModelSetup SelectedSourceModel { get; set; } /// - /// Updates the current thing with the selected properties + /// Gets a collection of the available s /// - void SetupEngineeringModelWithSelectedValues(); + IEnumerable IterationRows { get; } /// - /// Creates a new + /// Gets the /// - /// A - Task CreateEngineeringModel(); + IOrganizationalParticipantsTableViewModel OrganizationalParticipantsTableViewModel { get; } /// - /// Resets the current values + /// Gets the /// - void ResetSelectedValues(); + IParticipantsTableViewModel ParticipantsTableViewModel { get; } + + /// + /// Creates a new + /// + /// The value to check if a new should be created + /// A + Task CreateOrEditEngineeringModel(bool shouldCreate); } } diff --git a/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/IIterationsTableViewModel.cs b/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/IIterationsTableViewModel.cs deleted file mode 100644 index 2cb89ee2..00000000 --- a/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/IIterationsTableViewModel.cs +++ /dev/null @@ -1,44 +0,0 @@ -// -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) 2023-2024 Starion Group S.A. -// -// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Antoine Théate, João Rua -// -// This file is part of CDP4-COMET WEB Community Edition -// The CDP4-COMET WEB Community Edition is the Starion 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 -// 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.ViewModels.Components.SiteDirectory.EngineeringModels -{ - using CDP4Common.EngineeringModelData; - using CDP4Common.SiteDirectoryData; - - using COMETwebapp.ViewModels.Components.Common.BaseDataItemTable; - using COMETwebapp.ViewModels.Components.SiteDirectory.Rows; - - /// - /// View model used to list s - /// - public interface IIterationsTableViewModel : IBaseDataItemTableViewModel - { - /// - /// Initializes the - /// - /// The to get its participants - void InitializeViewModel(EngineeringModelSetup model); - } -} diff --git a/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/IOrganizationalParticipantsTableViewModel.cs b/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/IOrganizationalParticipantsTableViewModel.cs index d6bab280..26ac752b 100644 --- a/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/IOrganizationalParticipantsTableViewModel.cs +++ b/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/IOrganizationalParticipantsTableViewModel.cs @@ -45,6 +45,11 @@ public interface IOrganizationalParticipantsTableViewModel : IDeletableDataItemT /// IEnumerable ParticipatingOrganizations { get; set; } + /// + /// Gets the current + /// + EngineeringModelSetup CurrentModel { get; } + /// /// Initializes the /// diff --git a/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/IterationsTableViewModel.cs b/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/IterationsTableViewModel.cs deleted file mode 100644 index 64caf50c..00000000 --- a/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/IterationsTableViewModel.cs +++ /dev/null @@ -1,77 +0,0 @@ -// -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) 2023-2024 Starion Group S.A. -// -// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Antoine Théate, João Rua -// -// This file is part of CDP4-COMET WEB Community Edition -// The CDP4-COMET WEB Community Edition is the Starion 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 -// 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.ViewModels.Components.SiteDirectory.EngineeringModels -{ - using CDP4Common.EngineeringModelData; - using CDP4Common.SiteDirectoryData; - - using CDP4Dal; - - using COMET.Web.Common.Services.SessionManagement; - - using COMETwebapp.ViewModels.Components.Common.BaseDataItemTable; - using COMETwebapp.ViewModels.Components.SiteDirectory.Rows; - - /// - /// View model used to list s - /// - public class IterationsTableViewModel : BaseDataItemTableViewModel, IIterationsTableViewModel - { - /// - /// Gets or sets the current - /// - private EngineeringModelSetup CurrentModel { get; set; } - - /// - /// Initializes a new instance of the class. - /// - /// The - /// The - /// The - public IterationsTableViewModel(ISessionService sessionService, ICDPMessageBus messageBus, ILogger logger) - : base(sessionService, messageBus, logger) - { - } - - /// - /// Initializes the - /// - /// The to get its participants - public void InitializeViewModel(EngineeringModelSetup model) - { - this.CurrentModel = model; - base.InitializeViewModel(); - } - - /// - /// Queries a list of things of the current type - /// - /// A list of things - protected override List QueryListOfThings() - { - return this.SessionService.OpenIterations.Items.Where(x => ((EngineeringModel)x.Container).EngineeringModelSetup.Iid == this.CurrentModel?.Iid).ToList(); - } - } -} diff --git a/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/OrganizationalParticipantsTableViewModel.cs b/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/OrganizationalParticipantsTableViewModel.cs index 541b4c47..54edcb5f 100644 --- a/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/OrganizationalParticipantsTableViewModel.cs +++ b/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/OrganizationalParticipantsTableViewModel.cs @@ -1,26 +1,26 @@ // -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) 2023-2024 Starion Group S.A. -// -// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Antoine Théate, João Rua -// -// This file is part of CDP4-COMET WEB Community Edition -// The CDP4-COMET WEB Community Edition is the Starion 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.ViewModels.Components.SiteDirectory.EngineeringModels { @@ -34,48 +34,61 @@ namespace COMETwebapp.ViewModels.Components.SiteDirectory.EngineeringModels using COMETwebapp.ViewModels.Components.Common.DeletableDataItemTable; using COMETwebapp.ViewModels.Components.SiteDirectory.Rows; + using DynamicData; + + using ReactiveUI; + /// /// View model used to manage /// public class OrganizationalParticipantsTableViewModel : DeletableDataItemTableViewModel, IOrganizationalParticipantsTableViewModel { /// - /// Gets or sets the current + /// Backing field for the /// - private EngineeringModelSetup CurrentModel { get; set; } + private IEnumerable participatingOrganizations; /// /// Initializes a new instance of the class. /// /// The - /// The - /// The - public OrganizationalParticipantsTableViewModel(ISessionService sessionService, ICDPMessageBus messageBus, ILogger logger) + /// The + /// The + public OrganizationalParticipantsTableViewModel(ISessionService sessionService, ICDPMessageBus messageBus, ILogger logger) : base(sessionService, messageBus, logger) { + this.Disposables.Add(this.WhenAnyValue(x => x.ParticipatingOrganizations).Subscribe(this.OnSelectedParticipantOrganizationsChanged)); } /// - /// Gets a collection of all the available s + /// Gets the current /// - public IEnumerable Organizations { get; private set; } + public EngineeringModelSetup CurrentModel { get; private set; } /// - /// Gets or sets a collection of all the participating s for the organizational participant creation + /// Gets a collection of all the available s /// - public IEnumerable ParticipatingOrganizations { get; set; } + public IEnumerable Organizations { get; set; } + + /// + /// Gets or sets a collection of all the participating s for the organizational participant + /// creation + /// + public IEnumerable ParticipatingOrganizations + { + get => this.participatingOrganizations; + set => this.RaiseAndSetIfChanged(ref this.participatingOrganizations, value); + } /// /// Initializes the /// - /// The to get its active domains + /// The to get its active domains public void InitializeViewModel(EngineeringModelSetup model) { this.CurrentModel = model; this.ParticipatingOrganizations = model.OrganizationalParticipant.Select(x => x.Organization); - this.Organizations = this.SessionService.GetSiteDirectory().Organization; - - base.InitializeViewModel(); + this.Organizations = this.SessionService.GetSiteDirectory().Organization.OrderBy(x => x.Name, StringComparer.InvariantCultureIgnoreCase); } /// @@ -84,7 +97,31 @@ public void InitializeViewModel(EngineeringModelSetup model) /// A list of things protected override List QueryListOfThings() { - return this.CurrentModel?.OrganizationalParticipant; + return []; + } + + /// + /// Method executed everytime the has changed + /// + /// The new participating organizations + private void OnSelectedParticipantOrganizationsChanged(IEnumerable organizations) + { + if (this.CurrentModel is null) + { + return; + } + + var organizationsToRemove = this.CurrentModel.OrganizationalParticipant.Where(x => !organizations.Contains(x.Organization)); + + var organizationsToAdd = organizations + .Where(x => !this.CurrentModel.OrganizationalParticipant.Select(y => y.Organization).Contains(x)) + .Select(org => new OrganizationalParticipant + { + Organization = org + }); + + this.CurrentModel.OrganizationalParticipant.RemoveMany(organizationsToRemove); + this.CurrentModel.OrganizationalParticipant.AddRange(organizationsToAdd); } } } diff --git a/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/ParticipantsTableViewModel.cs b/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/ParticipantsTableViewModel.cs index 0d79ae33..576a5708 100644 --- a/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/ParticipantsTableViewModel.cs +++ b/COMETwebapp/ViewModels/Components/SiteDirectory/EngineeringModels/ParticipantsTableViewModel.cs @@ -1,26 +1,26 @@ // -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) 2023-2024 Starion Group S.A. -// -// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Antoine Théate, João Rua -// -// This file is part of CDP4-COMET WEB Community Edition -// The CDP4-COMET WEB Community Edition is the Starion 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.ViewModels.Components.SiteDirectory.EngineeringModels { @@ -29,6 +29,8 @@ namespace COMETwebapp.ViewModels.Components.SiteDirectory.EngineeringModels using CDP4Dal; + using COMET.Web.Common.Extensions; + using COMET.Web.Common.Model; using COMET.Web.Common.Services.SessionManagement; using COMET.Web.Common.ViewModels.Components.Applications; @@ -42,7 +44,7 @@ namespace COMETwebapp.ViewModels.Components.SiteDirectory.EngineeringModels public class ParticipantsTableViewModel : DeletableDataItemTableViewModel, IParticipantsTableViewModel { /// - /// Gets or sets the current + /// Gets or sets the current /// private EngineeringModelSetup CurrentModel { get; set; } @@ -50,38 +52,38 @@ public class ParticipantsTableViewModel : DeletableDataItemTableViewModel class. /// /// The - /// The - /// The - public ParticipantsTableViewModel(ISessionService sessionService, ICDPMessageBus messageBus, ILogger logger) + /// The + /// The + public ParticipantsTableViewModel(ISessionService sessionService, ICDPMessageBus messageBus, ILogger logger) : base(sessionService, messageBus, logger) { this.CurrentThing = new Participant(); } /// - /// Gets a collection of all the available s + /// Gets a collection of all the available s /// public IEnumerable Persons { get; private set; } /// - /// Gets a collection of all the available s + /// Gets a collection of all the available s /// public IEnumerable ParticipantRoles { get; private set; } /// - /// Gets a collection of all the available s + /// Gets a collection of all the available s /// public IEnumerable DomainsOfExpertise { get; private set; } /// - /// Gets or sets a collection of all the selected s for the participant creation + /// Gets or sets a collection of all the selected s for the participant creation /// public IEnumerable SelectedDomains { get; set; } /// /// Initializes the /// - /// The to get its participants + /// The to get its participants public void InitializeViewModel(EngineeringModelSetup model) { var siteDirectory = this.SessionService.GetSiteDirectory(); @@ -94,26 +96,7 @@ public void InitializeViewModel(EngineeringModelSetup model) } /// - /// Queries a list of things of the current type - /// - /// A list of things - protected override List QueryListOfThings() - { - return this.CurrentModel?.Participant; - } - - /// - /// Update this view model properties when the has changed - /// - /// A - protected override async Task OnThingChanged() - { - await base.OnThingChanged(); - this.SelectedDomains = this.CurrentThing.Domain; - } - - /// - /// Updates the current participant domains with the + /// Updates the current participant domains with the /// public void UpdateSelectedDomains() { @@ -123,8 +106,8 @@ public void UpdateSelectedDomains() /// /// Creates or edits the current participant /// - /// The value to check if a new should be created - /// A + /// The value to check if a new should be created + /// A public async Task CreateOrEditParticipant(bool shouldCreate) { this.IsLoading = true; @@ -153,5 +136,56 @@ public async Task CreateOrEditParticipant(bool shouldCreate) this.IsLoading = false; } + + /// + /// Queries a list of things of the current type + /// + /// A list of things + protected override List QueryListOfThings() + { + return this.CurrentModel?.Participant; + } + + /// + /// Update this view model properties when the has + /// changed + /// + /// A + protected override async Task OnThingChanged() + { + await base.OnThingChanged(); + this.SelectedDomains = this.CurrentThing.Domain; + } + + /// + /// Gets the message for the success notification + /// + /// The value to check if the thing was created + /// The message + protected override NotificationDescription GetNotificationDescription(bool created) + { + var notificationDescription = new NotificationDescription + { + OnSuccess = $"The {nameof(Participant)} {this.CurrentThing.Person.GetShortNameOrName()} was {(created ? "added" : "updated")}", + OnError = $"Error while {(created ? "adding" : "updating")} the {nameof(Participant)} {this.CurrentThing.Person.GetShortNameOrName()}" + }; + + return notificationDescription; + } + + /// + /// Gets the message for the success notification + /// + /// The message + protected override NotificationDescription GetDeletionNotificationDescription() + { + var notificationDescription = new NotificationDescription + { + OnSuccess = $"The {nameof(Participant)} {this.CurrentThing.Person.GetShortNameOrName()} was deleted!", + OnError = $"Error while deleting The {nameof(Participant)} {this.CurrentThing.Person.GetShortNameOrName()}" + }; + + return notificationDescription; + } } }