diff --git a/COMETwebapp.Tests/Pages/ReferenceData/ReferenceDataPageTestFixture.cs b/COMETwebapp.Tests/Components/ReferenceData/ReferenceDataBodyTestFixture.cs similarity index 90% rename from COMETwebapp.Tests/Pages/ReferenceData/ReferenceDataPageTestFixture.cs rename to COMETwebapp.Tests/Components/ReferenceData/ReferenceDataBodyTestFixture.cs index 9e22ebc3..2e514542 100644 --- a/COMETwebapp.Tests/Pages/ReferenceData/ReferenceDataPageTestFixture.cs +++ b/COMETwebapp.Tests/Components/ReferenceData/ReferenceDataBodyTestFixture.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 @@ -22,7 +22,7 @@ // // -------------------------------------------------------------------------------------------------------------------- -namespace COMETwebapp.Tests.Pages.ReferenceData +namespace COMETwebapp.Tests.Components.ReferenceData { using Bunit; @@ -32,11 +32,11 @@ namespace COMETwebapp.Tests.Pages.ReferenceData using COMET.Web.Common.Services.ConfigurationService; using COMET.Web.Common.Services.SessionManagement; using COMET.Web.Common.Test.Helpers; - using COMET.Web.Common.ViewModels.Components.Applications; + using COMETwebapp.Components.ReferenceData; using COMETwebapp.Components.ReferenceData.MeasurementScales; using COMETwebapp.Components.ReferenceData.ParameterTypes; - using COMETwebapp.Pages.ReferenceData; + using COMETwebapp.ViewModels.Components.ReferenceData; using COMETwebapp.ViewModels.Components.ReferenceData.MeasurementScales; using COMETwebapp.ViewModels.Components.ReferenceData.ParameterTypes; using COMETwebapp.ViewModels.Components.ReferenceData.Rows; @@ -53,13 +53,13 @@ namespace COMETwebapp.Tests.Pages.ReferenceData using TestContext = Bunit.TestContext; [TestFixture] - public class ReferenceDataPageTestFixture + public class ReferenceDataBodyTestFixture { private TestContext context; private Mock parameterTypesTableViewModel; private Mock measurementScalesTableViewModel; private Mock sessionService; - private IRenderedComponent renderer; + private IRenderedComponent renderer; [SetUp] public void Setup() @@ -83,9 +83,9 @@ public void Setup() this.context.Services.AddSingleton(this.parameterTypesTableViewModel.Object); this.context.Services.AddSingleton(this.measurementScalesTableViewModel.Object); this.context.Services.AddSingleton(configuration.Object); - this.context.Services.AddSingleton(); + this.context.Services.AddSingleton(new Mock().Object); - this.renderer = this.context.RenderComponent(); + this.renderer = this.context.RenderComponent(); } [TearDown] @@ -95,7 +95,7 @@ public void Teardown() } [Test] - public async Task VerifyReferenceDataPage() + public async Task VerifyReferenceDataBody() { Assert.Multiple(() => { diff --git a/COMETwebapp.Tests/Pages/SiteDirectory/SiteDirectoryPageTestFixture.cs b/COMETwebapp.Tests/Components/SiteDirectory/SiteDirectoryBodyTestFixture.cs similarity index 89% rename from COMETwebapp.Tests/Pages/SiteDirectory/SiteDirectoryPageTestFixture.cs rename to COMETwebapp.Tests/Components/SiteDirectory/SiteDirectoryBodyTestFixture.cs index 0214b115..aea49b24 100644 --- a/COMETwebapp.Tests/Pages/SiteDirectory/SiteDirectoryPageTestFixture.cs +++ b/COMETwebapp.Tests/Components/SiteDirectory/SiteDirectoryBodyTestFixture.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 @@ -22,7 +22,7 @@ // // -------------------------------------------------------------------------------------------------------------------- -namespace COMETwebapp.Tests.Pages.SiteDirectory +namespace COMETwebapp.Tests.Components.SiteDirectory { using Bunit; @@ -32,11 +32,10 @@ namespace COMETwebapp.Tests.Pages.SiteDirectory using COMET.Web.Common.Services.ConfigurationService; using COMET.Web.Common.Services.SessionManagement; using COMET.Web.Common.Test.Helpers; - using COMET.Web.Common.ViewModels.Components.Applications; using COMETwebapp.Components.SiteDirectory; using COMETwebapp.Components.SiteDirectory.EngineeringModel; - using COMETwebapp.Pages.SiteDirectory; + using COMETwebapp.ViewModels.Components.SiteDirectory; using COMETwebapp.ViewModels.Components.SiteDirectory.DomainsOfExpertise; using COMETwebapp.ViewModels.Components.SiteDirectory.EngineeringModels; using COMETwebapp.ViewModels.Components.SiteDirectory.Rows; @@ -53,13 +52,13 @@ namespace COMETwebapp.Tests.Pages.SiteDirectory using TestContext = Bunit.TestContext; [TestFixture] - public class SiteDirectoryPageTestFixture + public class SiteDirectoryBodyTestFixture { private TestContext context; private Mock engineeringModelsTableViewModel; private Mock domainsOfExpertiseTableViewModel; private Mock sessionService; - private IRenderedComponent renderer; + private IRenderedComponent renderer; [SetUp] public void Setup() @@ -83,9 +82,9 @@ public void Setup() this.context.Services.AddSingleton(this.engineeringModelsTableViewModel.Object); this.context.Services.AddSingleton(this.domainsOfExpertiseTableViewModel.Object); this.context.Services.AddSingleton(configuration.Object); - this.context.Services.AddSingleton(); + this.context.Services.AddSingleton(new Mock().Object); - this.renderer = this.context.RenderComponent(); + this.renderer = this.context.RenderComponent(); } [TearDown] @@ -95,7 +94,7 @@ public void Teardown() } [Test] - public async Task VerifySiteDirectoryPage() + public async Task VerifySiteDirectoryBody() { Assert.Multiple(() => { diff --git a/COMETwebapp.Tests/Pages/TabsTestFixture.cs b/COMETwebapp.Tests/Pages/TabsTestFixture.cs index e459bcd9..424f4b3b 100644 --- a/COMETwebapp.Tests/Pages/TabsTestFixture.cs +++ b/COMETwebapp.Tests/Pages/TabsTestFixture.cs @@ -174,9 +174,8 @@ public async Task VerifyTabCustomButton() tabToOpen = new TabbedApplicationInformation(this.engineeringModelBodyViewModel.Object, typeof(EngineeringModelBody), null); openTabs.ReplaceAt(0, tabToOpen); this.renderer.Render(); - tabCustomButton = this.renderer.FindComponents().First(x => x.Instance.Id == "tab-custom-option-button"); - await this.renderer.InvokeAsync(tabCustomButton.Instance.Click.InvokeAsync); - Assert.That(this.renderer.Instance.IsOpenTabVisible, Is.False); + var hasCustomOption = this.renderer.FindComponents().Any(x => x.Instance.Id == "tab-custom-option-button"); + Assert.That(hasCustomOption, Is.False); } [Test] diff --git a/COMETwebapp.Tests/ViewModels/Components/Common/OpenTabViewModelTestFixture.cs b/COMETwebapp.Tests/ViewModels/Components/Common/OpenTabViewModelTestFixture.cs index 2c78cc78..0aab375c 100644 --- a/COMETwebapp.Tests/ViewModels/Components/Common/OpenTabViewModelTestFixture.cs +++ b/COMETwebapp.Tests/ViewModels/Components/Common/OpenTabViewModelTestFixture.cs @@ -111,7 +111,7 @@ public async Task VerifyOpenIterationAndModel() Assert.Multiple(() => { - this.tabsViewModel.Verify(x => x.CreateNewTab(It.IsAny(), It.IsAny(), It.IsAny()), Times.Once); + this.tabsViewModel.Verify(x => x.CreateNewTab(It.IsAny(), It.IsAny(), It.IsAny()), Times.Exactly(2)); this.sessionService.Verify(x => x.ReadIteration(It.IsAny(), It.IsAny()), Times.Once); }); diff --git a/COMETwebapp/Components/ReferenceData/ReferenceDataBody.razor b/COMETwebapp/Components/ReferenceData/ReferenceDataBody.razor new file mode 100644 index 00000000..77799869 --- /dev/null +++ b/COMETwebapp/Components/ReferenceData/ReferenceDataBody.razor @@ -0,0 +1,42 @@ + +@inherits ApplicationBase + + + + + @foreach (var mappedValue in this.mapOfComponentsAndNames) + { + + } + + + + @if (this.SelectedComponent != null) + { + + } + diff --git a/COMETwebapp/Pages/ReferenceData/ReferenceDataPage.razor.cs b/COMETwebapp/Components/ReferenceData/ReferenceDataBody.razor.cs similarity index 83% rename from COMETwebapp/Pages/ReferenceData/ReferenceDataPage.razor.cs rename to COMETwebapp/Components/ReferenceData/ReferenceDataBody.razor.cs index 7baf380e..b16c3c34 100644 --- a/COMETwebapp/Pages/ReferenceData/ReferenceDataPage.razor.cs +++ b/COMETwebapp/Components/ReferenceData/ReferenceDataBody.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 @@ -22,7 +22,7 @@ // // -------------------------------------------------------------------------------------------------------------------- -namespace COMETwebapp.Pages.ReferenceData +namespace COMETwebapp.Components.ReferenceData { using COMETwebapp.Components.ReferenceData.Categories; using COMETwebapp.Components.ReferenceData.MeasurementScales; @@ -32,9 +32,9 @@ namespace COMETwebapp.Pages.ReferenceData using DevExpress.Blazor; /// - /// Support class for the + /// Core component for the Reference Data body application /// - public partial class ReferenceDataPage + public partial class ReferenceDataBody { /// /// A map with all the available components and their names @@ -70,5 +70,13 @@ private void OnItemClick(ToolbarItemClickEventArgs e) { this.SelectedComponent = this.mapOfComponentsAndNames.First(x => x.Value == e.ItemName).Key; } + + /// + /// 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) + { + } } } diff --git a/COMETwebapp/Components/SiteDirectory/SiteDirectoryBody.razor b/COMETwebapp/Components/SiteDirectory/SiteDirectoryBody.razor new file mode 100644 index 00000000..2096fcaa --- /dev/null +++ b/COMETwebapp/Components/SiteDirectory/SiteDirectoryBody.razor @@ -0,0 +1,42 @@ + +@inherits ApplicationBase + + + + + @foreach (var mappedValue in this.mapOfComponentsAndNames) + { + + } + + + + @if (this.SelectedComponent != null) + { + + } + diff --git a/COMETwebapp/Pages/SiteDirectory/DirectoryPage.razor.cs b/COMETwebapp/Components/SiteDirectory/SiteDirectoryBody.razor.cs similarity index 83% rename from COMETwebapp/Pages/SiteDirectory/DirectoryPage.razor.cs rename to COMETwebapp/Components/SiteDirectory/SiteDirectoryBody.razor.cs index f309a938..98328be0 100644 --- a/COMETwebapp/Pages/SiteDirectory/DirectoryPage.razor.cs +++ b/COMETwebapp/Components/SiteDirectory/SiteDirectoryBody.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 @@ -22,21 +22,18 @@ // // -------------------------------------------------------------------------------------------------------------------- -namespace COMETwebapp.Pages.SiteDirectory +namespace COMETwebapp.Components.SiteDirectory { - using COMETwebapp.Components.SiteDirectory; using COMETwebapp.Components.SiteDirectory.EngineeringModel; using COMETwebapp.Components.SiteDirectory.Roles; using COMETwebapp.Components.SiteDirectory.UserManagement; using DevExpress.Blazor; - using DomainsOfExpertiseTable = COMETwebapp.Components.SiteDirectory.DomainsOfExpertiseTable; - /// - /// Support class for the + /// Core component for the Server Admin (old Site Directory) body application /// - public partial class DirectoryPage + public partial class SiteDirectoryBody { /// /// A map with all the available components and their names @@ -66,6 +63,14 @@ protected override void OnInitialized() this.SelectedComponent = this.mapOfComponentsAndNames.First().Key; } + /// + /// 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) + { + } + /// /// Method invoked to set the selected component from toolbar /// diff --git a/COMETwebapp/Components/Tabs/TabComponent.razor b/COMETwebapp/Components/Tabs/TabComponent.razor index 09d92ff1..d9e3c201 100644 --- a/COMETwebapp/Components/Tabs/TabComponent.razor +++ b/COMETwebapp/Components/Tabs/TabComponent.razor @@ -36,7 +36,7 @@ @(this.Text) - @if (this.CustomOptionIcon is not null) + @if (this.CustomOptionIcon is not null && this.CustomOptionIconVisible) { + /// Gets or sets the condition to check if the should be visible + /// + [Parameter] + public bool CustomOptionIconVisible { get; set; } = true; + /// /// Gets or sets the icon to be displayed in the left, distinguishing different applications /// diff --git a/COMETwebapp/Components/Tabs/TabsPanelComponent.razor b/COMETwebapp/Components/Tabs/TabsPanelComponent.razor index ffc055a9..f774bf9b 100644 --- a/COMETwebapp/Components/Tabs/TabsPanelComponent.razor +++ b/COMETwebapp/Components/Tabs/TabsPanelComponent.razor @@ -26,32 +26,33 @@
@if (this.Handler.CurrentTab is not null) { -
- - @foreach (var tab in this.Tabs) - { - - } - - +
+
+ @foreach (var tab in this.Tabs) + { + + } + +
@if (this.IsSidePanelAvailable) { + CssClass="ml-auto p-0"> diff --git a/COMETwebapp/Components/Tabs/TabsPanelComponent.razor.cs b/COMETwebapp/Components/Tabs/TabsPanelComponent.razor.cs index b81b4d0e..a62908dd 100644 --- a/COMETwebapp/Components/Tabs/TabsPanelComponent.razor.cs +++ b/COMETwebapp/Components/Tabs/TabsPanelComponent.razor.cs @@ -106,15 +106,15 @@ public partial class TabsPanelComponent : DisposableComponent /// /// Gets the tab text for the given object of interest /// - /// The object of interest to get its tab text + /// Thetab to get its text /// The tab text - private static string GetTabText(object objectOfInterest) + private static string GetTabText(TabbedApplicationInformation tab) { - return objectOfInterest switch + return tab.ObjectOfInterest switch { Iteration iteration => iteration.QueryName(), EngineeringModel engineeringModel => engineeringModel.EngineeringModelSetup.Name, - _ => string.Empty + _ => Applications.ExistingApplications.OfType().First(x => x.ComponentType == tab.ComponentType).Name }; } @@ -142,6 +142,11 @@ private string GetCaptionText(object objectOfInterest) modelName.Append(" - "); + if (iterationOfInterest == null) + { + return modelName.ToString(); + } + var domainOfExpertiseShortName = this.SessionService.GetDomainOfExpertise(iterationOfInterest).ShortName; modelName.Append(domainOfExpertiseShortName); @@ -162,7 +167,7 @@ private void AddSidePanel() currentTab.Panel = newPanel; this.ViewModel.SidePanels.Add(newPanel); - this.ViewModel.CurrentTab = this.ViewModel.OpenTabs.Items.LastOrDefault(x => x.ComponentType == this.ViewModel.SelectedApplication.ComponentType && x.Panel == null); + this.ViewModel.CurrentTab = this.ViewModel.OpenTabs.Items.FirstOrDefault(x => x.Panel == null); } } } diff --git a/COMETwebapp/Extensions/ServiceCollectionExtensions.cs b/COMETwebapp/Extensions/ServiceCollectionExtensions.cs index 0570613a..b9127ddd 100644 --- a/COMETwebapp/Extensions/ServiceCollectionExtensions.cs +++ b/COMETwebapp/Extensions/ServiceCollectionExtensions.cs @@ -58,7 +58,9 @@ namespace COMETwebapp.Extensions using COMETwebapp.ViewModels.Components.EngineeringModel.FileStore.FileRevisionHandler; using COMETwebapp.ViewModels.Components.EngineeringModel.FileStore.FolderHandler; using COMETwebapp.ViewModels.Components.ParameterEditor.BatchParameterEditor; + using COMETwebapp.ViewModels.Components.ReferenceData; using COMETwebapp.ViewModels.Pages; + using COMETwebapp.ViewModels.Components.SiteDirectory; /// /// Extension class for the @@ -124,6 +126,8 @@ public static void RegisterViewModels(this IServiceCollection serviceCollection) serviceCollection.AddTransient(); serviceCollection.AddScoped(); serviceCollection.AddTransient(); + serviceCollection.AddTransient(); + serviceCollection.AddTransient(); } } } diff --git a/COMETwebapp/Model/Applications.cs b/COMETwebapp/Model/Applications.cs index af79db6b..92528984 100644 --- a/COMETwebapp/Model/Applications.cs +++ b/COMETwebapp/Model/Applications.cs @@ -31,6 +31,8 @@ namespace COMETwebapp.Model using COMETwebapp.Components.ModelDashboard; using COMETwebapp.Components.ModelEditor; using COMETwebapp.Components.ParameterEditor; + using COMETwebapp.Components.ReferenceData; + using COMETwebapp.Components.SiteDirectory; using COMETwebapp.Components.SubscriptionDashboard; using COMETwebapp.Components.SystemRepresentation; using COMETwebapp.Components.Viewer; @@ -131,24 +133,6 @@ private static List InitializesApplications() ComponentType = typeof(ViewerBody) }, - new Application - { - Name = "Reference Data", - Color = "#fc3a1aad", - IconType = typeof(FeatherFile), - Description = "Visualize reference data", - Url = WebAppConstantValues.ReferenceDataPage - }, - - new Application - { - Name = "Server Administration", - Color = "#fc3a1aad", - IconType = typeof(FeatherServer), - Description = "Visualize site directory data", - Url = WebAppConstantValues.SiteDirectoryPage - }, - new TabbedApplication { Name = "Engineering Model", @@ -179,6 +163,26 @@ private static List InitializesApplications() ComponentType = typeof(BookEditorBody) }, + new TabbedApplication + { + Name = "Reference Data", + Color = "#fc3a1aad", + IconType = typeof(FeatherFile), + Description = "Visualize reference data", + Url = WebAppConstantValues.ReferenceDataPage, + ComponentType = typeof(ReferenceDataBody) + }, + + new TabbedApplication + { + Name = "Server Administration", + Color = "#fc3a1aad", + IconType = typeof(FeatherServer), + Description = "Visualize site directory data", + Url = WebAppConstantValues.SiteDirectoryPage, + ComponentType = typeof(SiteDirectoryBody) + }, + new Application { Name = "Tabs", diff --git a/COMETwebapp/Pages/ReferenceData/ReferenceDataPage.razor b/COMETwebapp/Pages/ReferenceData/ReferenceDataPage.razor index 99e75981..d4e2d50d 100644 --- a/COMETwebapp/Pages/ReferenceData/ReferenceDataPage.razor +++ b/COMETwebapp/Pages/ReferenceData/ReferenceDataPage.razor @@ -20,22 +20,6 @@ Copyright (c) 2023-2024 Starion Group S.A. - - - @foreach (var mappedValue in this.mapOfComponentsAndNames) - { - - } - - - - @if (this.SelectedComponent != null) - { - - } + \ No newline at end of file diff --git a/COMETwebapp/Pages/SiteDirectory/DirectoryPage.razor b/COMETwebapp/Pages/SiteDirectory/DirectoryPage.razor index ef11f351..fe85058f 100644 --- a/COMETwebapp/Pages/SiteDirectory/DirectoryPage.razor +++ b/COMETwebapp/Pages/SiteDirectory/DirectoryPage.razor @@ -16,26 +16,11 @@ Copyright (c) 2023-2024 Starion Group S.A. -------------------------------------------------------------------------------> @attribute [Route(WebAppConstantValues.SiteDirectoryPage)] @attribute [Authorize] +@using COMETwebapp.Components.SiteDirectory @using COMETwebapp.Utilities - - - @foreach (var mappedValue in this.mapOfComponentsAndNames) - { - - } - - - - @if (this.SelectedComponent != null) - { - - } + - \ No newline at end of file + diff --git a/COMETwebapp/Pages/Tabs.razor b/COMETwebapp/Pages/Tabs.razor index 3d029b73..85e40a22 100644 --- a/COMETwebapp/Pages/Tabs.razor +++ b/COMETwebapp/Pages/Tabs.razor @@ -33,17 +33,17 @@ OnCreateTabForModel="@(tab => this.OnCreateTabForModel(tab))" OnRemoveTabClick="@(tab => this.OnRemoveTabClick(tab))" OnOpenTabClick="@(() => this.OnOpenTabClick())" - Tabs="@(this.OpenTabsFromSelectedApplication.Where(x => x.Panel == null).ToList())" + Tabs="@(this.OpenTabs.Where(x => x.Panel == null).ToList())" IsSidePanelAvailable="true"/> - @foreach (var panelsGrouping in this.OpenTabsFromSelectedApplication.Where(x => x.Panel is not null).GroupBy(x => x.Panel)) + @foreach (var panelsGrouping in this.OpenTabs.Where(x => x.Panel is not null).GroupBy(x => x.Panel)) { } } diff --git a/COMETwebapp/Pages/Tabs.razor.cs b/COMETwebapp/Pages/Tabs.razor.cs index feb2419c..22eec333 100644 --- a/COMETwebapp/Pages/Tabs.razor.cs +++ b/COMETwebapp/Pages/Tabs.razor.cs @@ -49,9 +49,9 @@ public partial class Tabs private TabPanelInformation SelectedSidePanel { get; set; } /// - /// Collection of open tabs that belong from the selected application + /// Collection of open tabs that belong from view model sourcelist /// - private IEnumerable OpenTabsFromSelectedApplication => this.ViewModel.OpenTabs.Items.Where(x => x.ComponentType == this.ViewModel.SelectedApplication?.ComponentType); + private IEnumerable OpenTabs => this.ViewModel.OpenTabs.Items; /// /// The model id to fill the opentab form, if needed diff --git a/COMETwebapp/Shared/SideBarEntry/ApplicationsSideBar.razor b/COMETwebapp/Shared/SideBarEntry/ApplicationsSideBar.razor index 5aeb5464..ad061751 100644 --- a/COMETwebapp/Shared/SideBarEntry/ApplicationsSideBar.razor +++ b/COMETwebapp/Shared/SideBarEntry/ApplicationsSideBar.razor @@ -27,10 +27,10 @@ Model
-@foreach (var applicationEntry in this.RegistrationService.RegisteredApplications.OfType().Where(x => !x.IsDisabled)) +@foreach (var applicationEntry in this.GetModelApplications()) { @@ -40,10 +40,10 @@ General
-@foreach (var applicationEntry in this.RegistrationService.RegisteredApplications.Where(x => x is not TabbedApplication && !x.IsDisabled && x.Url != WebAppConstantValues.TabsPage)) +@foreach (var applicationEntry in this.GetGeneralApplications()) { diff --git a/COMETwebapp/Shared/SideBarEntry/ApplicationsSideBar.razor.cs b/COMETwebapp/Shared/SideBarEntry/ApplicationsSideBar.razor.cs index 070f181b..00716ff6 100644 --- a/COMETwebapp/Shared/SideBarEntry/ApplicationsSideBar.razor.cs +++ b/COMETwebapp/Shared/SideBarEntry/ApplicationsSideBar.razor.cs @@ -80,7 +80,11 @@ protected override void OnInitialized() { base.OnInitialized(); this.NavigationManager.LocationChanged += this.OnLocationChanged; - this.Disposables.Add(this.WhenAnyValue(x => x.TabsViewModel.SelectedApplication).SubscribeAsync(_ => this.InvokeAsync(this.StateHasChanged))); + + this.Disposables.Add(this.WhenAnyValue(x => + x.TabsViewModel.SelectedApplication, + x => x.TabsViewModel.CurrentTab + ).SubscribeAsync(_ => this.InvokeAsync(this.StateHasChanged))); } /// @@ -109,11 +113,18 @@ private void OnLocationChanged(object sender, LocationChangedEventArgs e) /// /// Navigates to the selected tabbed application /// - /// The to navigate to - private void NavigateToTabbedApplication(TabbedApplication application) + /// The to navigate to + private void NavigateToApplication(Application application) { - this.TabsViewModel.SelectedApplication = application; - this.NavigationManager.NavigateTo(WebAppConstantValues.TabsPage); + if (application is TabbedApplication tabbedApplication) + { + this.TabsViewModel.SelectedApplication = tabbedApplication; + this.NavigationManager.NavigateTo(WebAppConstantValues.TabsPage); + } + else + { + this.NavigationManager.NavigateTo(application.Url); + } } /// @@ -150,5 +161,38 @@ private bool IsApplicationEnabled(Application application) return this.CurrentApplication != application; } + + /// + /// Gets the model s + /// + /// A collection of applications + private IEnumerable GetModelApplications() + { + return this.RegistrationService.RegisteredApplications.OfType().Where(x => !x.IsDisabled && x.ThingTypeOfInterest != null); + } + + /// + /// Gets the general s + /// + /// A collection of applications + private IEnumerable GetGeneralApplications() + { + return this.RegistrationService.RegisteredApplications.Where(x => !x.IsDisabled && x.Url != WebAppConstantValues.TabsPage && !ApplicationHasThingTypeOfInterest(x)); + } + + /// + /// Checks if an application has a thing type of interest + /// + /// The application to check + /// The value to check if the application has a thing type of interest + private static bool ApplicationHasThingTypeOfInterest(Application application) + { + if (application is not TabbedApplication tabbedApplication) + { + return false; + } + + return tabbedApplication.ThingTypeOfInterest != null; + } } } diff --git a/COMETwebapp/ViewModels/Components/Common/OpenTab/OpenTabViewModel.cs b/COMETwebapp/ViewModels/Components/Common/OpenTab/OpenTabViewModel.cs index 71d1c08d..3ddea25d 100644 --- a/COMETwebapp/ViewModels/Components/Common/OpenTab/OpenTabViewModel.cs +++ b/COMETwebapp/ViewModels/Components/Common/OpenTab/OpenTabViewModel.cs @@ -110,6 +110,12 @@ public async Task OpenTab(TabPanelInformation panel) var result = new Result(); var isIteration = this.SelectedApplication?.ThingTypeOfInterest == typeof(Iteration); + if (this.SelectedApplication?.ThingTypeOfInterest is null) + { + this.tabsViewModel.CreateNewTab(this.SelectedApplication, Guid.Empty, panel); + return; + } + if (!this.IsCurrentModelOpened) { result = await base.OpenSession(); diff --git a/COMETwebapp/ViewModels/Components/ReferenceData/IReferenceDataBodyViewModel.cs b/COMETwebapp/ViewModels/Components/ReferenceData/IReferenceDataBodyViewModel.cs new file mode 100644 index 00000000..6d92073c --- /dev/null +++ b/COMETwebapp/ViewModels/Components/ReferenceData/IReferenceDataBodyViewModel.cs @@ -0,0 +1,35 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// 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.ReferenceData +{ + using COMET.Web.Common.ViewModels.Components.Applications; + + /// + /// View Model that handle the logic for the Reference data body application + /// + public interface IReferenceDataBodyViewModel : IApplicationBaseViewModel + { + } +} diff --git a/COMETwebapp/ViewModels/Components/ReferenceData/ReferenceDataBodyViewModel.cs b/COMETwebapp/ViewModels/Components/ReferenceData/ReferenceDataBodyViewModel.cs new file mode 100644 index 00000000..0c5d8dab --- /dev/null +++ b/COMETwebapp/ViewModels/Components/ReferenceData/ReferenceDataBodyViewModel.cs @@ -0,0 +1,55 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// 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.ReferenceData +{ + using CDP4Dal; + + using COMET.Web.Common.Services.SessionManagement; + using COMET.Web.Common.ViewModels.Components.Applications; + + /// + /// View Model that handle the logic for the Reference data body application + /// + public class ReferenceDataBodyViewModel : ApplicationBaseViewModel, IReferenceDataBodyViewModel + { + /// + /// Initializes a new instance of the class. + /// + /// The + /// The + public ReferenceDataBodyViewModel(ISessionService sessionService, ICDPMessageBus messageBus) : base(sessionService, messageBus) + { + } + + /// + /// Handles the refresh of the current + /// + /// A + protected override Task OnSessionRefreshed() + { + return Task.CompletedTask; + } + } +} diff --git a/COMETwebapp/ViewModels/Components/SiteDirectory/ISiteDirectoryBodyViewModel.cs b/COMETwebapp/ViewModels/Components/SiteDirectory/ISiteDirectoryBodyViewModel.cs new file mode 100644 index 00000000..bedb5ec9 --- /dev/null +++ b/COMETwebapp/ViewModels/Components/SiteDirectory/ISiteDirectoryBodyViewModel.cs @@ -0,0 +1,35 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// 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 +{ + using COMET.Web.Common.ViewModels.Components.Applications; + + /// + /// View Model that handle the logic for the Server admin body application + /// + public interface ISiteDirectoryBodyViewModel : IApplicationBaseViewModel + { + } +} diff --git a/COMETwebapp/ViewModels/Components/SiteDirectory/SiteDirectoryBodyViewModel.cs b/COMETwebapp/ViewModels/Components/SiteDirectory/SiteDirectoryBodyViewModel.cs new file mode 100644 index 00000000..46d74c61 --- /dev/null +++ b/COMETwebapp/ViewModels/Components/SiteDirectory/SiteDirectoryBodyViewModel.cs @@ -0,0 +1,55 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// 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 +{ + using CDP4Dal; + + using COMET.Web.Common.Services.SessionManagement; + using COMET.Web.Common.ViewModels.Components.Applications; + + /// + /// View Model that handle the logic for the Server admin body application + /// + public class SiteDirectoryBodyViewModel : ApplicationBaseViewModel, ISiteDirectoryBodyViewModel + { + /// + /// Initializes a new instance of the class. + /// + /// The + /// The + public SiteDirectoryBodyViewModel(ISessionService sessionService, ICDPMessageBus messageBus) : base(sessionService, messageBus) + { + } + + /// + /// Handles the refresh of the current + /// + /// A + protected override Task OnSessionRefreshed() + { + return Task.CompletedTask; + } + } +} diff --git a/COMETwebapp/ViewModels/Pages/TabsViewModel.cs b/COMETwebapp/ViewModels/Pages/TabsViewModel.cs index bacfe704..eb7c8175 100644 --- a/COMETwebapp/ViewModels/Pages/TabsViewModel.cs +++ b/COMETwebapp/ViewModels/Pages/TabsViewModel.cs @@ -71,6 +71,7 @@ public TabsViewModel(ISessionService sessionService, IServiceProvider servicePro this.sessionService = sessionService; this.serviceProvider = serviceProvider; this.Disposables.Add(this.WhenAnyValue(x => x.SelectedApplication).Subscribe(_ => this.OnSelectedApplicationChange())); + this.Disposables.Add(this.WhenAnyValue(x => x.CurrentTab).Subscribe(_ => this.OnCurrentTabChange())); this.Disposables.Add(this.sessionService.OpenIterations.CountChanged.Subscribe(this.CloseTabIfIterationClosed)); this.Disposables.Add(this.OpenTabs.Connect().WhereReasonsAre(ListChangeReason.Remove, ListChangeReason.RemoveRange).Subscribe(this.OnOpenTabRemoved)); } @@ -138,12 +139,7 @@ public void CreateNewTab(TabbedApplication application, Guid objectOfInterestId, } var tabToCreate = new TabbedApplicationInformation(viewModel, application.ComponentType, thingOfInterest); - - if (thingOfInterest != null) - { - this.OpenTabs.Add(tabToCreate); - } - + this.OpenTabs.Add(tabToCreate); this.SelectedApplication = application; if (sidePanel == null) @@ -162,7 +158,7 @@ public void CreateNewTab(TabbedApplication application, Guid objectOfInterestId, /// private void OnSelectedApplicationChange() { - if (this.SelectedApplication == null) + if (this.SelectedApplication == null || this.CurrentTab?.ComponentType == this.SelectedApplication?.ComponentType) { return; } @@ -170,6 +166,19 @@ private void OnSelectedApplicationChange() this.CurrentTab = this.OpenTabs.Items.FirstOrDefault(x => x.ComponentType == this.SelectedApplication.ComponentType && x.Panel == null); } + /// + /// Method executed everytime the changes + /// + private void OnCurrentTabChange() + { + if (this.CurrentTab == null) + { + return; + } + + this.SelectedApplication = Applications.ExistingApplications.OfType().FirstOrDefault(x => x.ComponentType == this.CurrentTab.ComponentType); + } + /// /// Closes a tab if its iteration has been closed /// @@ -236,7 +245,7 @@ private void SetCurrentTabAfterTabRemoval(IChangeSet x.ComponentType == this.SelectedApplication.ComponentType && x.Panel == selectedSidePanel); + handler.CurrentTab = this.OpenTabs.Items.FirstOrDefault(x => x.Panel == selectedSidePanel); } if (selectedSidePanel != null && handler.CurrentTab == null)