Skip to content

Commit

Permalink
organizations can be edited/created + unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
joao4all committed Apr 22, 2024
1 parent 7492289 commit a7bb8f4
Show file tree
Hide file tree
Showing 8 changed files with 228 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ namespace COMETwebapp.Tests.Components.SiteDirectory

using DynamicData;

using Microsoft.AspNetCore.Components.Forms;
using Microsoft.Extensions.DependencyInjection;

using Moq;
Expand Down Expand Up @@ -142,18 +143,27 @@ public async Task VerifyAddingOrEditingOrganization()

Assert.Multiple(() =>
{
Assert.That(renderer.Instance.ShouldCreateThing, Is.EqualTo(true));
Assert.That(renderer.Instance.IsOnEditMode, Is.EqualTo(false));
Assert.That(this.viewModel.Object.Thing, Is.InstanceOf(typeof(Organization)));
});

var editORganizationButton = renderer.FindComponents<DxButton>().First(x => x.Instance.Id == "editOrganizationButton");
await renderer.InvokeAsync(editORganizationButton.Instance.Click.InvokeAsync);

var organizationsGrid = renderer.FindComponent<DxGrid>();
await renderer.InvokeAsync(() => organizationsGrid.Instance.SelectedDataItemChanged.InvokeAsync(new OrganizationRowViewModel(this.organization1)));
Assert.That(renderer.Instance.IsOnEditMode, Is.EqualTo(true));

var organizationsForm = renderer.FindComponents<OrganizationsForm>()[1];
var organizationsEditForm = organizationsForm.FindComponent<EditForm>();
await organizationsForm.InvokeAsync(organizationsEditForm.Instance.OnValidSubmit.InvokeAsync);

Assert.Multiple(() =>
{
Assert.That(renderer.Instance.ShouldCreateThing, Is.EqualTo(false));
this.viewModel.Verify(x => x.CreateOrEditOrganization(false), Times.Once);
Assert.That(this.viewModel.Object.Thing, Is.InstanceOf(typeof(Organization)));
});

var form = renderer.FindComponent<DxGrid>();
await renderer.InvokeAsync(form.Instance.EditModelSaving.InvokeAsync);
this.viewModel.Verify(x => x.CreateOrEditOrganization(false), Times.Once);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ namespace COMETwebapp.Tests.ViewModels.Components.SiteDirectory

using CDP4Web.Enumerations;

using COMET.Web.Common.Enumerations;
using COMET.Web.Common.Services.SessionManagement;

using COMETwebapp.Services.ShowHideDeprecatedThingsService;
Expand Down Expand Up @@ -202,5 +201,17 @@ public async Task VerifyRowOperations()
await this.viewModel.OnConfirmPopupButtonClick();
this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny<SiteDirectory>(), It.Is<IReadOnlyCollection<Thing>>(c => ((IDeprecatableThing)c.First()).IsDeprecated == false)));
}

[Test]
public async Task VerifyCreateOrEditOrganization()
{
this.viewModel.InitializeViewModel();

await this.viewModel.CreateOrEditOrganization(false);
this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny<SiteDirectory>(), It.Is<List<Thing>>(c => c.Count == 1)), Times.Once);

await this.viewModel.CreateOrEditOrganization(true);
this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny<SiteDirectory>(), It.Is<List<Thing>>(c => c.Count == 2)), Times.Once);
}
}
}
46 changes: 46 additions & 0 deletions COMETwebapp/Components/SiteDirectory/OrganizationsForm.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<!------------------------------------------------------------------------------
Copyright (c) 2023-2024 RHEA System 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 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 http://www.gnu.org/licenses/.
------------------------------------------------------------------------------->
@inherits SelectedDataItemForm

<EditForm Context="editFormContext" Model="@(this.ViewModel.Thing)" OnValidSubmit="@(this.OnValidSubmit)">
<FluentValidationValidator />
<DxFormLayout CssClass="w-100">
<DxFormLayoutItem Caption="Shortname:" ColSpanMd="10">
<DxTextBox @bind-Text="@this.ViewModel.Thing.ShortName"/>
</DxFormLayoutItem>
<DxFormLayoutItem Caption="Name:" ColSpanMd="10">
<DxTextBox @bind-Text="@this.ViewModel.Thing.Name"/>
</DxFormLayoutItem>
<DxFormLayoutItem Caption="Deprecated:" ColSpanMd="6">
<DxCheckBox @bind-Checked="@this.ViewModel.Thing.IsDeprecated"/>
</DxFormLayoutItem>
</DxFormLayout>
<div class="pt-3"></div>
<ValidationSummary />
<div class="dxbl-grid-edit-form-buttons">
<DxButton Id="saveOrganizationButton"
SubmitFormOnClick="true">
Save
</DxButton>

