From 1847095aa0862f677a6bf9f9ab7d9370d0ced44a Mon Sep 17 00:00:00 2001 From: Joao Rua Date: Wed, 17 Apr 2024 11:25:06 +0100 Subject: [PATCH] site directory renamed to server administration + user managment refactored and moved to server administration page --- .../MeasurementScalesTableTestFixture.cs | 1 - .../UserManagementTableTestFixture.cs | 83 ++-- .../Model/ApplicationsTestFixture.cs | 2 +- .../SiteDirectory/OrganizationsTable.razor.cs | 3 +- .../UserManagementTable.razor | 52 ++- .../UserManagementTable.razor.cs | 117 ++++++ .../UserManagementTable.razor.css | 0 .../UserManagementTable.razor.cs | 201 ---------- .../Extensions/ServiceCollectionExtensions.cs | 2 +- COMETwebapp/Model/Applications.cs | 10 +- .../SiteDirectory/DirectoryPage.razor.cs | 1 + .../UserManagement/UserManagementPage.razor | 26 -- COMETwebapp/Utilities/WebAppConstantValues.cs | 5 - .../BaseDataItemTableViewModel.cs | 16 +- .../Rows/PersonRowViewModel.cs | 90 +---- .../IUserManagementTableViewModel.cs | 88 +---- .../UserManagementTableViewModel.cs | 207 ++++++++++ .../UserManagementTableViewModel.cs | 370 ------------------ COMETwebapp/_Imports.razor | 1 - 19 files changed, 426 insertions(+), 849 deletions(-) rename COMETwebapp.Tests/Components/{UserManagement => SiteDirectory}/UserManagementTableTestFixture.cs (88%) rename COMETwebapp/Components/{UserManagement => SiteDirectory}/UserManagementTable.razor (85%) create mode 100644 COMETwebapp/Components/SiteDirectory/UserManagementTable.razor.cs rename COMETwebapp/Components/{UserManagement => SiteDirectory}/UserManagementTable.razor.css (100%) delete mode 100644 COMETwebapp/Components/UserManagement/UserManagementTable.razor.cs delete mode 100644 COMETwebapp/Pages/UserManagement/UserManagementPage.razor rename COMETwebapp/ViewModels/Components/{UserManagement => SiteDirectory}/Rows/PersonRowViewModel.cs (59%) rename COMETwebapp/ViewModels/Components/{ => SiteDirectory}/UserManagement/IUserManagementTableViewModel.cs (51%) create mode 100644 COMETwebapp/ViewModels/Components/SiteDirectory/UserManagement/UserManagementTableViewModel.cs delete mode 100644 COMETwebapp/ViewModels/Components/UserManagement/UserManagementTableViewModel.cs diff --git a/COMETwebapp.Tests/Components/ReferenceData/MeasurementScalesTableTestFixture.cs b/COMETwebapp.Tests/Components/ReferenceData/MeasurementScalesTableTestFixture.cs index 294cdb04..f170ca0a 100644 --- a/COMETwebapp.Tests/Components/ReferenceData/MeasurementScalesTableTestFixture.cs +++ b/COMETwebapp.Tests/Components/ReferenceData/MeasurementScalesTableTestFixture.cs @@ -35,7 +35,6 @@ namespace COMETwebapp.Tests.Components.ReferenceData using COMETwebapp.Components.ReferenceData; using COMETwebapp.Services.ShowHideDeprecatedThingsService; - using COMETwebapp.ViewModels.Components.ReferenceData; using COMETwebapp.ViewModels.Components.ReferenceData.MeasurementScales; using COMETwebapp.ViewModels.Components.ReferenceData.Rows; diff --git a/COMETwebapp.Tests/Components/UserManagement/UserManagementTableTestFixture.cs b/COMETwebapp.Tests/Components/SiteDirectory/UserManagementTableTestFixture.cs similarity index 88% rename from COMETwebapp.Tests/Components/UserManagement/UserManagementTableTestFixture.cs rename to COMETwebapp.Tests/Components/SiteDirectory/UserManagementTableTestFixture.cs index 16bd6cf7..65d3598e 100644 --- a/COMETwebapp.Tests/Components/UserManagement/UserManagementTableTestFixture.cs +++ b/COMETwebapp.Tests/Components/SiteDirectory/UserManagementTableTestFixture.cs @@ -22,8 +22,7 @@ // // -------------------------------------------------------------------------------------------------------------------- -#pragma warning disable BL0005 -namespace COMETwebapp.Tests.Components.UserManagement +namespace COMETwebapp.Tests.Components.SiteDirectory { using System.Collections.Concurrent; @@ -32,6 +31,7 @@ namespace COMETwebapp.Tests.Components.UserManagement using CDP4Common.CommonData; using CDP4Common.EngineeringModelData; using CDP4Common.SiteDirectoryData; + using CDP4Common.Types; using CDP4Dal; using CDP4Dal.DAL; @@ -44,13 +44,14 @@ namespace COMETwebapp.Tests.Components.UserManagement using COMET.Web.Common.Services.SessionManagement; using COMET.Web.Common.Test.Helpers; - using COMETwebapp.Components.UserManagement; + using COMETwebapp.Components.SiteDirectory; using COMETwebapp.Services.ShowHideDeprecatedThingsService; - using COMETwebapp.ViewModels.Components.UserManagement; + using COMETwebapp.ViewModels.Components.SiteDirectory.UserManagement; using DevExpress.Blazor; using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Logging; using Moq; @@ -62,8 +63,9 @@ namespace COMETwebapp.Tests.Components.UserManagement public class UserManagementTableTestFixture { private TestContext context; - private IUserManagementTableViewModel viewModel; + private UserManagementTableViewModel viewModel; private Mock session; + private Mock> logger; private Mock permissionService; private Mock sessionService; private Mock showHideDeprecatedThingsService; @@ -88,30 +90,23 @@ public void SetUp() this.session = new Mock(); this.sessionService = new Mock(); + this.logger = new Mock>(); this.showHideDeprecatedThingsService = new Mock(); - this.sessionService.Setup(x => x.Session).Returns(this.session.Object); + this.sessionService.Setup(x => x.Session).Returns(this.session.Object); this.permissionService = new Mock(); this.permissionService.Setup(x => x.CanWrite(It.IsAny())).Returns(true); this.permissionService.Setup(x => x.CanWrite(It.IsAny(), It.IsAny())).Returns(true); - - this.showHideDeprecatedThingsService.Setup(x => x.ShowDeprecatedThings).Returns(true); - this.session.Setup(x => x.PermissionService).Returns(this.permissionService.Object); + this.showHideDeprecatedThingsService.Setup(x => x.ShowDeprecatedThings).Returns(true); - this.context.Services.AddSingleton(this.sessionService); - this.context.ConfigureDevExpressBlazor(); var configuration = new Mock(); configuration.Setup(x => x.ServerConfiguration).Returns(new ServerConfiguration()); - this.context.Services.AddSingleton(configuration.Object); this.messageBus = new CDPMessageBus(); this.assembler = new Assembler(this.uri, this.messageBus); this.domain = new DomainOfExpertise(Guid.NewGuid(), this.assembler.Cache, this.uri); - - this.viewModel = new UserManagementTableViewModel(this.sessionService.Object, this.showHideDeprecatedThingsService.Object, this.messageBus); - - this.context.Services.AddSingleton(this.viewModel); + this.viewModel = new UserManagementTableViewModel(this.sessionService.Object, this.showHideDeprecatedThingsService.Object, this.messageBus, this.logger.Object); this.person = new Person(Guid.NewGuid(), this.assembler.Cache, this.uri) { @@ -239,6 +234,9 @@ public void SetUp() Model = { this.engineeringSetup } }; + this.assembler.Cache.TryAdd(new CacheKey(Guid.NewGuid(), null), new Lazy(this.person)); + this.assembler.Cache.TryAdd(new CacheKey(Guid.NewGuid(), null), new Lazy(this.person1)); + this.siteDirectory.Person.Add(this.person); this.siteDirectory.Person.Add(this.person1); this.siteDirectory.Domain.Add(this.domain); @@ -249,6 +247,11 @@ public void SetUp() this.session.Setup(x => x.Credentials).Returns(new Credentials("admin", "pass", this.uri)); this.session.Setup(x => x.RetrieveSiteDirectory()).Returns(this.siteDirectory); this.session.Setup(x => x.ActivePerson).Returns(this.person); + + this.context.Services.AddSingleton(this.viewModel); + this.context.Services.AddSingleton(this.sessionService); + this.context.Services.AddSingleton(configuration.Object); + this.context.ConfigureDevExpressBlazor(); } [TearDown] @@ -256,6 +259,7 @@ public void Teardown() { this.context.CleanContext(); this.messageBus.ClearSubscriptions(); + this.viewModel.Dispose(); } [Test] @@ -279,19 +283,19 @@ public async Task VerifyComponent() Assert.Multiple(() => { - Assert.That(this.viewModel.Person.Name?.Trim(), Is.Empty); - Assert.That(this.viewModel.ShouldCreatePerson, Is.EqualTo(true)); + Assert.That(this.viewModel.Thing.Name?.Trim(), Is.Empty); + Assert.That(renderer.Instance.ShouldCreateThing, Is.EqualTo(true)); }); await renderer.InvokeAsync(grid.Instance.EditModelSaving.InvokeAsync); - this.sessionService.Verify(x => x.UpdateThings(It.IsAny(), It.Is>(c => c.Contains(this.viewModel.Person))), Times.Once); + this.sessionService.Verify(x => x.UpdateThings(It.IsAny(), It.Is>(c => c.Contains(this.viewModel.Thing))), Times.Once); await grid.InvokeAsync(editPersonButton.Instance.Click.InvokeAsync); Assert.Multiple(() => { - Assert.That(this.viewModel.Person.Name, Is.EqualTo(this.viewModel.Rows.Items.First().PersonName)); - Assert.That(this.viewModel.ShouldCreatePerson, Is.EqualTo(false)); + Assert.That(this.viewModel.Thing.Name, Is.EqualTo(this.viewModel.Rows.Items.First().Name)); + Assert.That(renderer.Instance.ShouldCreateThing, Is.EqualTo(false)); }); await renderer.InvokeAsync(grid.Instance.EditModelSaving.InvokeAsync); @@ -315,14 +319,12 @@ public async Task VerifyActivatingPerson() Assert.Multiple(() => { - Assert.That(checkBox.Instance.Checked, Is.True); Assert.That(renderer.Markup, Does.Contain(this.person.Name)); Assert.That(renderer.Markup, Does.Contain(this.person1.Name)); }); - await renderer.InvokeAsync(() => checkBox.Instance.Checked = false); - - Assert.Multiple(() => { Assert.That(checkBox.Instance.Checked, Is.False); }); + await renderer.InvokeAsync(() => checkBox.Instance.CheckedChanged.InvokeAsync(false)); + this.sessionService.Verify(x => x.UpdateThings(It.IsAny(), It.IsAny()), Times.Once); } [Test] @@ -341,7 +343,7 @@ public async Task VerifyAddingOrEditingPerson() Assert.That(renderer.Markup, Does.Contain(this.person1.Name)); }); - this.viewModel.Person = new Person + this.viewModel.Thing = new Person { GivenName = "Test", Surname = "Test", @@ -352,8 +354,8 @@ public async Task VerifyAddingOrEditingPerson() TelephoneNumber = { new TelephoneNumber() } }; - await this.viewModel.CreateOrEditPerson(); - this.messageBus.SendMessage(new ObjectChangedEvent(this.viewModel.Person, EventKind.Added)); + await this.viewModel.CreateOrEditPerson(true); + this.messageBus.SendMessage(new ObjectChangedEvent(this.viewModel.Thing, EventKind.Added)); Assert.Multiple(() => { @@ -364,7 +366,7 @@ public async Task VerifyAddingOrEditingPerson() [Test] public async Task VerifyDeprecatingPerson() - { + { var renderer = this.context.RenderComponent(); Assert.Multiple(() => @@ -375,7 +377,7 @@ public async Task VerifyDeprecatingPerson() }); var deprecateButton = renderer.FindComponents().First(x => x.Instance.Id == "deprecateButton"); - var currentPerson = this.viewModel.Person; + var currentPerson = this.viewModel.Thing; Assert.That(this.viewModel.IsOnDeprecationMode, Is.False); @@ -384,12 +386,12 @@ public async Task VerifyDeprecatingPerson() Assert.Multiple(() => { Assert.That(this.viewModel.IsOnDeprecationMode, Is.True); - Assert.That(this.viewModel.Person, Is.Not.EqualTo(currentPerson)); + Assert.That(this.viewModel.Thing, Is.Not.EqualTo(currentPerson)); }); - this.viewModel.Person = this.person; + this.viewModel.Thing = this.person; - await this.viewModel.OnConfirmButtonClick(); + await this.viewModel.OnConfirmPopupButtonClick(); Assert.That(this.viewModel.IsOnDeprecationMode, Is.False); } @@ -420,7 +422,7 @@ public async Task VerifyUnDeprecatingPerson() }); var undeprecateButton = renderer.FindComponents().First(x => x.Instance.Id == "undeprecateButton"); - var currentPerson = this.viewModel.Person; + var currentPerson = this.viewModel.Thing; Assert.That(this.viewModel.IsOnDeprecationMode, Is.False); @@ -429,12 +431,12 @@ public async Task VerifyUnDeprecatingPerson() Assert.Multiple(() => { Assert.That(this.viewModel.IsOnDeprecationMode, Is.True); - Assert.That(this.viewModel.Person, Is.Not.EqualTo(currentPerson)); + Assert.That(this.viewModel.Thing, Is.Not.EqualTo(currentPerson)); }); - this.viewModel.Person = this.person1; + this.viewModel.Thing = this.person1; - await this.viewModel.OnConfirmButtonClick(); + await this.viewModel.OnConfirmPopupButtonClick(); Assert.That(this.viewModel.IsOnDeprecationMode, Is.False); } @@ -449,16 +451,17 @@ public void VerifyRecordChange() var personTest = new Person() { - Iid = Guid.NewGuid() + Iid = Guid.NewGuid(), + Container = this.siteDirectory }; this.messageBus.SendObjectChangeEvent(personTest, EventKind.Added); this.messageBus.SendMessage(SessionStateKind.RefreshEnded); - this.messageBus.SendObjectChangeEvent(this.viewModel.Rows.Items.First().Person, EventKind.Removed); + this.messageBus.SendObjectChangeEvent(this.viewModel.Rows.Items.First().Thing, EventKind.Removed); this.messageBus.SendMessage(SessionStateKind.RefreshEnded); - this.messageBus.SendObjectChangeEvent(this.viewModel.Rows.Items.First().Person, EventKind.Updated); + this.messageBus.SendObjectChangeEvent(this.viewModel.Rows.Items.First().Thing, EventKind.Updated); this.messageBus.SendMessage(SessionStateKind.RefreshEnded); Assert.That(this.viewModel.Rows, Has.Count.EqualTo(2)); diff --git a/COMETwebapp.Tests/Model/ApplicationsTestFixture.cs b/COMETwebapp.Tests/Model/ApplicationsTestFixture.cs index 71c54e0a..3b098660 100644 --- a/COMETwebapp.Tests/Model/ApplicationsTestFixture.cs +++ b/COMETwebapp.Tests/Model/ApplicationsTestFixture.cs @@ -36,7 +36,7 @@ public void VerifyApplications() { var applications = Applications.ExistingApplications; - Assert.That(applications, Has.Count.EqualTo(13)); + Assert.That(applications, Has.Count.EqualTo(12)); foreach (var application in applications) { diff --git a/COMETwebapp/Components/SiteDirectory/OrganizationsTable.razor.cs b/COMETwebapp/Components/SiteDirectory/OrganizationsTable.razor.cs index d8aaa379..b157db38 100644 --- a/COMETwebapp/Components/SiteDirectory/OrganizationsTable.razor.cs +++ b/COMETwebapp/Components/SiteDirectory/OrganizationsTable.razor.cs @@ -27,7 +27,6 @@ namespace COMETwebapp.Components.SiteDirectory using CDP4Common.SiteDirectoryData; using COMETwebapp.Components.Common; - using COMETwebapp.ViewModels.Components.SiteDirectory.DomainsOfExpertise; using COMETwebapp.ViewModels.Components.SiteDirectory.Organizations; using COMETwebapp.ViewModels.Components.SiteDirectory.Rows; @@ -41,7 +40,7 @@ namespace COMETwebapp.Components.SiteDirectory public partial class OrganizationsTable : SelectedDeprecatableDataItemBase { /// - /// The for this component + /// The for this component /// [Inject] public IOrganizationsTableViewModel ViewModel { get; set; } diff --git a/COMETwebapp/Components/UserManagement/UserManagementTable.razor b/COMETwebapp/Components/SiteDirectory/UserManagementTable.razor similarity index 85% rename from COMETwebapp/Components/UserManagement/UserManagementTable.razor rename to COMETwebapp/Components/SiteDirectory/UserManagementTable.razor index 3ec8d58e..59b62dc5 100644 --- a/COMETwebapp/Components/UserManagement/UserManagementTable.razor +++ b/COMETwebapp/Components/SiteDirectory/UserManagementTable.razor @@ -1,7 +1,7 @@  -@using COMETwebapp.ViewModels.Components.UserManagement.Rows -@using CDP4Common.SiteDirectoryData -@inherits COMET.Web.Common.Components.Applications.ApplicationBase +@inherits SelectedDeprecatableDataItemBase + EditModelSaving="@(this.OnEditThingSaving)" + CustomizeElement="DisableDeprecatedThing"> - - + + @@ -67,14 +65,10 @@ - if (row.IsDeprecated) - { - - } - else - { - - } + } @@ -84,40 +78,40 @@ - + - + - + - + - + - + @@ -149,8 +143,8 @@ @this.ViewModel.PopupDialog
- - + +
diff --git a/COMETwebapp/Components/SiteDirectory/UserManagementTable.razor.cs b/COMETwebapp/Components/SiteDirectory/UserManagementTable.razor.cs new file mode 100644 index 00000000..a7a945e6 --- /dev/null +++ b/COMETwebapp/Components/SiteDirectory/UserManagementTable.razor.cs @@ -0,0 +1,117 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2023-2024 RHEA System 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 RHEA Web Application implementation of ECSS-E-TM-10-25 Annex A and Annex C. +// +// The CDP4-COMET WEB Community Edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU Affero General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// The CDP4-COMET WEB Community Edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// 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 +{ + using CDP4Common.SiteDirectoryData; + + using COMETwebapp.Components.Common; + using COMETwebapp.ViewModels.Components.SiteDirectory.Rows; + using COMETwebapp.ViewModels.Components.SiteDirectory.UserManagement; + + using DevExpress.Blazor; + + using Microsoft.AspNetCore.Components; + + /// + /// Support class for the + /// + public partial class UserManagementTable : SelectedDeprecatableDataItemBase + { + /// + /// The for this component + /// + [Inject] + public IUserManagementTableViewModel ViewModel { get; set; } + + /// + /// Method invoked when a custom summary calculation is required, allowing you to + /// perform custom calculations based on the data displayed in the grid. + /// + /// A + public static void CustomSummary(GridCustomSummaryEventArgs e) + { + switch (e.SummaryStage) + { + case GridCustomSummaryStage.Start: + e.TotalValue = 0; + break; + case GridCustomSummaryStage.Calculate: + if (e.DataItem is PersonRowViewModel { IsActive: false }) + { + e.TotalValue = (int)e.TotalValue + 1; + } + + break; + case GridCustomSummaryStage.Finalize: + default: + break; + } + } + + /// + /// Method invoked when the component is ready to start, having received its + /// initial parameters from its parent in the render tree. + /// + protected override void OnInitialized() + { + base.OnInitialized(); + this.Initialize(this.ViewModel); + } + + /// + /// Method that is invoked when the edit/add person model form is being saved + /// + /// A + protected override async Task OnEditThingSaving() + { + await this.ViewModel.CreateOrEditPerson(this.ShouldCreateThing); + } + + /// + /// Method invoked when creating a new person + /// + /// A + protected override void CustomizeEditThing(GridCustomizeEditModelEventArgs e) + { + var dataItem = (PersonRowViewModel)e.DataItem; + this.ShouldCreateThing = e.IsNew; + this.ViewModel.Thing = dataItem == null ? new Person { IsActive = true } : dataItem.Thing.Clone(true); + e.EditModel = this.ViewModel.Thing; + } + + /// + /// Method invoked when the summary text of a summary item is being displayed, allowing you to customize + /// the text as needed. Override this method to modify the summary text based on specific conditions. + /// + /// A + private static void CustomizeSummaryDisplayText(GridCustomizeSummaryDisplayTextEventArgs e) + { + if (e.Item.Name == "Inactive") + { + e.DisplayText = $"{e.Value} Inactive"; + } + } + } +} diff --git a/COMETwebapp/Components/UserManagement/UserManagementTable.razor.css b/COMETwebapp/Components/SiteDirectory/UserManagementTable.razor.css similarity index 100% rename from COMETwebapp/Components/UserManagement/UserManagementTable.razor.css rename to COMETwebapp/Components/SiteDirectory/UserManagementTable.razor.css diff --git a/COMETwebapp/Components/UserManagement/UserManagementTable.razor.cs b/COMETwebapp/Components/UserManagement/UserManagementTable.razor.cs deleted file mode 100644 index 48381077..00000000 --- a/COMETwebapp/Components/UserManagement/UserManagementTable.razor.cs +++ /dev/null @@ -1,201 +0,0 @@ -// -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) 2023-2024 RHEA System S.A. -// -// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Nabil Abbar -// -// This file is part of CDP4-COMET WEB Community Edition -// The CDP4-COMET WEB Community Edition is the RHEA Web Application implementation of ECSS-E-TM-10-25 Annex A and Annex C. -// -// The CDP4-COMET WEB Community Edition is free software; you can redistribute it and/or -// modify it under the terms of the GNU Affero General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// The CDP4-COMET WEB Community Edition is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// 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.UserManagement -{ - using CDP4Common.SiteDirectoryData; - - using COMET.Web.Common.Extensions; - - using COMETwebapp.ViewModels.Components.UserManagement.Rows; - - using DevExpress.Blazor; - - using DynamicData; - - using Microsoft.AspNetCore.Components; - - using ReactiveUI; - - /// - /// Support class for the - /// - public partial class UserManagementTable - { - /// - /// Gets or sets the grid control that is being customized. - /// - private IGrid Grid { get; set; } - - /// - /// Method invoked when a custom summary calculation is required, allowing you to - /// perform custom calculations based on the data displayed in the grid. - /// - /// A - public static void CustomSummary(GridCustomSummaryEventArgs e) - { - switch (e.SummaryStage) - { - case GridCustomSummaryStage.Start: - e.TotalValue = 0; - break; - case GridCustomSummaryStage.Calculate: - if (e.DataItem is PersonRowViewModel { IsActive: false }) - { - e.TotalValue = (int)e.TotalValue + 1; - } - - break; - case GridCustomSummaryStage.Finalize: - default: - break; - } - } - - /// - /// Method invoked to "Show/Hide Deprecated Items" - /// - public void HideOrShowDeprecatedItems() - { - if (this.ViewModel.ShowHideDeprecatedThingsService.ShowDeprecatedThings) - { - this.Grid.ClearFilter(); - } - else - { - this.Grid.FilterBy("IsDeprecated", GridFilterRowOperatorType.Equal, false); - } - } - - /// - /// Method invoked when the component is ready to start, having received its - /// initial parameters from its parent in the render tree. - /// - protected override void OnInitialized() - { - base.OnInitialized(); - - this.ViewModel.OnInitialized(); - - this.Disposables.Add(this.ViewModel.Rows.CountChanged.SubscribeAsync(_ => this.InvokeAsync(this.StateHasChanged))); - this.Disposables.Add(this.ViewModel.WhenAnyValue(x => x.Person).SubscribeAsync(_ => this.InvokeAsync(this.StateHasChanged))); - this.Disposables.Add(this.ViewModel.Rows.Connect().AutoRefresh().SubscribeAsync(_ => this.InvokeAsync(this.StateHasChanged))); - } - - /// - /// Method invoked when creating a new person - /// - /// A - private void CustomizeEditPerson(GridCustomizeEditModelEventArgs e) - { - var dataItem = (PersonRowViewModel)e.DataItem; - this.ViewModel.ShouldCreatePerson = e.IsNew; - - if (dataItem == null) - { - var newPerson = new Person - { - IsActive = true - }; - - e.EditModel = newPerson; - this.ViewModel.Person = newPerson; - return; - } - - e.EditModel = dataItem; - this.ViewModel.Person = dataItem.Person.Clone(true); - } - - /// - /// Method that is invoked when the edit/add person model form is being saved - /// - /// A - private async Task OnEditModelSaving() - { - await this.ViewModel.CreateOrEditPerson(); - } - - /// - /// Method invoked when the summary text of a summary item is being displayed, allowing you to customize - /// the text as needed. Override this method to modify the summary text based on specific conditions. - /// - /// A - private static void CustomizeSummaryDisplayText(GridCustomizeSummaryDisplayTextEventArgs e) - { - if (e.Item.Name == "Inactive") - { - e.DisplayText = $"{e.Value} Inactive"; - } - } - - /// - /// Method invoked to highlight deprecated persons - /// - /// A - private static void DisableDeprecatedPerson(GridCustomizeElementEventArgs e) - { - if (e.ElementType == GridElementType.DataRow && (bool)e.Grid.GetRowValue(e.VisibleIndex, "IsDeprecated")) - { - e.CssClass = "highlighted-item"; - } - } - - /// - /// Method invoked after each time the component has been rendered. Note that the component does - /// not automatically re-render after the completion of any returned , because - /// that would cause an infinite render loop. - /// - /// - /// Set to true if this is the first time has been invoked - /// on this component instance; otherwise false. - /// - /// A representing any asynchronous operation. - /// - /// The and lifecycle methods - /// are useful for performing interop, or interacting with values received from @ref. - /// Use the parameter to ensure that initialization work is only performed - /// once. - /// - protected override async Task OnAfterRenderAsync(bool firstRender) - { - await base.OnAfterRenderAsync(firstRender); - - if (firstRender) - { - this.Disposables.Add(this.WhenAnyValue(x => x.ViewModel.ShowHideDeprecatedThingsService.ShowDeprecatedThings) - .Subscribe(_ => this.HideOrShowDeprecatedItems())); - } - } - - /// - /// Initializes values of the component and of the ViewModel based on parameters provided from the url - /// - /// A for parameters - protected override void InitializeValues(Dictionary parameters) - { - //in this case, we don't have selectors that needs parameters from the url - } - } -} diff --git a/COMETwebapp/Extensions/ServiceCollectionExtensions.cs b/COMETwebapp/Extensions/ServiceCollectionExtensions.cs index 0b7d4e18..ce31b316 100644 --- a/COMETwebapp/Extensions/ServiceCollectionExtensions.cs +++ b/COMETwebapp/Extensions/ServiceCollectionExtensions.cs @@ -48,7 +48,7 @@ namespace COMETwebapp.Extensions using COMETwebapp.ViewModels.Components.SiteDirectory.Roles; using COMETwebapp.ViewModels.Components.SubscriptionDashboard; using COMETwebapp.ViewModels.Components.SystemRepresentation; - using COMETwebapp.ViewModels.Components.UserManagement; + using COMETwebapp.ViewModels.Components.SiteDirectory.UserManagement; using COMETwebapp.ViewModels.Components.Viewer; using COMETwebapp.ViewModels.Shared.TopMenuEntry; using COMETwebapp.ViewModels.Components.EngineeringModel.FileStore; diff --git a/COMETwebapp/Model/Applications.cs b/COMETwebapp/Model/Applications.cs index b9db9b50..b222b37e 100644 --- a/COMETwebapp/Model/Applications.cs +++ b/COMETwebapp/Model/Applications.cs @@ -106,7 +106,7 @@ public static class Applications }, new Application { - Name = "Site Directory", + Name = "Server Administration", Color = "#fc3a1aad", Icon = "folder", Description = "Visualize site directory data", @@ -120,14 +120,6 @@ public static class Applications Description = "Visualize the engineering model data", Url = WebAppConstantValues.EngineeringModelPage }, - new Application - { - Name = "User Management", - Color = "#76fd98", - Icon = "people", - Description = "Manage users", - Url = WebAppConstantValues.UserManagementPage - }, new Application { Name = "Model Editor", diff --git a/COMETwebapp/Pages/SiteDirectory/DirectoryPage.razor.cs b/COMETwebapp/Pages/SiteDirectory/DirectoryPage.razor.cs index bc2edf31..a9d9af8a 100644 --- a/COMETwebapp/Pages/SiteDirectory/DirectoryPage.razor.cs +++ b/COMETwebapp/Pages/SiteDirectory/DirectoryPage.razor.cs @@ -50,6 +50,7 @@ public partial class DirectoryPage {typeof(EngineeringModelsTable), "Models"}, {typeof(DomainsOfExpertiseTable), "Domains"}, {typeof(OrganizationsTable), "Organizations"}, + {typeof(UserManagementTable), "User Management"}, {typeof(RolesTables), "Roles"}, }; diff --git a/COMETwebapp/Pages/UserManagement/UserManagementPage.razor b/COMETwebapp/Pages/UserManagement/UserManagementPage.razor deleted file mode 100644 index b596aaf3..00000000 --- a/COMETwebapp/Pages/UserManagement/UserManagementPage.razor +++ /dev/null @@ -1,26 +0,0 @@ - -@using COMETwebapp.Utilities -@inherits COMET.Web.Common.Pages.ApplicationPageTemplate -@attribute [Route(WebAppConstantValues.UserManagementPage)] -@attribute [Authorize] - - - - - - diff --git a/COMETwebapp/Utilities/WebAppConstantValues.cs b/COMETwebapp/Utilities/WebAppConstantValues.cs index b431ff3f..c270d7a7 100644 --- a/COMETwebapp/Utilities/WebAppConstantValues.cs +++ b/COMETwebapp/Utilities/WebAppConstantValues.cs @@ -121,11 +121,6 @@ public static class WebAppConstantValues /// public const string SiteDirectoryPage = "SiteDirectory"; - /// - /// The page name of the User Management - /// - public const string UserManagementPage = "UserManagement"; - /// /// The page name of the Model Editor /// diff --git a/COMETwebapp/ViewModels/Components/Common/BaseDataItemTable/BaseDataItemTableViewModel.cs b/COMETwebapp/ViewModels/Components/Common/BaseDataItemTable/BaseDataItemTableViewModel.cs index d43ef096..58ed0484 100644 --- a/COMETwebapp/ViewModels/Components/Common/BaseDataItemTable/BaseDataItemTableViewModel.cs +++ b/COMETwebapp/ViewModels/Components/Common/BaseDataItemTable/BaseDataItemTableViewModel.cs @@ -43,11 +43,6 @@ namespace COMETwebapp.ViewModels.Components.Common.BaseDataItemTable /// public abstract class BaseDataItemTableViewModel : ApplicationBaseViewModel, IBaseDataItemTableViewModel where T : Thing where TRow : BaseDataItemRowViewModel { - /// - /// Injected property to get access to - /// - private readonly IPermissionService permissionService; - /// /// A collection of used to create subscriptions /// @@ -58,6 +53,11 @@ public abstract class BaseDataItemTableViewModel : ApplicationBaseViewM typeof(ReferenceDataLibrary) }; + /// + /// Injected property to get access to + /// + protected readonly IPermissionService PermissionService; + /// /// The /// @@ -72,7 +72,7 @@ public abstract class BaseDataItemTableViewModel : ApplicationBaseViewM protected BaseDataItemTableViewModel(ISessionService sessionService, ICDPMessageBus messageBus, ILogger> logger) : base(sessionService, messageBus) { - this.permissionService = sessionService.Session.PermissionService; + this.PermissionService = sessionService.Session.PermissionService; this.Logger = logger; this.InitializeSubscriptions(ObjectChangedTypesOfInterest); @@ -196,13 +196,13 @@ protected override Task OnSessionRefreshed() /// /// Updates the active user access rights /// - protected void RefreshAccessRight() + protected virtual void RefreshAccessRight() { this.IsLoading = true; foreach (var row in this.Rows.Items) { - row.IsAllowedToWrite = this.permissionService.CanWrite(row.Thing.ClassKind, row.Thing.Container); + row.IsAllowedToWrite = this.PermissionService.CanWrite(row.Thing.ClassKind, row.Thing.Container); } this.IsLoading = false; diff --git a/COMETwebapp/ViewModels/Components/UserManagement/Rows/PersonRowViewModel.cs b/COMETwebapp/ViewModels/Components/SiteDirectory/Rows/PersonRowViewModel.cs similarity index 59% rename from COMETwebapp/ViewModels/Components/UserManagement/Rows/PersonRowViewModel.cs rename to COMETwebapp/ViewModels/Components/SiteDirectory/Rows/PersonRowViewModel.cs index 73e2b808..14787712 100644 --- a/COMETwebapp/ViewModels/Components/UserManagement/Rows/PersonRowViewModel.cs +++ b/COMETwebapp/ViewModels/Components/SiteDirectory/Rows/PersonRowViewModel.cs @@ -2,7 +2,7 @@ // // Copyright (c) 2023-2024 RHEA System S.A. // -// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, Nabil Abbar +// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, João Rua // // This file is part of CDP4-COMET WEB Community Edition // The CDP4-COMET WEB Community Edition is the RHEA Web Application implementation of ECSS-E-TM-10-25 Annex A and Annex C. @@ -22,42 +22,29 @@ // // -------------------------------------------------------------------------------------------------------------------- -namespace COMETwebapp.ViewModels.Components.UserManagement.Rows +namespace COMETwebapp.ViewModels.Components.SiteDirectory.Rows { using CDP4Common.SiteDirectoryData; + using COMETwebapp.ViewModels.Components.Common.Rows; + using ReactiveUI; /// /// Row View Model for /// - public class PersonRowViewModel : ReactiveObject + public class PersonRowViewModel : DeprecatableDataItemRowViewModel { /// /// Backing field for /// private bool isActive; - /// - /// Backing field for - /// - private bool isDeprecated; - /// /// Backing field for /// private string personEmailAddress; - /// - /// Backing field for - /// - private string personName; - - /// - /// Backing field for - /// - private string personShortName; - /// /// Backing field for /// @@ -71,40 +58,13 @@ public class PersonRowViewModel : ReactiveObject /// /// Initializes a new instance of the class. /// - /// The associated - public PersonRowViewModel(Person person) - { - this.Person = person; - this.PersonName = person.Name; - this.PersonShortName = person.ShortName; - this.Role = person.Role?.Name; - this.PersonEmailAddress = person.DefaultEmailAddress?.Value; - this.PersonTelephoneNumber = person.DefaultTelephoneNumber?.Value; - this.IsActive = person.IsActive; - this.IsDeprecated = person.IsDeprecated; - } - - /// - /// The associated - /// - public Person Person { get; private set; } - - /// - /// The name of the - /// - public string PersonName + /// The associated + public PersonRowViewModel(Person thing) : base(thing) { - get => this.personName; - set => this.RaiseAndSetIfChanged(ref this.personName, value); - } - - /// - /// The short name of the - /// - public string PersonShortName - { - get => this.personShortName; - set => this.RaiseAndSetIfChanged(ref this.personShortName, value); + this.Role = thing.Role?.Name; + this.PersonEmailAddress = thing.DefaultEmailAddress?.Value; + this.PersonTelephoneNumber = thing.DefaultTelephoneNumber?.Value; + this.IsActive = thing.IsActive; } /// @@ -143,42 +103,18 @@ public bool IsActive set => this.RaiseAndSetIfChanged(ref this.isActive, value); } - /// - /// Value indicating if the is deprecated - /// - public bool IsDeprecated - { - get => this.isDeprecated; - set => this.RaiseAndSetIfChanged(ref this.isDeprecated, value); - } - - /// - /// Backing field for - /// - private bool isAllowedToWrite; - - /// - /// Value indicating if the is deprecated - /// - public bool IsAllowedToWrite - { - get => this.isAllowedToWrite; - set => this.RaiseAndSetIfChanged(ref this.isAllowedToWrite, value); - } - /// /// Update this row view model properties /// /// The to use for updating public void UpdateProperties(PersonRowViewModel person) { - this.PersonName = person.PersonName; - this.PersonShortName = person.PersonShortName; + base.UpdateProperties(person); + this.PersonEmailAddress = person.PersonEmailAddress; this.PersonTelephoneNumber = person.PersonTelephoneNumber; this.Role = person.Role; this.IsActive = person.IsActive; - this.IsDeprecated = person.IsDeprecated; } } } diff --git a/COMETwebapp/ViewModels/Components/UserManagement/IUserManagementTableViewModel.cs b/COMETwebapp/ViewModels/Components/SiteDirectory/UserManagement/IUserManagementTableViewModel.cs similarity index 51% rename from COMETwebapp/ViewModels/Components/UserManagement/IUserManagementTableViewModel.cs rename to COMETwebapp/ViewModels/Components/SiteDirectory/UserManagement/IUserManagementTableViewModel.cs index 64ca0edd..69951b33 100644 --- a/COMETwebapp/ViewModels/Components/UserManagement/IUserManagementTableViewModel.cs +++ b/COMETwebapp/ViewModels/Components/SiteDirectory/UserManagement/IUserManagementTableViewModel.cs @@ -2,7 +2,7 @@ // // Copyright (c) 2023-2024 RHEA System S.A. // -// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Nabil Abbar +// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, João Rua // // This file is part of CDP4-COMET WEB Community Edition // The CDP4-COMET WEB Community Edition is the RHEA Web Application implementation of ECSS-E-TM-10-25 Annex A and Annex C. @@ -22,29 +22,21 @@ // // -------------------------------------------------------------------------------------------------------------------- -namespace COMETwebapp.ViewModels.Components.UserManagement +namespace COMETwebapp.ViewModels.Components.SiteDirectory.UserManagement { + using CDP4Common.CommonData; using CDP4Common.SiteDirectoryData; - using COMET.Web.Common.ViewModels.Components.Applications; - - using COMETwebapp.Services.ShowHideDeprecatedThingsService; - using COMETwebapp.ViewModels.Components.UserManagement.Rows; + using COMETwebapp.ViewModels.Components.Common.DeprecatableDataItemTable; + using COMETwebapp.ViewModels.Components.SiteDirectory.Rows; using DevExpress.Blazor; - using DynamicData; - /// /// View model used to manage /// - public interface IUserManagementTableViewModel : IApplicationBaseViewModel, IHaveReusableRows + public interface IUserManagementTableViewModel : IDeprecatableDataItemTableViewModel { - /// - /// The to create - /// - Person Person { get; set; } - /// /// The to create /// @@ -55,16 +47,6 @@ public interface IUserManagementTableViewModel : IApplicationBaseViewModel, IHav /// TelephoneNumber TelephoneNumber { get; set; } - /// - /// Gets or sets the data source for the grid control. - /// - SourceList DataSource { get; } - - /// - /// A reactive collection of - /// - SourceList Rows { get; } - /// /// Available s /// @@ -95,72 +77,22 @@ public interface IUserManagementTableViewModel : IApplicationBaseViewModel, IHav /// IEnumerable TelephoneNumberKinds { get; set; } - /// - /// Injected property to get access to - /// - IShowHideDeprecatedThingsService ShowHideDeprecatedThingsService { get; } - /// /// Indicates if the is the default telephone number /// bool IsDefaultTelephoneNumber { get; set; } /// - /// Indicates if confirmation popup is visible - /// - bool IsOnDeprecationMode { get; set; } - - /// - /// Popup message dialog - /// - string PopupDialog { get; set; } - - /// - /// Gets or sets the condition to check if a person should be created - /// - bool ShouldCreatePerson { get; set; } - - /// - /// Method invoked when confirming the deprecation/un-deprecation of a - /// - /// A - Task OnConfirmButtonClick(); - - /// - /// Method invoked when canceling the deprecation/un-deprecation of a - /// - void OnCancelButtonClick(); - - /// - /// Action invoked when the deprecate or undeprecate button is clicked - /// - /// A that represents the person to deprecate or undeprecate - void OnDeprecateUnDeprecateButtonClick(PersonRowViewModel personRow); - - /// - /// Tries to activate or disactivate a + /// Tries to activate or disactivate a /// /// A Task ActivateOrDeactivatePerson(GridDataColumnCellDisplayTemplateContext context, bool value); /// - /// Method invoked when the component is ready to start, having received its - /// initial parameters from its parent in the render tree. - /// Override this method if you will perform an asynchronous operation and - /// want the component to refresh when that operation is completed. - /// - void OnInitialized(); - - /// - /// Tries to create or edit an existing , based on the property - /// - /// A - Task CreateOrEditPerson(); - - /// - /// Tries to deprecate or undeprecate a + /// Tries to create or edit an existing /// + /// Value to check if the current Person should be created /// A - Task DeprecateOrUndeprecatePerson(); + Task CreateOrEditPerson(bool shouldCreate); } } diff --git a/COMETwebapp/ViewModels/Components/SiteDirectory/UserManagement/UserManagementTableViewModel.cs b/COMETwebapp/ViewModels/Components/SiteDirectory/UserManagement/UserManagementTableViewModel.cs new file mode 100644 index 00000000..e3602052 --- /dev/null +++ b/COMETwebapp/ViewModels/Components/SiteDirectory/UserManagement/UserManagementTableViewModel.cs @@ -0,0 +1,207 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2023-2024 RHEA System 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 RHEA Web Application implementation of ECSS-E-TM-10-25 Annex A and Annex C. +// +// The CDP4-COMET WEB Community Edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU Affero General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// The CDP4-COMET WEB Community Edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// 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.UserManagement +{ + using CDP4Common.CommonData; + using CDP4Common.SiteDirectoryData; + + using CDP4Dal; + + using COMET.Web.Common.Services.SessionManagement; + + using COMETwebapp.Services.ShowHideDeprecatedThingsService; + using COMETwebapp.ViewModels.Components.Common.DeprecatableDataItemTable; + using COMETwebapp.ViewModels.Components.SiteDirectory.Rows; + + using DevExpress.Blazor; + + /// + /// View model used to manage + /// + public class UserManagementTableViewModel : DeprecatableDataItemTableViewModel, IUserManagementTableViewModel + { + /// + /// Initializes a new instance of the class. + /// + /// The + /// The + /// The + /// The + public UserManagementTableViewModel(ISessionService sessionService, IShowHideDeprecatedThingsService showHideDeprecatedThingsService, ICDPMessageBus messageBus, + ILogger logger) : base(sessionService, messageBus, showHideDeprecatedThingsService, logger) + { + this.Thing = new Person(); + } + + /// + /// The to create + /// + public EmailAddress EmailAddress { get; set; } = new(); + + /// + /// The to create + /// + public TelephoneNumber TelephoneNumber { get; set; } = new(); + + /// + /// Available s + /// + public IEnumerable AvailableOrganizations { get; set; } + + /// + /// Available s + /// + public IEnumerable AvailablePersonRoles { get; set; } + + /// + /// Available s + /// + public IEnumerable AvailableDomains { get; set; } + + /// + /// Available s + /// + public IEnumerable EmailAddressKinds { get; set; } = Enum.GetValues(typeof(VcardEmailAddressKind)).Cast(); + + /// + /// Indicates if the is the default email address + /// + public bool IsDefaultEmail { get; set; } + + /// + /// Available s + /// + public IEnumerable TelephoneNumberKinds { get; set; } = Enum.GetValues(typeof(VcardTelephoneNumberKind)).Cast(); + + /// + /// Indicates if the is the default telephone number + /// + public bool IsDefaultTelephoneNumber { get; set; } + + /// + /// Method invoked when the component is ready to start, having received its + /// initial parameters from its parent in the render tree. + /// Override this method if you will perform an asynchronous operation and + /// want the component to refresh when that operation is completed. + /// + public override void InitializeViewModel() + { + var siteDirectory = this.SessionService.Session.RetrieveSiteDirectory(); + this.AvailableOrganizations = siteDirectory.Organization; + this.AvailablePersonRoles = siteDirectory.PersonRole; + this.AvailableDomains = siteDirectory.Domain; + + base.InitializeViewModel(); + } + + /// + /// Tries to create or edit an existing + /// + /// Value to check if the current Person should be created + /// A + public async Task CreateOrEditPerson(bool shouldCreate) + { + var thingsToCreate = new List(); + + if (!string.IsNullOrWhiteSpace(this.EmailAddress.Value)) + { + this.Thing.EmailAddress.Add(this.EmailAddress); + thingsToCreate.Add(this.EmailAddress); + } + + if (!string.IsNullOrWhiteSpace(this.TelephoneNumber.Value)) + { + this.Thing.TelephoneNumber.Add(this.TelephoneNumber); + thingsToCreate.Add(this.TelephoneNumber); + } + + if (this.IsDefaultEmail) + { + this.Thing.DefaultEmailAddress = this.EmailAddress; + } + + if (this.IsDefaultTelephoneNumber) + { + this.Thing.DefaultTelephoneNumber = this.TelephoneNumber; + } + + var siteDirectoryClone = this.SessionService.GetSiteDirectory().Clone(false); + + if (shouldCreate) + { + siteDirectoryClone.Person.Add(this.Thing); + thingsToCreate.Add(siteDirectoryClone); + } + + thingsToCreate.Add(this.Thing); + await this.SessionService.UpdateThings(siteDirectoryClone, thingsToCreate); + await this.SessionService.RefreshSession(); + this.ResetFields(); + } + + /// + /// Tries to activate or disactivate a + /// + /// A + public async Task ActivateOrDeactivatePerson(GridDataColumnCellDisplayTemplateContext context, bool value) + { + var siteDirectoryClone = this.SessionService.GetSiteDirectory().Clone(false); + var personRow = (PersonRowViewModel)context.DataItem; + var personToUpdate = personRow.Thing; + var clonedPerson = personToUpdate.Clone(false); + clonedPerson.IsActive = value; + + await this.SessionService.UpdateThings(siteDirectoryClone, clonedPerson); + await this.SessionService.RefreshSession(); + } + + /// + /// Updates the active user access rights + /// + protected override void RefreshAccessRight() + { + this.IsLoading = true; + + foreach (var row in this.Rows.Items) + { + row.IsAllowedToWrite = row.Thing.Iid != this.SessionService.Session.ActivePerson.Iid + && this.PermissionService.CanWrite(ClassKind.Person, this.SessionService.GetSiteDirectory()); + } + + this.IsLoading = false; + } + + /// + /// Method that resets all form fields + /// + private void ResetFields() + { + this.EmailAddress = new EmailAddress(); + this.TelephoneNumber = new TelephoneNumber(); + this.IsDefaultEmail = false; + this.IsDefaultTelephoneNumber = false; + } + } +} diff --git a/COMETwebapp/ViewModels/Components/UserManagement/UserManagementTableViewModel.cs b/COMETwebapp/ViewModels/Components/UserManagement/UserManagementTableViewModel.cs deleted file mode 100644 index d4249717..00000000 --- a/COMETwebapp/ViewModels/Components/UserManagement/UserManagementTableViewModel.cs +++ /dev/null @@ -1,370 +0,0 @@ -// -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) 2023-2024 RHEA System S.A. -// -// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Nabil Abbar -// -// This file is part of CDP4-COMET WEB Community Edition -// The CDP4-COMET WEB Community Edition is the RHEA Web Application implementation of ECSS-E-TM-10-25 Annex A and Annex C. -// -// The CDP4-COMET WEB Community Edition is free software; you can redistribute it and/or -// modify it under the terms of the GNU Affero General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// The CDP4-COMET WEB Community Edition is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// 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.UserManagement -{ - using AntDesign; - - using CDP4Common.CommonData; - using CDP4Common.SiteDirectoryData; - - using CDP4Dal; - using CDP4Dal.Permission; - - using COMET.Web.Common.Services.SessionManagement; - using COMET.Web.Common.ViewModels.Components.Applications; - - using COMETwebapp.Services.ShowHideDeprecatedThingsService; - using COMETwebapp.ViewModels.Components.UserManagement.Rows; - - using DevExpress.Blazor; - - using DynamicData; - - using ReactiveUI; - - /// - /// View model used to manage - /// - public class UserManagementTableViewModel : ApplicationBaseViewModel, IUserManagementTableViewModel - { - /// - /// Injected property to get access to - /// - private readonly IPermissionService permissionService; - - /// - /// Injected property to get access to - /// - private readonly ISessionService sessionService; - - /// - /// Backing field for - /// - private bool isOnDeprecationMode; - - /// - /// Initializes a new instance of the class. - /// - /// The - /// The - /// The - public UserManagementTableViewModel(ISessionService sessionService, IShowHideDeprecatedThingsService showHideDeprecatedThingsService, ICDPMessageBus messageBus) : base(sessionService, messageBus) - { - this.sessionService = sessionService; - this.permissionService = sessionService.Session.PermissionService; - this.ShowHideDeprecatedThingsService = showHideDeprecatedThingsService; - - this.InitializeSubscriptions(new List { typeof(Person) }); - this.RegisterViewModelWithReusableRows(this); - } - - /// - /// Injected property to get access to - /// - public IShowHideDeprecatedThingsService ShowHideDeprecatedThingsService { get; } - - /// - /// Gets or sets the condition to check if a person should be created - /// - public bool ShouldCreatePerson { get; set; } = true; - - /// - /// The to create or edit - /// - public Person Person { get; set; } = new(); - - /// - /// A reactive collection of - /// - public SourceList Rows { get; } = new(); - - /// - /// The to create - /// - public EmailAddress EmailAddress { get; set; } = new(); - - /// - /// The to create - /// - public TelephoneNumber TelephoneNumber { get; set; } = new(); - - /// - /// Gets or sets the data source for the grid control. - /// - public SourceList DataSource { get; } = new(); - - /// - /// Available s - /// - public IEnumerable AvailableOrganizations { get; set; } - - /// - /// Available s - /// - public IEnumerable AvailablePersonRoles { get; set; } - - /// - /// Available s - /// - public IEnumerable AvailableDomains { get; set; } - - /// - /// Available s - /// - public IEnumerable EmailAddressKinds { get; set; } = Enum.GetValues(typeof(VcardEmailAddressKind)).Cast(); - - /// - /// Indicates if the is the default email address - /// - public bool IsDefaultEmail { get; set; } - - /// - /// Available s - /// - public IEnumerable TelephoneNumberKinds { get; set; } = Enum.GetValues(typeof(VcardTelephoneNumberKind)).Cast(); - - /// - /// Indicates if the is the default telephone number - /// - public bool IsDefaultTelephoneNumber { get; set; } - - /// - /// Indicates if confirmation popup is visible - /// - public bool IsOnDeprecationMode - { - get => this.isOnDeprecationMode; - set => this.RaiseAndSetIfChanged(ref this.isOnDeprecationMode, value); - } - - /// - /// popum message dialog - /// - public string PopupDialog { get; set; } - - /// - /// Method invoked when confirming the deprecation/un-deprecation of a - /// - /// A - public async Task OnConfirmButtonClick() - { - await this.DeprecateOrUndeprecatePerson(); - this.IsOnDeprecationMode = false; - } - - /// - /// Method invoked when canceling the deprecation/un-deprecation of a - /// - public void OnCancelButtonClick() - { - this.IsOnDeprecationMode = false; - } - - /// - /// Tries to create or edit an existing , based on the property - /// - /// A - public async Task CreateOrEditPerson() - { - var thingsToCreate = new List(); - - if (!string.IsNullOrWhiteSpace(this.EmailAddress.Value)) - { - this.Person.EmailAddress.Add(this.EmailAddress); - thingsToCreate.Add(this.EmailAddress); - } - - if (!string.IsNullOrWhiteSpace(this.TelephoneNumber.Value)) - { - this.Person.TelephoneNumber.Add(this.TelephoneNumber); - thingsToCreate.Add(this.TelephoneNumber); - } - - if (this.IsDefaultEmail) - { - this.Person.DefaultEmailAddress = this.EmailAddress; - } - - if (this.IsDefaultTelephoneNumber) - { - this.Person.DefaultTelephoneNumber = this.TelephoneNumber; - } - - var siteDirectoryClone = this.SessionService.GetSiteDirectory().Clone(false); - - if (this.ShouldCreatePerson) - { - siteDirectoryClone.Person.Add(this.Person); - thingsToCreate.Add(siteDirectoryClone); - } - - thingsToCreate.Add(this.Person); - await this.SessionService.UpdateThings(siteDirectoryClone, thingsToCreate); - await this.sessionService.RefreshSession(); - this.ResetFields(); - } - - /// - /// Action invoked when the deprecate or undeprecate button is clicked - /// - /// A that represents the person to deprecate or undeprecate - public void OnDeprecateUnDeprecateButtonClick(PersonRowViewModel personRow) - { - this.Person = new Person(); - this.Person = personRow.Person; - this.PopupDialog = this.Person.IsDeprecated ? "You are about to un-deprecate the user: " + personRow.PersonName : "You are about to deprecate the user: " + personRow.PersonName; - this.IsOnDeprecationMode = true; - } - - /// - /// Tries to activate or disactivate a - /// - /// A - public async Task ActivateOrDeactivatePerson(GridDataColumnCellDisplayTemplateContext context, bool value) - { - var siteDirectoryClone = this.sessionService.GetSiteDirectory().Clone(false); - var personRow = (PersonRowViewModel)context.DataItem; - var personToUpdate = personRow.Person; - var clonedPerson = personToUpdate.Clone(false); - clonedPerson.IsActive = value; - - await this.sessionService.UpdateThings(siteDirectoryClone, clonedPerson); - await this.sessionService.RefreshSession(); - } - - /// - /// Method invoked when the component is ready to start, having received its - /// initial parameters from its parent in the render tree. - /// Override this method if you will perform an asynchronous operation and - /// want the component to refresh when that operation is completed. - /// - public void OnInitialized() - { - this.DataSource.AddRange(this.sessionService.Session.RetrieveSiteDirectory().Person); - this.DataSource.Items.ForEach(x => this.Rows.Add(new PersonRowViewModel(x))); - this.AvailableOrganizations = this.sessionService.Session.RetrieveSiteDirectory().Organization; - this.AvailablePersonRoles = this.sessionService.Session.RetrieveSiteDirectory().PersonRole; - this.AvailableDomains = this.sessionService.Session.RetrieveSiteDirectory().Domain; - this.RefreshAccessRight(); - } - - /// - /// Remove rows related to a that has been deleted - /// - /// A collection of deleted - public void RemoveRows(IEnumerable deletedThings) - { - foreach (var person in deletedThings.OfType()) - { - var row = this.Rows.Items.FirstOrDefault(x => x.Person.Iid == person.Iid); - - if (row != null) - { - this.Rows.Remove(row); - } - } - } - - /// - /// Add rows related to that has been added - /// - /// A collection of added - public void AddRows(IEnumerable addedThings) - { - this.Rows.AddRange(addedThings.OfType().Select(x => new PersonRowViewModel(x))); - } - - /// - /// Updates rows related to that have been updated - /// - /// A collection of updated - public void UpdateRows(IEnumerable updatedThings) - { - foreach (var person in updatedThings.OfType()) - { - var row = this.Rows.Items.FirstOrDefault(x => x.Person.Iid == person.Iid); - row?.UpdateProperties(new PersonRowViewModel(person)); - } - } - - /// - /// Tries to deprecate or undeprecate a - /// - /// A - public async Task DeprecateOrUndeprecatePerson() - { - var siteDirectoryClone = this.sessionService.GetSiteDirectory().Clone(false); - var clonedPerson = this.Person.Clone(false); - clonedPerson.IsDeprecated = !clonedPerson.IsDeprecated; - - await this.sessionService.UpdateThings(siteDirectoryClone, clonedPerson); - await this.sessionService.RefreshSession(); - this.IsOnDeprecationMode = false; - } - - /// - /// Handles the refresh of the current - /// - /// A - protected override async Task OnSessionRefreshed() - { - if (this.AddedThings.Count == 0 && this.DeletedThings.Count == 0 && this.UpdatedThings.Count == 0) - { - return; - } - - this.IsLoading = true; - await Task.Delay(1); - - this.UpdateInnerComponents(); - this.ClearRecordedChanges(); - this.RefreshAccessRight(); - this.IsLoading = false; - } - - /// - /// Updates the active user access rights - /// - private void RefreshAccessRight() - { - foreach (var row in this.Rows.Items) - { - row.IsAllowedToWrite = row.Person.Iid != this.sessionService.Session.ActivePerson.Iid - && this.permissionService.CanWrite(ClassKind.Person, this.sessionService.GetSiteDirectory()); - } - } - - /// - /// Method that resets all form fields - /// - private void ResetFields() - { - this.EmailAddress = new EmailAddress(); - this.TelephoneNumber = new TelephoneNumber(); - this.IsDefaultEmail = false; - this.IsDefaultTelephoneNumber = false; - } - } -} diff --git a/COMETwebapp/_Imports.razor b/COMETwebapp/_Imports.razor index 50d4d211..f39e2a67 100644 --- a/COMETwebapp/_Imports.razor +++ b/COMETwebapp/_Imports.razor @@ -28,7 +28,6 @@ @using COMETwebapp.Components.ModelDashboard.Elements @using COMETwebapp.Components.ModelDashboard.ParameterValues @using COMETwebapp.Components.ReferenceData -@using COMETwebapp.Components.UserManagement @using COMETwebapp.Components.SystemRepresentation @using COMETwebapp.Components.Viewer.PropertiesPanel @using COMETwebapp.ViewModels.Components.SiteDirectory.Rows