diff --git a/COMET.Web.Common.Tests/Components/Applications/SingleEngineeringModelApplicationTemplateTestFixture.cs b/COMET.Web.Common.Tests/Components/Applications/SingleEngineeringModelApplicationTemplateTestFixture.cs index f96bc8fe..ddfcbdc9 100644 --- a/COMET.Web.Common.Tests/Components/Applications/SingleEngineeringModelApplicationTemplateTestFixture.cs +++ b/COMET.Web.Common.Tests/Components/Applications/SingleEngineeringModelApplicationTemplateTestFixture.cs @@ -37,6 +37,7 @@ namespace COMET.Web.Common.Tests.Components.Applications using COMET.Web.Common.Components.Applications; using COMET.Web.Common.Components.Selectors; using COMET.Web.Common.Model.Configuration; + using COMET.Web.Common.Services.Cache; using COMET.Web.Common.Services.ConfigurationService; using COMET.Web.Common.Services.SessionManagement; using COMET.Web.Common.Services.StringTableService; @@ -70,6 +71,7 @@ public void Setup() this.viewModel = new Mock(); this.openEngineeringModels = []; + var cacheService = new Mock(); var sessionService = new Mock(); sessionService.Setup(x => x.OpenEngineeringModels).Returns(this.openEngineeringModels); sessionService.Setup(x => x.OpenIterations).Returns(new SourceList()); @@ -84,6 +86,7 @@ public void Setup() this.context.Services.AddSingleton(mockConfigurationService.Object); this.context.Services.AddSingleton(new Mock().Object); this.context.Services.AddSingleton(sessionService.Object); + this.context.Services.AddSingleton(cacheService.Object); this.context.ConfigureDevExpressBlazor(); } diff --git a/COMET.Web.Common.Tests/Components/Applications/SingleIterationApplicationTemplateTestFixture.cs b/COMET.Web.Common.Tests/Components/Applications/SingleIterationApplicationTemplateTestFixture.cs index 22d432fa..729e4326 100644 --- a/COMET.Web.Common.Tests/Components/Applications/SingleIterationApplicationTemplateTestFixture.cs +++ b/COMET.Web.Common.Tests/Components/Applications/SingleIterationApplicationTemplateTestFixture.cs @@ -38,6 +38,7 @@ namespace COMET.Web.Common.Tests.Components.Applications using COMET.Web.Common.Components.Selectors; using COMET.Web.Common.Extensions; using COMET.Web.Common.Model.Configuration; + using COMET.Web.Common.Services.Cache; using COMET.Web.Common.Services.ConfigurationService; using COMET.Web.Common.Services.SessionManagement; using COMET.Web.Common.Services.StringTableService; @@ -61,6 +62,7 @@ namespace COMET.Web.Common.Tests.Components.Applications public class SingleIterationApplicationTemplateTestFixture { private Mock viewModel; + private Mock cacheService; private SourceList openIterations; private TestContext context; private ICDPMessageBus messageBus; @@ -72,6 +74,7 @@ public void Setup() this.context = new TestContext(); this.openIterations = new SourceList(); this.viewModel = new Mock(); + this.cacheService = new Mock(); var sessionService = new Mock(); sessionService.Setup(x => x.OpenIterations).Returns(this.openIterations); var session = new Mock(); @@ -86,6 +89,7 @@ public void Setup() this.context.Services.AddSingleton(mockConfigurationService.Object); this.context.Services.AddSingleton(new Mock().Object); this.context.Services.AddSingleton(sessionService.Object); + this.context.Services.AddSingleton(this.cacheService.Object); this.context.Services.AddSingleton(this.messageBus); this.context.ConfigureDevExpressBlazor(); } diff --git a/COMET.Web.Common.Tests/Components/IndexComponentTestFixture.cs b/COMET.Web.Common.Tests/Components/IndexComponentTestFixture.cs index f9522088..f4e0f132 100644 --- a/COMET.Web.Common.Tests/Components/IndexComponentTestFixture.cs +++ b/COMET.Web.Common.Tests/Components/IndexComponentTestFixture.cs @@ -39,6 +39,7 @@ namespace COMET.Web.Common.Tests.Components using COMET.Web.Common.Extensions; using COMET.Web.Common.Model; using COMET.Web.Common.Model.Configuration; + using COMET.Web.Common.Services.Cache; using COMET.Web.Common.Services.ConfigurationService; using COMET.Web.Common.Services.RegistrationService; using COMET.Web.Common.Services.SessionManagement; @@ -64,6 +65,7 @@ public class IndexComponentTestFixture { private IIndexViewModel viewModel; private TestContext context; + private Mock cacheService; private Mock versionService; private Mock sessionService; private Mock serverConnectionService; @@ -80,6 +82,7 @@ public void Setup() this.versionService = new Mock(); this.sessionService = new Mock(); this.serverConnectionService = new Mock(); + this.cacheService = new Mock(); var serverConfiguration = new ServerConfiguration { FullTrustConfiguration = new FullTrustConfiguration() }; this.serverConnectionService.Setup(x => x.ServerConfiguration).Returns(serverConfiguration); this.sourceList = new SourceList(); @@ -100,6 +103,7 @@ public void Setup() this.context.Services.AddSingleton(); this.context.Services.AddSingleton(); this.context.Services.AddSingleton(this.registrationService.Object); + this.context.Services.AddSingleton(this.cacheService.Object); this.context.ConfigureDevExpressBlazor(); this.authorization = this.context.AddTestAuthorization(); diff --git a/COMET.Web.Common.Tests/Components/OpenModelTestFixture.cs b/COMET.Web.Common.Tests/Components/OpenModelTestFixture.cs index a40e21a3..4dd98989 100644 --- a/COMET.Web.Common.Tests/Components/OpenModelTestFixture.cs +++ b/COMET.Web.Common.Tests/Components/OpenModelTestFixture.cs @@ -31,6 +31,7 @@ namespace COMET.Web.Common.Tests.Components using CDP4Common.SiteDirectoryData; using COMET.Web.Common.Components; + using COMET.Web.Common.Services.Cache; using COMET.Web.Common.Services.ConfigurationService; using COMET.Web.Common.Services.SessionManagement; using COMET.Web.Common.Services.StringTableService; @@ -57,6 +58,7 @@ public class OpenModelTestFixture private TestContext context; private Mock sessionService; private Mock configurationService; + private Mock cacheService; [SetUp] public void Setup() @@ -64,7 +66,8 @@ public void Setup() this.context = new TestContext(); this.sessionService = new Mock(); this.configurationService = new Mock(); - this.viewModel = new OpenModelViewModel(this.sessionService.Object, this.configurationService.Object); + this.cacheService = new Mock(); + this.viewModel = new OpenModelViewModel(this.sessionService.Object, this.configurationService.Object, this.cacheService.Object); this.context.ConfigureDevExpressBlazor(); this.context.Services.AddSingleton(this.viewModel); diff --git a/COMET.Web.Common.Tests/Services/CacheService/CacheServiceTestFixture.cs b/COMET.Web.Common.Tests/Services/CacheService/CacheServiceTestFixture.cs new file mode 100644 index 00000000..0c2cdb5d --- /dev/null +++ b/COMET.Web.Common.Tests/Services/CacheService/CacheServiceTestFixture.cs @@ -0,0 +1,116 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2023-2024 Starion Group S.A. +// +// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, Nabil Abbar +// +// This file is part of CDP4-COMET WEB Community Edition +// The CDP4-COMET WEB Community Edition is the Starion Web Application implementation of ECSS-E-TM-10-25 +// Annex A and Annex C. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +// -------------------------------------------------------------------------------------------------------------------- + + +namespace COMET.Web.Common.Tests.Services.CacheService +{ + using CDP4Common.EngineeringModelData; + + using COMET.Web.Common.Enumerations; + using COMET.Web.Common.Services.Cache; + + using NUnit.Framework; + + [TestFixture] + public class CacheServiceTestFixture + { + private CacheService cacheService; + + [SetUp] + public void Setup() + { + this.cacheService = new CacheService(); + } + + [Test] + public void VerifyAddNewKey() + { + var engineeringModel = new EngineeringModel(); + var browserSessionSettingKey = BrowserSessionSettingKey.LastUsedEngineeringModel; + + Assert.That(() => this.cacheService.AddOrUpdateBrowserSessionSetting(browserSessionSettingKey, engineeringModel), Throws.Nothing); + + Assert.That(this.cacheService.TryGetBrowserSessionSetting(browserSessionSettingKey, out var result), Is.True); + + Assert.That(result, Is.EqualTo(engineeringModel)); + } + + [Test] + public void VerifyKeyDoesNotExistWorksAsExpected() + { + var browserSessionSettingKey = BrowserSessionSettingKey.LastUsedEngineeringModel; + + Assert.That(this.cacheService.TryGetBrowserSessionSetting(browserSessionSettingKey, out var result), Is.False); + + Assert.That(result, Is.Null); + } + + [Test] + public void VerifyOverwriteExistingKey() + { + var engineeringModel1 = new EngineeringModel(); + var browserSessionSettingKey = BrowserSessionSettingKey.LastUsedEngineeringModel; + + Assert.That(() => this.cacheService.AddOrUpdateBrowserSessionSetting(browserSessionSettingKey, engineeringModel1), Throws.Nothing); + + Assert.That(this.cacheService.TryGetBrowserSessionSetting(browserSessionSettingKey, out var result), Is.True); + + Assert.That(result, Is.EqualTo(engineeringModel1)); + + var engineeringModel2 = new EngineeringModel(); + + Assert.That(() => this.cacheService.AddOrUpdateBrowserSessionSetting(browserSessionSettingKey, engineeringModel2), Throws.Nothing); + + Assert.That(this.cacheService.TryGetBrowserSessionSetting(browserSessionSettingKey, out var result2), Is.True); + + Assert.That(result2, Is.EqualTo(engineeringModel2)); + } + + [Test] + public void VerifyGetOrAddKey() + { + var engineeringModel1 = new EngineeringModel(); + var browserSessionSettingKey = BrowserSessionSettingKey.LastUsedEngineeringModel; + + Assert.That(this.cacheService.TryGetOrAddBrowserSessionSetting(browserSessionSettingKey, engineeringModel1, out var result), Is.True); + + Assert.That(result, Is.EqualTo(engineeringModel1)); + + Assert.That(this.cacheService.TryGetBrowserSessionSetting(browserSessionSettingKey, out var result2), Is.True); + + Assert.That(result2, Is.EqualTo(engineeringModel1)); + + var engineeringModel2 = new EngineeringModel(); + + Assert.That(this.cacheService.TryGetOrAddBrowserSessionSetting(browserSessionSettingKey, engineeringModel2, out var result3), Is.True); + + Assert.That(result3, Is.EqualTo(engineeringModel1)); + + Assert.That(this.cacheService.TryGetBrowserSessionSetting(browserSessionSettingKey, out var result4), Is.True); + + Assert.That(result4, Is.EqualTo(engineeringModel1)); + } + } +} diff --git a/COMET.Web.Common.Tests/ViewModels/Components/OpenModelViewModelTestFixture.cs b/COMET.Web.Common.Tests/ViewModels/Components/OpenModelViewModelTestFixture.cs index d84d6e38..b5fb14bf 100644 --- a/COMET.Web.Common.Tests/ViewModels/Components/OpenModelViewModelTestFixture.cs +++ b/COMET.Web.Common.Tests/ViewModels/Components/OpenModelViewModelTestFixture.cs @@ -28,7 +28,10 @@ namespace COMET.Web.Common.Tests.ViewModels.Components using CDP4Common.EngineeringModelData; using CDP4Common.SiteDirectoryData; + using COMET.Web.Common.Enumerations; + using COMET.Web.Common.Model; using COMET.Web.Common.Model.Configuration; + using COMET.Web.Common.Services.Cache; using COMET.Web.Common.Services.ConfigurationService; using COMET.Web.Common.Services.SessionManagement; using COMET.Web.Common.ViewModels.Components; @@ -45,6 +48,7 @@ public class OpenModelViewModelTestFixture private OpenModelViewModel viewModel; private Mock configurationService; private Mock sessionService; + private Mock cacheService; private const string RdlShortName = "filterRdl"; private List models; @@ -53,12 +57,20 @@ public void Setup() { this.configurationService = new Mock(); this.sessionService = new Mock(); + this.cacheService = new Mock(); var iterations = new SourceList(); this.sessionService.Setup(x => x.OpenIterations).Returns(iterations); - this.viewModel = new OpenModelViewModel(this.sessionService.Object, this.configurationService.Object); + this.viewModel = new OpenModelViewModel(this.sessionService.Object, this.configurationService.Object, this.cacheService.Object); this.models = CreateData().ToList(); this.sessionService.Setup(x => x.GetParticipantModels()).Returns(this.models); + + object result; + this.cacheService.Setup(x => x.TryGetBrowserSessionSetting(BrowserSessionSettingKey.LastUsedDomainOfExpertise, out result)).Returns(false); + + this.cacheService.Setup(x => x.TryGetBrowserSessionSetting(BrowserSessionSettingKey.LastUsedEngineeringModel, out result)).Returns(false); + + this.cacheService.Setup(x => x.TryGetBrowserSessionSetting(BrowserSessionSettingKey.LastUsedIterationData, out result)).Returns(false); } [Test] @@ -98,7 +110,32 @@ public void VerifyInitializeViewModel() serverConfiguration.RdlFilter.Kinds = new[] { EngineeringModelKind.STUDY_MODEL }; serverConfiguration.RdlFilter.RdlShortNames = Enumerable.Empty(); this.viewModel.InitializesProperties(); - Assert.That(this.viewModel.AvailableEngineeringModelSetups.Count(), Is.EqualTo(4)); + Assert.That(this.viewModel.AvailableEngineeringModelSetups.Count(), Is.EqualTo(4)); + } + + [Test] + public void VerifyInitializeViewModelWithBrowserSessionSettings() + { + //Initialize without server configuration + this.viewModel.InitializesProperties(); + Assert.That(this.viewModel.AvailableEngineeringModelSetups.Count(), Is.EqualTo(5)); + + var preselectedEngineeringModel = this.viewModel.AvailableEngineeringModelSetups.First(); + + object domainOfExpertise = new DomainOfExpertise(Guid.NewGuid(), null, null); + object engineeringModelSetup = preselectedEngineeringModel; + object iterationData = new IterationData(preselectedEngineeringModel.IterationSetup.First()); + + this.cacheService.Setup(x => x.TryGetBrowserSessionSetting(BrowserSessionSettingKey.LastUsedDomainOfExpertise, out domainOfExpertise)).Returns(true); + + this.cacheService.Setup(x => x.TryGetBrowserSessionSetting(BrowserSessionSettingKey.LastUsedEngineeringModel, out engineeringModelSetup)).Returns(true); + + this.cacheService.Setup(x => x.TryGetBrowserSessionSetting(BrowserSessionSettingKey.LastUsedIterationData, out iterationData)).Returns(true); + + this.viewModel.InitializesProperties(); + Assert.That(this.viewModel.SelectedEngineeringModel, Is.EqualTo(engineeringModelSetup)); + Assert.That(this.viewModel.SelectedIterationSetup, Is.EqualTo(iterationData)); + Assert.That(this.viewModel.SelectedDomainOfExpertise, Is.EqualTo(domainOfExpertise)); } private static List CreateData() diff --git a/COMET.Web.Common/Enumerations/BrowserSessionSettingKey.cs b/COMET.Web.Common/Enumerations/BrowserSessionSettingKey.cs new file mode 100644 index 00000000..fb575ed6 --- /dev/null +++ b/COMET.Web.Common/Enumerations/BrowserSessionSettingKey.cs @@ -0,0 +1,50 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// 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 COMET.Web.Common.Enumerations +{ + using CDP4Common.EngineeringModelData; + using CDP4Common.SiteDirectoryData; + + /// + /// En enumeration of possible keys to be used to store and retrieve cached BrowserSessionSettings + /// + public enum BrowserSessionSettingKey + { + /// + /// Key to handle the last selected + /// + LastUsedEngineeringModel, + + /// + /// Key to handle the last selected + /// + LastUsedIterationData, + + /// + /// Key to handle the last selected + /// + LastUsedDomainOfExpertise + } +} diff --git a/COMET.Web.Common/Extensions/ServiceCollectionExtensions.cs b/COMET.Web.Common/Extensions/ServiceCollectionExtensions.cs index 67f4a180..04b48574 100644 --- a/COMET.Web.Common/Extensions/ServiceCollectionExtensions.cs +++ b/COMET.Web.Common/Extensions/ServiceCollectionExtensions.cs @@ -32,6 +32,7 @@ namespace COMET.Web.Common.Extensions using COMET.Web.Common.Model; using COMET.Web.Common.Server.Services.ConfigurationService; using COMET.Web.Common.Server.Services.StringTableService; + using COMET.Web.Common.Services.Cache; using COMET.Web.Common.Services.ConfigurationService; using COMET.Web.Common.Services.NotificationService; using COMET.Web.Common.Services.RegistrationService; @@ -87,6 +88,7 @@ public static void RegisterCdp4CometCommonServices(this IServiceCollection servi serviceProvider.AddScoped(); serviceProvider.AddScoped(); serviceProvider.AddSingleton(); + serviceProvider.AddScoped(); serviceProvider.AddAuthorizationCore(); serviceProvider.AddDevExpressBlazor(configure => configure.SizeMode = SizeMode.Medium); serviceProvider.RegisterCommonViewModels(); diff --git a/COMET.Web.Common/Services/Cache/CacheService.cs b/COMET.Web.Common/Services/Cache/CacheService.cs new file mode 100644 index 00000000..630c1b3e --- /dev/null +++ b/COMET.Web.Common/Services/Cache/CacheService.cs @@ -0,0 +1,86 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// 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 COMET.Web.Common.Services.Cache +{ + using System.Collections.Concurrent; + + using COMET.Web.Common.Enumerations; + + /// + /// Handles cached data for (re) use in the application + /// + public class CacheService : ICacheService + { + /// + /// Holds all the settings that can be used during the browser session's lifetime to make the user's experience better + /// + private readonly ConcurrentDictionary browserSessionSettings = new(); + + /// + /// Tries to get a stored value in the BrowserSessionSettings Dictionary + /// + /// The key of the BrowserSessionSetting + /// The value linked to the BrowserSessionSetting key in + /// true if the setting was found + public bool TryGetBrowserSessionSetting(BrowserSessionSettingKey browserSessionSettingKeyKey, out object browserSessionSettingvalue) + { + if (this.browserSessionSettings.TryGetValue(browserSessionSettingKeyKey, out browserSessionSettingvalue)) + { + return browserSessionSettingvalue != null; + } + + return false; + } + + /// + /// Tries to get a stored value in the BrowserSessionSettings Dictionary and adds a new value if not present yet + /// + /// The key of the BrowserSessionSetting + /// The default value to return if the key of the BrowserSessionSetting value that will be returned and stored if the BrowserSessionSetting key was not present in yet + /// The value linked to the BrowserSessionSetting key in + /// true if the setting was found + public bool TryGetOrAddBrowserSessionSetting(BrowserSessionSettingKey browserSessionSettingKeyKey, object defaultBrowserSessionSettingValue, out object browserSessionSettingvalue) + { + if (!this.browserSessionSettings.TryGetValue(browserSessionSettingKeyKey, out browserSessionSettingvalue)) + { + this.AddOrUpdateBrowserSessionSetting(browserSessionSettingKeyKey, defaultBrowserSessionSettingValue); + + this.browserSessionSettings.TryGetValue(browserSessionSettingKeyKey, out browserSessionSettingvalue); + } + + return browserSessionSettingvalue != null; + } + + /// + /// Store a value in the BrowserSessionSettings Dictionary. Overwrites the value if the key already exists + /// + /// The key of the BrowserSessionSetting + /// The value to store in the BrowserSessionSetting dictionary for a specific key + public void AddOrUpdateBrowserSessionSetting(BrowserSessionSettingKey browserSessionSettingKeyKey, object browserSessionSettingValue) + { + this.browserSessionSettings.AddOrUpdate(browserSessionSettingKeyKey, x => browserSessionSettingValue, (_, _) => browserSessionSettingValue); + } + } +} diff --git a/COMET.Web.Common/Services/Cache/ICacheService.cs b/COMET.Web.Common/Services/Cache/ICacheService.cs new file mode 100644 index 00000000..94fbbb93 --- /dev/null +++ b/COMET.Web.Common/Services/Cache/ICacheService.cs @@ -0,0 +1,58 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2023-2024 Starion Group S.A. +// +// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, João Rua +// +// This file is part of 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 COMET.Web.Common.Services.Cache; + +using COMET.Web.Common.Enumerations; + +/// +/// Defines the properties and methods of a class that implements the interface +/// +public interface ICacheService +{ + /// + /// Tries to get a stored value in the BrowserSessionSettings Dictionary + /// + /// The key of the BrowserSessionSetting + /// The value linked to the BrowserSessionSetting key in + /// true if the setting was found + bool TryGetBrowserSessionSetting(BrowserSessionSettingKey browserSessionSettingKeyKey, out object browserSessionSettingvalue); + + /// + /// Tries to get a stored value in the BrowserSessionSettings Dictionary and adds a new value if not present yet + /// + /// The key of the BrowserSessionSetting + /// The default value to return if the key of the BrowserSessionSetting value that will be returned and stored if the BrowserSessionSetting key was not present in yet + /// The value linked to the BrowserSessionSetting key in + /// true if the setting was found + bool TryGetOrAddBrowserSessionSetting(BrowserSessionSettingKey browserSessionSettingKeyKey, object defaultBrowserSessionSettingValue, out object browserSessionSettingvalue); + + /// + /// Tries to store a value in the BrowserSessionSettings Dictionary. Overwrites the value if it already exists + /// + /// The key of the BrowserSessionSetting + /// The value to store in the BrowserSessionSetting dictionary for a specific key + /// true if the setting was added + void AddOrUpdateBrowserSessionSetting(BrowserSessionSettingKey browserSessionSettingKeyKey, object browserSessionSettingValue); +} diff --git a/COMET.Web.Common/ViewModels/Components/OpenModelViewModel.cs b/COMET.Web.Common/ViewModels/Components/OpenModelViewModel.cs index 735ad160..170f5ddb 100644 --- a/COMET.Web.Common/ViewModels/Components/OpenModelViewModel.cs +++ b/COMET.Web.Common/ViewModels/Components/OpenModelViewModel.cs @@ -31,7 +31,9 @@ namespace COMET.Web.Common.ViewModels.Components using CDP4Common.EngineeringModelData; using CDP4Common.SiteDirectoryData; + using COMET.Web.Common.Enumerations; using COMET.Web.Common.Model; + using COMET.Web.Common.Services.Cache; using COMET.Web.Common.Services.ConfigurationService; using COMET.Web.Common.Services.SessionManagement; using COMET.Web.Common.Utilities.DisposableObject; @@ -57,6 +59,11 @@ public class OpenModelViewModel : DisposableObject, IOpenModelViewModel /// private readonly IConfigurationService configurationService; + /// + /// Gets the + /// + protected readonly ICacheService cacheService; + /// /// Backing field for /// @@ -81,10 +88,12 @@ public class OpenModelViewModel : DisposableObject, IOpenModelViewModel /// /// The /// The - public OpenModelViewModel(ISessionService sessionService, IConfigurationService configurationService) + /// The + public OpenModelViewModel(ISessionService sessionService, IConfigurationService configurationService, ICacheService cacheService) { this.sessionService = sessionService; this.configurationService = configurationService; + this.cacheService = cacheService; this.Disposables.Add(this.WhenAnyPropertyChanged(nameof(this.SelectedEngineeringModel)) .Subscribe(_ => this.ComputeAvailableCollections())); @@ -149,6 +158,23 @@ public void InitializesProperties() this.SelectedDomainOfExpertise = null; this.SelectedEngineeringModel = null; this.SelectedIterationSetup = null; + + if (this.cacheService.TryGetBrowserSessionSetting(BrowserSessionSettingKey.LastUsedEngineeringModel, out var engineeringModelSetup)) + { + this.selectedEngineeringModel = engineeringModelSetup as EngineeringModelSetup; + this.SetAvailableDomainOfEpertiseAndIterationSetups(); + } + + if (this.cacheService.TryGetBrowserSessionSetting(BrowserSessionSettingKey.LastUsedIterationData, out var iterationData)) + { + this.selectedIterationSetup = iterationData as IterationData; + } + + if (this.cacheService.TryGetBrowserSessionSetting(BrowserSessionSettingKey.LastUsedDomainOfExpertise, out var domainOfExpertise)) + { + this.selectedDomainOfExpertise = domainOfExpertise as DomainOfExpertise; + } + this.IsOpeningSession = false; var availableEngineeringModelSetups = this.sessionService.GetParticipantModels() @@ -214,16 +240,19 @@ public virtual async Task> OpenSession() /// The of the to select public void PreSelectIteration(Guid modelId, Guid iterationId, Guid domainId) { - this.selectedEngineeringModel = this.sessionService.OpenEngineeringModels.FirstOrDefault(x => x.Iid == modelId)?.EngineeringModelSetup; - var iterationSetup = this.SelectedEngineeringModel?.IterationSetup.Find(x => x.IterationIid == iterationId); - - if (iterationSetup != null) + if (!this.cacheService.TryGetBrowserSessionSetting(BrowserSessionSettingKey.LastUsedIterationData, out _)) { - this.SelectedIterationSetup = new IterationData(iterationSetup); - } + this.selectedEngineeringModel = this.sessionService.OpenEngineeringModels.FirstOrDefault(x => x.Iid == modelId)?.EngineeringModelSetup; + var iterationSetup = this.SelectedEngineeringModel?.IterationSetup.Find(x => x.IterationIid == iterationId); - this.AvailablesDomainOfExpertises = this.sessionService.GetModelDomains(this.SelectedEngineeringModel); - this.SelectedDomainOfExpertise = this.AvailablesDomainOfExpertises.FirstOrDefault(x => x.Iid == domainId); + if (iterationSetup != null) + { + this.SelectedIterationSetup = new IterationData(iterationSetup); + } + + this.AvailablesDomainOfExpertises = this.sessionService.GetModelDomains(this.SelectedEngineeringModel); + this.SelectedDomainOfExpertise = this.AvailablesDomainOfExpertises.FirstOrDefault(x => x.Iid == domainId); + } } /// @@ -241,12 +270,8 @@ private void ComputeAvailableCollections() else { this.SelectedDomainOfExpertise = this.SelectedEngineeringModel.ActiveDomain.Find(x => x == this.sessionService.Session.ActivePerson.DefaultDomain); - this.AvailablesDomainOfExpertises = this.sessionService.GetModelDomains(this.SelectedEngineeringModel); - this.AvailableIterationSetups = this.SelectedEngineeringModel.IterationSetup - .Where(x => this.sessionService.OpenIterations.Items.All(i => i.Iid != x.IterationIid)) - .OrderBy(x => x.IterationNumber) - .Select(x => new IterationData(x)); + this.SetAvailableDomainOfEpertiseAndIterationSetups(); this.SelectedIterationSetup = this.AvailableIterationSetups.LastOrDefault(); @@ -259,5 +284,18 @@ private void ComputeAvailableCollections() this.SelectedIterationSetup = new IterationData(currentModelIteration); } } + + /// + /// Sets the and + /// + private void SetAvailableDomainOfEpertiseAndIterationSetups() + { + this.AvailablesDomainOfExpertises = this.sessionService.GetModelDomains(this.SelectedEngineeringModel); + + this.AvailableIterationSetups = this.SelectedEngineeringModel.IterationSetup + .Where(x => this.sessionService.OpenIterations.Items.All(i => i.Iid != x.IterationIid)) + .OrderBy(x => x.IterationNumber) + .Select(x => new IterationData(x)); + } } } diff --git a/COMETwebapp.Tests/Pages/ModelDashboard/ModelDashboardTestFixture.cs b/COMETwebapp.Tests/Pages/ModelDashboard/ModelDashboardTestFixture.cs index 283dbab0..1b8569da 100644 --- a/COMETwebapp.Tests/Pages/ModelDashboard/ModelDashboardTestFixture.cs +++ b/COMETwebapp.Tests/Pages/ModelDashboard/ModelDashboardTestFixture.cs @@ -35,6 +35,7 @@ namespace COMETwebapp.Tests.Pages.ModelDashboard using COMET.Web.Common.Components.Selectors; using COMET.Web.Common.Extensions; using COMET.Web.Common.Model.Configuration; + using COMET.Web.Common.Services.Cache; using COMET.Web.Common.Services.ConfigurationService; using COMET.Web.Common.Services.SessionManagement; using COMET.Web.Common.Services.StringTableService; @@ -66,6 +67,7 @@ public class ModelDashboardTestFixture private TestContext context; private ISingleIterationApplicationTemplateViewModel viewModel; private Mock sessionService; + private Mock cacheService; private SourceList openedIterations; private Mock session; private Iteration firstIteration; @@ -77,6 +79,7 @@ public void Setup() { this.context = new TestContext(); this.sessionService = new Mock(); + this.cacheService = new Mock(); this.openedIterations = new SourceList(); this.sessionService.Setup(x => x.OpenIterations).Returns(this.openedIterations); this.viewModel = new SingleIterationApplicationTemplateViewModel(this.sessionService.Object, new IterationSelectorViewModel()); @@ -121,6 +124,7 @@ public void Setup() this.context.ConfigureDevExpressBlazor(); this.context.Services.AddSingleton(this.viewModel); this.context.Services.AddSingleton(this.sessionService.Object); + this.context.Services.AddSingleton(this.cacheService.Object); this.context.Services.AddSingleton(mockConfigurationService.Object); this.context.Services.AddSingleton(); this.context.Services.AddSingleton(); diff --git a/COMETwebapp.Tests/Pages/ParameterEditor/ParameterEditorTestFixture.cs b/COMETwebapp.Tests/Pages/ParameterEditor/ParameterEditorTestFixture.cs index 625085f9..c338f20b 100644 --- a/COMETwebapp.Tests/Pages/ParameterEditor/ParameterEditorTestFixture.cs +++ b/COMETwebapp.Tests/Pages/ParameterEditor/ParameterEditorTestFixture.cs @@ -35,6 +35,7 @@ namespace COMETwebapp.Tests.Pages.ParameterEditor using COMET.Web.Common.Components.Selectors; using COMET.Web.Common.Extensions; using COMET.Web.Common.Model.Configuration; + using COMET.Web.Common.Services.Cache; using COMET.Web.Common.Services.ConfigurationService; using COMET.Web.Common.Services.NotificationService; using COMET.Web.Common.Services.SessionManagement; @@ -69,6 +70,7 @@ public class ParameterEditorTestFixture private TestContext context; private ISingleIterationApplicationTemplateViewModel viewModel; private Mock sessionService; + private Mock cacheService; private SourceList openedIterations; private Mock session; private Iteration firstIteration; @@ -80,6 +82,7 @@ public void Setup() { this.context = new TestContext(); this.sessionService = new Mock(); + this.cacheService = new Mock(); this.openedIterations = new SourceList(); this.sessionService.Setup(x => x.OpenIterations).Returns(this.openedIterations); this.viewModel = new SingleIterationApplicationTemplateViewModel(this.sessionService.Object, new IterationSelectorViewModel()); @@ -139,6 +142,7 @@ public void Setup() this.context.ConfigureDevExpressBlazor(); this.context.Services.AddSingleton(this.viewModel); this.context.Services.AddSingleton(this.sessionService.Object); + this.context.Services.AddSingleton(this.cacheService.Object); this.context.Services.AddSingleton(mockConfigurationService.Object); this.context.Services.AddSingleton(parameterEditorBodyViewModel.Object); this.context.Services.AddSingleton(parameterTableViewModel.Object); diff --git a/COMETwebapp.Tests/Pages/Viewer/ViewerTestFixture.cs b/COMETwebapp.Tests/Pages/Viewer/ViewerTestFixture.cs index b0969c62..02c5effc 100644 --- a/COMETwebapp.Tests/Pages/Viewer/ViewerTestFixture.cs +++ b/COMETwebapp.Tests/Pages/Viewer/ViewerTestFixture.cs @@ -35,6 +35,7 @@ namespace COMETwebapp.Tests.Pages.Viewer using COMET.Web.Common.Components.Selectors; using COMET.Web.Common.Extensions; using COMET.Web.Common.Model.Configuration; + using COMET.Web.Common.Services.Cache; using COMET.Web.Common.Services.ConfigurationService; using COMET.Web.Common.Services.SessionManagement; using COMET.Web.Common.Services.StringTableService; @@ -70,6 +71,7 @@ public class ViewerTestFixture private ISingleIterationApplicationTemplateViewModel viewModel; private Mock sessionService; private SourceList openedIterations; + private Mock cacheService; private Mock session; private Iteration firstIteration; private Iteration secondIteration; @@ -80,6 +82,7 @@ public void Setup() { this.context = new TestContext(); this.sessionService = new Mock(); + this.cacheService = new Mock(); this.openedIterations = new SourceList(); this.sessionService.Setup(x => x.OpenIterations).Returns(this.openedIterations); this.viewModel = new SingleIterationApplicationTemplateViewModel(this.sessionService.Object, new IterationSelectorViewModel()); @@ -125,6 +128,7 @@ public void Setup() this.context.ConfigureDevExpressBlazor(); this.context.Services.AddSingleton(this.viewModel); this.context.Services.AddSingleton(this.sessionService.Object); + this.context.Services.AddSingleton(this.cacheService.Object); this.context.Services.AddSingleton(); this.context.Services.AddSingleton(); this.context.Services.AddSingleton(); diff --git a/COMETwebapp.Tests/ViewModels/Components/Common/OpenTabViewModelTestFixture.cs b/COMETwebapp.Tests/ViewModels/Components/Common/OpenTabViewModelTestFixture.cs index 0aab375c..27974a0c 100644 --- a/COMETwebapp.Tests/ViewModels/Components/Common/OpenTabViewModelTestFixture.cs +++ b/COMETwebapp.Tests/ViewModels/Components/Common/OpenTabViewModelTestFixture.cs @@ -28,6 +28,7 @@ namespace COMETwebapp.Tests.ViewModels.Components.Common using CDP4Common.SiteDirectoryData; using COMET.Web.Common.Model; + using COMET.Web.Common.Services.Cache; using COMET.Web.Common.Services.ConfigurationService; using COMET.Web.Common.Services.SessionManagement; @@ -48,6 +49,7 @@ namespace COMETwebapp.Tests.ViewModels.Components.Common public class OpenTabViewModelTestFixture { private OpenTabViewModel viewModel; + private Mock cacheService; private Mock sessionService; private Mock configurationService; private Mock tabsViewModel; @@ -57,6 +59,7 @@ public void Setup() { this.sessionService = new Mock(); this.configurationService = new Mock(); + this.cacheService = new Mock(); this.tabsViewModel = new Mock(); var id = Guid.NewGuid(); @@ -81,7 +84,7 @@ public void Setup() this.sessionService.Setup(x => x.ReadEngineeringModels(It.IsAny>())).Returns(Task.FromResult(new Result())); this.sessionService.Setup(x => x.ReadIteration(It.IsAny(), It.IsAny())).Returns(Task.FromResult(new Result())); - this.viewModel = new OpenTabViewModel(this.sessionService.Object, this.configurationService.Object, this.tabsViewModel.Object); + this.viewModel = new OpenTabViewModel(this.sessionService.Object, this.configurationService.Object, this.tabsViewModel.Object, this.cacheService.Object); } [TearDown] diff --git a/COMETwebapp.Tests/ViewModels/Pages/TabsViewModelTestFixture.cs b/COMETwebapp.Tests/ViewModels/Pages/TabsViewModelTestFixture.cs index cdcbd973..4599e09f 100644 --- a/COMETwebapp.Tests/ViewModels/Pages/TabsViewModelTestFixture.cs +++ b/COMETwebapp.Tests/ViewModels/Pages/TabsViewModelTestFixture.cs @@ -26,6 +26,7 @@ namespace COMETwebapp.Tests.ViewModels.Pages { using CDP4Common.EngineeringModelData; + using COMET.Web.Common.Services.Cache; using COMET.Web.Common.Services.SessionManagement; using COMET.Web.Common.ViewModels.Components.Applications; @@ -47,6 +48,7 @@ public class TabsViewModelTestFixture private TabsViewModel viewModel; private Mock sessionService; private Mock serviceProvider; + private Mock cacheService; private SourceList openIterations; [SetUp] @@ -54,6 +56,7 @@ public void Setup() { this.serviceProvider = new Mock(); this.sessionService = new Mock(); + this.cacheService = new Mock(); this.openIterations = new SourceList(); this.openIterations.Add(new Iteration()); @@ -62,7 +65,7 @@ public void Setup() this.sessionService.Setup(x => x.OpenEngineeringModels).Returns(engineeringModels); this.serviceProvider.Setup(x => x.GetService(It.IsAny())).Returns(new Mock().Object); - this.viewModel = new TabsViewModel(this.sessionService.Object, this.serviceProvider.Object); + this.viewModel = new TabsViewModel(this.sessionService.Object, this.serviceProvider.Object, this.cacheService.Object); } [Test] diff --git a/COMETwebapp/ViewModels/Components/Common/OpenTab/OpenTabViewModel.cs b/COMETwebapp/ViewModels/Components/Common/OpenTab/OpenTabViewModel.cs index 3ddea25d..236f0916 100644 --- a/COMETwebapp/ViewModels/Components/Common/OpenTab/OpenTabViewModel.cs +++ b/COMETwebapp/ViewModels/Components/Common/OpenTab/OpenTabViewModel.cs @@ -27,6 +27,8 @@ namespace COMETwebapp.ViewModels.Components.Common.OpenTab using CDP4Common.EngineeringModelData; using CDP4Common.SiteDirectoryData; + using COMET.Web.Common.Enumerations; + using COMET.Web.Common.Services.Cache; using COMET.Web.Common.Services.ConfigurationService; using COMET.Web.Common.Services.SessionManagement; using COMET.Web.Common.ViewModels.Components; @@ -64,7 +66,8 @@ public class OpenTabViewModel : OpenModelViewModel, IOpenTabViewModel /// The /// The /// The - public OpenTabViewModel(ISessionService sessionService, IConfigurationService configurationService, ITabsViewModel tabsViewModel) : base(sessionService, configurationService) + /// + public OpenTabViewModel(ISessionService sessionService, IConfigurationService configurationService, ITabsViewModel tabsViewModel, ICacheService cacheService) : base(sessionService, configurationService, cacheService) { this.sessionService = sessionService; this.tabsViewModel = tabsViewModel; @@ -128,6 +131,12 @@ public async Task OpenTab(TabPanelInformation panel) } } + this.cacheService.AddOrUpdateBrowserSessionSetting(BrowserSessionSettingKey.LastUsedIterationData, this.SelectedIterationSetup); + + this.cacheService.AddOrUpdateBrowserSessionSetting(BrowserSessionSettingKey.LastUsedDomainOfExpertise, this.SelectedDomainOfExpertise); + + this.cacheService.AddOrUpdateBrowserSessionSetting(BrowserSessionSettingKey.LastUsedEngineeringModel, this.SelectedEngineeringModel); + if (result.IsSuccess) { this.tabsViewModel.CreateNewTab(this.SelectedApplication, isIteration ? this.SelectedEngineeringModelIteration.Iid : this.SelectedEngineeringModel.EngineeringModelIid, panel); diff --git a/COMETwebapp/ViewModels/Pages/TabsViewModel.cs b/COMETwebapp/ViewModels/Pages/TabsViewModel.cs index 5565d515..ca1354d4 100644 --- a/COMETwebapp/ViewModels/Pages/TabsViewModel.cs +++ b/COMETwebapp/ViewModels/Pages/TabsViewModel.cs @@ -26,6 +26,7 @@ namespace COMETwebapp.ViewModels.Pages { using CDP4Common.EngineeringModelData; + using COMET.Web.Common.Services.Cache; using COMET.Web.Common.Services.SessionManagement; using COMET.Web.Common.Utilities.DisposableObject; using COMET.Web.Common.ViewModels.Components.Applications; @@ -61,7 +62,8 @@ public class TabsViewModel : DisposableObject, ITabsViewModel /// /// The /// The - public TabsViewModel(ISessionService sessionService, IServiceProvider serviceProvider) + /// The + public TabsViewModel(ISessionService sessionService, IServiceProvider serviceProvider, ICacheService cacheService) { this.sessionService = sessionService; this.serviceProvider = serviceProvider;