<DxButton Id="cancelOrganizationButton"
Click="@(() => this.OnCancel())"
RenderStyle="ButtonRenderStyle.Secondary">
Cancel
</DxButton>
</div>
</EditForm>
55 changes: 55 additions & 0 deletions COMETwebapp/Components/SiteDirectory/OrganizationsForm.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="OrganizationsForm.razor.cs" company="RHEA System S.A.">
// 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 <http://www.gnu.org/licenses/>.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace COMETwebapp.Components.SiteDirectory
{
using System.ComponentModel.DataAnnotations;

using COMETwebapp.Components.Common;
using COMETwebapp.ViewModels.Components.SiteDirectory.Organizations;

using Microsoft.AspNetCore.Components;

/// <summary>
/// Support class for the <see cref="OrganizationsForm"/>
/// </summary>
public partial class OrganizationsForm : SelectedDataItemForm
{
/// <summary>
/// The <see cref="IOrganizationsTableViewModel" /> for this component
/// </summary>
[Parameter, Required]
public IOrganizationsTableViewModel ViewModel { get; set; }

/// <summary>
/// Method that is executed when there is a valid submit
/// </summary>
/// <returns>A <see cref="Task"/></returns>
protected override async Task OnValidSubmit()
{
await this.ViewModel.CreateOrEditOrganization(this.ShouldCreate);
await base.OnValidSubmit();
}
}
}
106 changes: 54 additions & 52 deletions COMETwebapp/Components/SiteDirectory/OrganizationsTable.razor
Original file line number Diff line number Diff line change
Expand Up @@ -14,64 +14,66 @@ Copyright (c) 2023-2024 RHEA System 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
@inherits COMETwebapp.Components.Common.SelectedDeprecatableDataItemBase<CDP4Common.SiteDirectoryData.Organization, OrganizationRowViewModel>

<LoadingComponent IsVisible="@(this.ViewModel.IsLoading)">
<DxGrid @ref="this.Grid"
Data="this.ViewModel.Rows.Items"
ColumnResizeMode="GridColumnResizeMode.ColumnsContainer"
ShowSearchBox="true"
SearchBoxNullText="Search for an organization..."
PopupEditFormCssClass="pw-800"
PopupEditFormHeaderText="Organization (UNDER DEV)"
CustomizeElement="DisableDeprecatedThing"
CustomizeEditModel="this.CustomizeEditThing"
EditMode="GridEditMode.PopupEditForm"
EditModelSaving="@(this.OnEditThingSaving)"
PageSize="20"
PagerNavigationMode="PagerNavigationMode.Auto"
PageSizeSelectorVisible="true"
PageSizeSelectorItems="@(new int[] { 20,35,50 })"
PageSizeSelectorAllRowsItemVisible="true">
<Columns>
<DxGridDataColumn FieldName="@nameof(OrganizationRowViewModel.Name)" MinWidth="150" />
<DxGridDataColumn FieldName="@nameof(OrganizationRowViewModel.ShortName)" MinWidth="80" SearchEnabled="false" />
<DxGridDataColumn FieldName="@nameof(OrganizationRowViewModel.IsDeprecated)" UnboundType="GridUnboundColumnType.Boolean" Visible="false" Caption="Is Deprecated" MinWidth="80" SearchEnabled="false" />
<DxGridCommandColumn Width="200px" EditButtonVisible="false">
<HeaderTemplate>
<DxButton Id="addOrganizationButton" Text="Add Organization" IconCssClass="oi oi-plus" Click="() => this.Grid.StartEditNewRowAsync()" />
</HeaderTemplate>
<CellDisplayTemplate>
@{
var row = (OrganizationRowViewModel)context.DataItem;
<div class="d-flex justify-content-between">
<DxGrid @ref="this.Grid"
Data="this.ViewModel.Rows.Items"
ColumnResizeMode="GridColumnResizeMode.ColumnsContainer"
ShowSearchBox="true"
SearchBoxNullText="Search for an organization..."
AllowSelectRowByClick="true"
SelectionMode="GridSelectionMode.Single"
SelectedDataItemChanged="@((row) => this.OnSelectedDataItemChanged((OrganizationRowViewModel)row))"
PopupEditFormCssClass="pw-800"
PopupEditFormHeaderText="Organization"
CustomizeElement="DisableDeprecatedThing"
CustomizeEditModel="this.CustomizeEditThing"
EditMode="GridEditMode.PopupEditForm"
EditModelSaving="@(this.OnEditThingSaving)"
EditFormButtonsVisible="false"
PageSize="20"
PagerNavigationMode="PagerNavigationMode.Auto"
PageSizeSelectorVisible="true"
PageSizeSelectorItems="@(new int[] { 20, 35, 50 })"
PageSizeSelectorAllRowsItemVisible="true">
<Columns>
<DxGridDataColumn FieldName="@nameof(OrganizationRowViewModel.Name)" MinWidth="150"/>
<DxGridDataColumn FieldName="@nameof(OrganizationRowViewModel.ShortName)" MinWidth="80" SearchEnabled="false"/>
<DxGridDataColumn FieldName="@nameof(OrganizationRowViewModel.IsDeprecated)" UnboundType="GridUnboundColumnType.Boolean" Visible="false" Caption="Is Deprecated" MinWidth="80" SearchEnabled="false"/>
<DxGridCommandColumn Width="200px" EditButtonVisible="false">
<HeaderTemplate>
<DxButton Id="addOrganizationButton" Text="Add Organization" IconCssClass="oi oi-plus" Click="() => this.Grid.StartEditNewRowAsync()"/>
</HeaderTemplate>
<CellDisplayTemplate>
@{
var row = (OrganizationRowViewModel)context.DataItem;

<DxButton Id="editOrganizationButton" Text="Edit" Click="@(() => this.Grid.StartEditRowAsync(context.VisibleIndex))" Enabled="@(row.IsAllowedToWrite)" />
<DxButton Id="@(row.IsDeprecated ? "undeprecateButton" : "deprecateButton")"
Text="@(row.IsDeprecated ? "Un-deprecate" : "Deprecate")"
Click="() => this.ViewModel.OnDeprecateUnDeprecateButtonClick(row)"
Enabled="@(row.IsAllowedToWrite)"/>
}
</CellDisplayTemplate>
</DxGridCommandColumn>
</Columns>

<DxButton Id="@(row.IsDeprecated ? "undeprecateButton" : "deprecateButton")"
Text="@(row.IsDeprecated ? "Un-deprecate" : "Deprecate")"
Click="() => this.ViewModel.OnDeprecateUnDeprecateButtonClick(row)"
Enabled="@(row.IsAllowedToWrite)" />
}
</CellDisplayTemplate>
</DxGridCommandColumn>
</Columns>
<EditFormTemplate Context="EditFormContext">
<OrganizationsForm ViewModel="@this.ViewModel"
IsVisible="true"
ShouldCreate="true"
OnSaved="@(() => this.Grid.CancelEditAsync())"
OnCanceled="@(() => this.Grid.CancelEditAsync())"/>
</EditFormTemplate>

<EditFormTemplate Context="EditFormContext">
<DxFormLayout CssClass="w-100">
<DxFormLayoutItem Caption="Shortname:" ColSpanMd="10">
<DxTextBox @bind-Text="@this.ViewModel.Thing.ShortName" />
</DxFormLayoutItem>
<DxFormLayoutItem Caption="Name:" ColSpanMd="10">
<DxTextBox @bind-Text="@this.ViewModel.Thing.Name" />
</DxFormLayoutItem>
<DxFormLayoutItem Caption="Deprecated:" ColSpanMd="6">
<DxCheckBox @bind-Checked="@this.ViewModel.Thing.IsDeprecated" />
</DxFormLayoutItem>
</DxFormLayout>
</EditFormTemplate>

</DxGrid>
</DxGrid>
<DataItemDetailsComponent IsSelected="@this.IsOnEditMode">
<OrganizationsForm ViewModel="@this.ViewModel"
@bind-IsVisible="@this.IsOnEditMode"
ShouldCreate="false"/>
</DataItemDetailsComponent>
</div>
</LoadingComponent>

<DxPopup @bind-Visible="@this.ViewModel.IsOnDeprecationMode" HeaderText="Please confirm" Width="auto" CloseOnOutsideClick="false">
Expand Down
20 changes: 11 additions & 9 deletions COMETwebapp/Components/SiteDirectory/OrganizationsTable.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,18 @@ protected override void CustomizeEditThing(GridCustomizeEditModelEventArgs e)

var dataItem = (OrganizationRowViewModel)e.DataItem;
this.ShouldCreateThing = e.IsNew;
this.ViewModel.Thing = dataItem == null ? new Organization() : dataItem.Thing.Clone(true);
e.EditModel = this.ViewModel.Thing;
}

if (dataItem == null)
{
this.ViewModel.Thing = new Organization();
e.EditModel = this.ViewModel.Thing;
return;
}

e.EditModel = dataItem;
this.ViewModel.Thing = dataItem.Thing.Clone(true);
/// <summary>
/// Method invoked every time a row is selected
/// </summary>
/// <param name="row">The selected row</param>
private void OnSelectedDataItemChanged(OrganizationRowViewModel row)
{
this.ViewModel.Thing = row.Thing.Clone(true);
this.IsOnEditMode = true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,11 @@ namespace COMETwebapp.ViewModels.Components.SiteDirectory.Organizations
/// </summary>
public interface IOrganizationsTableViewModel : IDeprecatableDataItemTableViewModel<Organization, OrganizationRowViewModel>
{
/// <summary>
/// Creates or edits an <see cref="Organization"/>
/// </summary>
/// <param name="shouldCreate">The value to check if a new <see cref="Organization"/> should be created</param>
/// <returns>A <see cref="Task"/></returns>
Task CreateOrEditOrganization(bool shouldCreate);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

namespace COMETwebapp.ViewModels.Components.SiteDirectory.Organizations
{
using CDP4Common.CommonData;
using CDP4Common.SiteDirectoryData;

using CDP4Dal;
Expand All @@ -32,16 +33,15 @@ namespace COMETwebapp.ViewModels.Components.SiteDirectory.Organizations

using COMETwebapp.Services.ShowHideDeprecatedThingsService;
using COMETwebapp.ViewModels.Components.Common.DeprecatableDataItemTable;
using COMETwebapp.ViewModels.Components.ReferenceData.ParameterTypes;
using COMETwebapp.ViewModels.Components.SiteDirectory.Rows;

/// <summary>
/// View model used to manage <see cref="DomainOfExpertise" />
/// View model used to manage <see cref="Organization" />
/// </summary>
public class OrganizationsTableViewModel : DeprecatableDataItemTableViewModel<Organization, OrganizationRowViewModel>, IOrganizationsTableViewModel
{
/// <summary>
/// Initializes a new instance of the <see cref="ParameterTypeTableViewModel" /> class.
/// Initializes a new instance of the <see cref="OrganizationsTableViewModel" /> class.
/// </summary>
/// <param name="sessionService">The <see cref="ISessionService" /></param>
/// <param name="showHideDeprecatedThingsService">The <see cref="IShowHideDeprecatedThingsService" /></param>
Expand All @@ -50,6 +50,32 @@ public class OrganizationsTableViewModel : DeprecatableDataItemTableViewModel<Or
public OrganizationsTableViewModel(ISessionService sessionService, IShowHideDeprecatedThingsService showHideDeprecatedThingsService, ICDPMessageBus messageBus, ILogger<OrganizationsTableViewModel> logger)
: base(sessionService, messageBus, showHideDeprecatedThingsService, logger)
{
this.Thing = new Organization();
}

/// <summary>
/// Creates or edits an <see cref="Organization"/>
/// </summary>
/// <param name="shouldCreate">The value to check if a new <see cref="Organization"/> should be created</param>
/// <returns>A <see cref="Task"/></returns>
public async Task CreateOrEditOrganization(bool shouldCreate)
{
this.IsLoading = true;

var siteDirectoryClone = this.SessionService.GetSiteDirectory().Clone(false);
var thingsToCreate = new List<Thing>();

if (shouldCreate)
{
siteDirectoryClone.Organization.Add(this.Thing);
thingsToCreate.Add(siteDirectoryClone);
}

thingsToCreate.Add(this.Thing);
await this.SessionService.CreateOrUpdateThings(siteDirectoryClone, thingsToCreate);
await this.SessionService.RefreshSession();

this.IsLoading = false;
}
}
}

0 comments on commit a7bb8f4

Please sign in to comment.