From 396c4054ea9f99e4fea7e8fbb8c7d903ffbf8f71 Mon Sep 17 00:00:00 2001 From: andreastanderen <71079896+standeren@users.noreply.github.com> Date: Tue, 18 Jun 2024 09:05:34 +0200 Subject: [PATCH] 12735 update endpoint that sets datatype for process task to accept array of data types (#12865) * Change data type in body to be list * Add tests * Fix PR comments --- .../Controllers/ProcessModelingController.cs | 13 +- ...TypesChangedApplicationMetadataHandler.cs} | 17 +- ...ocessDataTypesChangedLayoutSetsHandler.cs} | 15 +- ...ent.cs => ProcessDataTypesChangedEvent.cs} | 5 +- .../src/Designer/Models/Dto/DataTypeChange.cs | 6 +- .../LayoutSetsFileSyncDataTypeTests.cs | 143 ------------- ...licationMetadataFileSyncDataTypesTests.cs} | 72 +++++-- .../LayoutSetsFileSyncDataTypesTests.cs | 198 ++++++++++++++++++ ... => ProcessDataTypesChangedNotifyTests.cs} | 10 +- .../features/processEditor/ProcessEditor.tsx | 14 +- .../useUpdateProcessDataTypesMutation.test.ts | 55 +++++ ...s => useUpdateProcessDataTypesMutation.ts} | 9 +- .../Tabs/AboutTab/AboutTab.test.tsx | 2 +- frontend/language/src/nb.json | 2 +- .../process-editor/src/ProcessEditor.test.tsx | 2 +- .../process-editor/src/ProcessEditor.tsx | 10 +- .../ConfigContent/ConfigContent.tsx | 4 +- .../EditTaskId/EditTaskId.test.tsx | 16 +- .../ConfigContent/EditTaskId/EditTaskId.tsx | 8 +- .../CreateCustomReceiptForm.test.tsx | 5 +- .../CustomReceipt/CustomReceipt.test.tsx | 10 +- .../CustomReceipt/CustomReceipt.tsx | 4 +- .../EditDataType/SelectDataType/index.ts | 1 - .../ConfigPanel/EditDataType/index.ts | 1 - .../EditDataTypes.module.css} | 0 .../EditDataTypes.test.tsx} | 24 +-- .../EditDataTypes.tsx} | 12 +- .../SelectDataTypes.module.css} | 0 .../SelectDataTypes/SelectDataTypes.test.tsx} | 62 +++--- .../SelectDataTypes/SelectDataTypes.tsx} | 19 +- .../EditDataTypes/SelectDataTypes/index.ts | 1 + .../ConfigPanel/EditDataTypes/index.ts | 1 + .../src/contexts/BpmnApiContext.tsx | 8 +- .../contexts/BpmnConfigPanelContext.test.tsx | 20 +- .../src/contexts/BpmnConfigPanelContext.tsx | 10 +- .../src/hooks/useBpmnEditor.test.tsx | 2 +- .../process-editor/src/hooks/useBpmnEditor.ts | 4 +- .../test/mocks/bpmnContextMock.ts | 2 +- frontend/packages/shared/src/api/mutations.ts | 6 +- frontend/packages/shared/src/api/paths.js | 4 +- .../VersionControlButtons.test.tsx | 2 +- .../src/hooks/queries/useRepoMetadataQuery.ts | 2 +- .../packages/shared/src/mocks/queriesMock.ts | 2 +- ...pmnMetaDataForm.ts => BpmnMetadataForm.ts} | 2 +- .../packages/shared/src/types/QueryKey.ts | 2 +- .../shared/src/types/api/DataTypeChange.ts | 4 - .../shared/src/types/api/DataTypesChange.ts | 4 + .../useAddItemToLayoutMutation.test.ts | 6 +- .../useAddItemToLayoutMutation.test.ts | 6 +- 49 files changed, 486 insertions(+), 341 deletions(-) rename backend/src/Designer/EventHandlers/{ProcessDataTypeChanged/ProcessDataTypeChangedApplicationMetadataHandler.cs => ProcessDataTypesChanged/ProcessDataTypesChangedApplicationMetadataHandler.cs} (72%) rename backend/src/Designer/EventHandlers/{ProcessDataTypeChanged/ProcessDataTypeChangedLayoutSetsHandler.cs => ProcessDataTypesChanged/ProcessDataTypesChangedLayoutSetsHandler.cs} (70%) rename backend/src/Designer/Events/{ProcessDataTypeChangedEvent.cs => ProcessDataTypesChangedEvent.cs} (59%) delete mode 100644 backend/tests/Designer.Tests/Controllers/ProcessModelingController/FileSync/DataTypeChangeTests/LayoutSetsFileSyncDataTypeTests.cs rename backend/tests/Designer.Tests/Controllers/ProcessModelingController/FileSync/{DataTypeChangeTests/ApplicationMetadataFileSyncDataTypeTests.cs => DataTypesChangeTests/ApplicationMetadataFileSyncDataTypesTests.cs} (59%) create mode 100644 backend/tests/Designer.Tests/Controllers/ProcessModelingController/FileSync/DataTypesChangeTests/LayoutSetsFileSyncDataTypesTests.cs rename backend/tests/Designer.Tests/Controllers/ProcessModelingController/{ProcessDataTypeChangedNotifyTests.cs => ProcessDataTypesChangedNotifyTests.cs} (75%) create mode 100644 frontend/app-development/hooks/mutations/useUpdateProcessDataTypesMutation.test.ts rename frontend/app-development/hooks/mutations/{useUpdateProcessDataTypeMutation.ts => useUpdateProcessDataTypesMutation.ts} (52%) delete mode 100644 frontend/packages/process-editor/src/components/ConfigPanel/EditDataType/SelectDataType/index.ts delete mode 100644 frontend/packages/process-editor/src/components/ConfigPanel/EditDataType/index.ts rename frontend/packages/process-editor/src/components/ConfigPanel/{EditDataType/EditDataType.module.css => EditDataTypes/EditDataTypes.module.css} (100%) rename frontend/packages/process-editor/src/components/ConfigPanel/{EditDataType/EditDataType.test.tsx => EditDataTypes/EditDataTypes.test.tsx} (93%) rename frontend/packages/process-editor/src/components/ConfigPanel/{EditDataType/EditDataType.tsx => EditDataTypes/EditDataTypes.tsx} (89%) rename frontend/packages/process-editor/src/components/ConfigPanel/{EditDataType/SelectDataType/SelectDataType.module.css => EditDataTypes/SelectDataTypes/SelectDataTypes.module.css} (100%) rename frontend/packages/process-editor/src/components/ConfigPanel/{EditDataType/SelectDataType/SelectDataType.test.tsx => EditDataTypes/SelectDataTypes/SelectDataTypes.test.tsx} (70%) rename frontend/packages/process-editor/src/components/ConfigPanel/{EditDataType/SelectDataType/SelectDataType.tsx => EditDataTypes/SelectDataTypes/SelectDataTypes.tsx} (83%) create mode 100644 frontend/packages/process-editor/src/components/ConfigPanel/EditDataTypes/SelectDataTypes/index.ts create mode 100644 frontend/packages/process-editor/src/components/ConfigPanel/EditDataTypes/index.ts rename frontend/packages/shared/src/types/{BpmnMetaDataForm.ts => BpmnMetadataForm.ts} (77%) delete mode 100644 frontend/packages/shared/src/types/api/DataTypeChange.ts create mode 100644 frontend/packages/shared/src/types/api/DataTypesChange.ts diff --git a/backend/src/Designer/Controllers/ProcessModelingController.cs b/backend/src/Designer/Controllers/ProcessModelingController.cs index 6c85d01485b..2a759502301 100644 --- a/backend/src/Designer/Controllers/ProcessModelingController.cs +++ b/backend/src/Designer/Controllers/ProcessModelingController.cs @@ -106,19 +106,18 @@ await _mediator.Publish(new ProcessTaskIdChangedEvent return Accepted(); } - [HttpPut("data-type")] - public async Task ProcessDataTypeChangedNotify(string org, string repo, [FromBody] DataTypeChange dataTypeChange, CancellationToken cancellationToken) + [HttpPut("data-types")] + public async Task ProcessDataTypesChangedNotify(string org, string repo, [FromBody] DataTypesChange dataTypesChange, CancellationToken cancellationToken) { string developer = AuthenticationHelper.GetDeveloperUserName(HttpContext); var editingContext = AltinnRepoEditingContext.FromOrgRepoDeveloper(org, repo, developer); - if (dataTypeChange is not null) + if (dataTypesChange is not null) { - - await _mediator.Publish(new ProcessDataTypeChangedEvent + await _mediator.Publish(new ProcessDataTypesChangedEvent { - NewDataType = dataTypeChange.NewDataType, - ConnectedTaskId = dataTypeChange.ConnectedTaskId, + NewDataTypes = dataTypesChange.NewDataTypes, + ConnectedTaskId = dataTypesChange.ConnectedTaskId, EditingContext = editingContext }, cancellationToken); } diff --git a/backend/src/Designer/EventHandlers/ProcessDataTypeChanged/ProcessDataTypeChangedApplicationMetadataHandler.cs b/backend/src/Designer/EventHandlers/ProcessDataTypesChanged/ProcessDataTypesChangedApplicationMetadataHandler.cs similarity index 72% rename from backend/src/Designer/EventHandlers/ProcessDataTypeChanged/ProcessDataTypeChangedApplicationMetadataHandler.cs rename to backend/src/Designer/EventHandlers/ProcessDataTypesChanged/ProcessDataTypesChangedApplicationMetadataHandler.cs index 674877a02ab..b2b692dc93a 100644 --- a/backend/src/Designer/EventHandlers/ProcessDataTypeChanged/ProcessDataTypeChangedApplicationMetadataHandler.cs +++ b/backend/src/Designer/EventHandlers/ProcessDataTypesChanged/ProcessDataTypesChangedApplicationMetadataHandler.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Altinn.Platform.Storage.Interface.Models; @@ -8,19 +9,19 @@ namespace Altinn.Studio.Designer.EventHandlers.ProcessDataTypeChanged; -public class ProcessDataTypeChangedApplicationMetadataHandler : INotificationHandler +public class ProcessDataTypesChangedApplicationMetadataHandler : INotificationHandler { private readonly IAltinnGitRepositoryFactory _altinnGitRepositoryFactory; private readonly IFileSyncHandlerExecutor _fileSyncHandlerExecutor; - public ProcessDataTypeChangedApplicationMetadataHandler(IAltinnGitRepositoryFactory altinnGitRepositoryFactory, + public ProcessDataTypesChangedApplicationMetadataHandler(IAltinnGitRepositoryFactory altinnGitRepositoryFactory, IFileSyncHandlerExecutor fileSyncHandlerExecutor) { _altinnGitRepositoryFactory = altinnGitRepositoryFactory; _fileSyncHandlerExecutor = fileSyncHandlerExecutor; } - public async Task Handle(ProcessDataTypeChangedEvent notification, CancellationToken cancellationToken) + public async Task Handle(ProcessDataTypesChangedEvent notification, CancellationToken cancellationToken) { await _fileSyncHandlerExecutor.ExecuteWithExceptionHandling( notification.EditingContext, @@ -34,7 +35,7 @@ await _fileSyncHandlerExecutor.ExecuteWithExceptionHandling( var applicationMetadata = await repository.GetApplicationMetadata(cancellationToken); - if (notification.ConnectedTaskId != Constants.General.CustomReceiptId && TryChangeDataType(applicationMetadata, notification.NewDataType, notification.ConnectedTaskId)) + if (notification.ConnectedTaskId != Constants.General.CustomReceiptId && TryChangeDataTypes(applicationMetadata, notification.NewDataTypes, notification.ConnectedTaskId)) { await repository.SaveApplicationMetadata(applicationMetadata); } @@ -46,18 +47,18 @@ await _fileSyncHandlerExecutor.ExecuteWithExceptionHandling( /// If there are changes, the application metadata is updated and the method returns true. /// Otherwise, the method returns false. /// - private static bool TryChangeDataType(Application applicationMetadata, string newDataType, string connectedTaskId) + private static bool TryChangeDataTypes(Application applicationMetadata, List newDataTypes, string connectedTaskId) { bool hasChanges = false; - var dataTypeToDisconnect = applicationMetadata.DataTypes.Find(dataType => dataType.TaskId == connectedTaskId); - if (dataTypeToDisconnect is not null) + var dataTypesToDisconnect = applicationMetadata.DataTypes.FindAll(dataType => dataType.TaskId == connectedTaskId); + foreach (var dataTypeToDisconnect in dataTypesToDisconnect) { dataTypeToDisconnect.TaskId = null; hasChanges = true; } - if (!string.IsNullOrEmpty(newDataType)) + foreach (string newDataType in newDataTypes) { var dataTypeToUpdate = applicationMetadata.DataTypes.Find(dataType => dataType.Id == newDataType); // Only update taskId on appMetaData dataType if the new connected dataType for the layout set exists in appMetaData diff --git a/backend/src/Designer/EventHandlers/ProcessDataTypeChanged/ProcessDataTypeChangedLayoutSetsHandler.cs b/backend/src/Designer/EventHandlers/ProcessDataTypesChanged/ProcessDataTypesChangedLayoutSetsHandler.cs similarity index 70% rename from backend/src/Designer/EventHandlers/ProcessDataTypeChanged/ProcessDataTypeChangedLayoutSetsHandler.cs rename to backend/src/Designer/EventHandlers/ProcessDataTypesChanged/ProcessDataTypesChangedLayoutSetsHandler.cs index 575186f99e4..f3242777ca9 100644 --- a/backend/src/Designer/EventHandlers/ProcessDataTypeChanged/ProcessDataTypeChangedLayoutSetsHandler.cs +++ b/backend/src/Designer/EventHandlers/ProcessDataTypesChanged/ProcessDataTypesChangedLayoutSetsHandler.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Altinn.Studio.Designer.Events; @@ -8,19 +9,19 @@ namespace Altinn.Studio.Designer.EventHandlers.ProcessDataTypeChanged; -public class ProcessDataTypeChangedLayoutSetsHandler : INotificationHandler +public class ProcessDataTypesChangedLayoutSetsHandler : INotificationHandler { private readonly IAltinnGitRepositoryFactory _altinnGitRepositoryFactory; private readonly IFileSyncHandlerExecutor _fileSyncHandlerExecutor; - public ProcessDataTypeChangedLayoutSetsHandler(IAltinnGitRepositoryFactory altinnGitRepositoryFactory, + public ProcessDataTypesChangedLayoutSetsHandler(IAltinnGitRepositoryFactory altinnGitRepositoryFactory, IFileSyncHandlerExecutor fileSyncHandlerExecutor) { _altinnGitRepositoryFactory = altinnGitRepositoryFactory; _fileSyncHandlerExecutor = fileSyncHandlerExecutor; } - public async Task Handle(ProcessDataTypeChangedEvent notification, CancellationToken cancellationToken) + public async Task Handle(ProcessDataTypesChangedEvent notification, CancellationToken cancellationToken) { await _fileSyncHandlerExecutor.ExecuteWithExceptionHandling( notification.EditingContext, @@ -39,20 +40,20 @@ await _fileSyncHandlerExecutor.ExecuteWithExceptionHandling( } var layoutSets = await repository.GetLayoutSetsFile(cancellationToken); - if (TryChangeDataType(layoutSets, notification.NewDataType, notification.ConnectedTaskId)) + if (TryChangeDataTypes(layoutSets, notification.NewDataTypes, notification.ConnectedTaskId)) { await repository.SaveLayoutSets(layoutSets); } }); } - private static bool TryChangeDataType(LayoutSets layoutSets, string newDataType, string connectedTaskId) + private static bool TryChangeDataTypes(LayoutSets layoutSets, List newDataTypes, string connectedTaskId) { bool hasChanges = false; var layoutSet = layoutSets.Sets?.Find(layoutSet => layoutSet.Tasks[0] == connectedTaskId); - if (layoutSet is not null) + if (layoutSet is not null && !newDataTypes.Contains(layoutSet.DataType)) { - layoutSet.DataType = newDataType; + layoutSet.DataType = newDataTypes[0]; hasChanges = true; } diff --git a/backend/src/Designer/Events/ProcessDataTypeChangedEvent.cs b/backend/src/Designer/Events/ProcessDataTypesChangedEvent.cs similarity index 59% rename from backend/src/Designer/Events/ProcessDataTypeChangedEvent.cs rename to backend/src/Designer/Events/ProcessDataTypesChangedEvent.cs index 8d483516639..2f786ade1f6 100644 --- a/backend/src/Designer/Events/ProcessDataTypeChangedEvent.cs +++ b/backend/src/Designer/Events/ProcessDataTypesChangedEvent.cs @@ -1,11 +1,12 @@ +using System.Collections.Generic; using Altinn.Studio.Designer.Models; using MediatR; namespace Altinn.Studio.Designer.Events; -public class ProcessDataTypeChangedEvent : INotification +public class ProcessDataTypesChangedEvent : INotification { - public string NewDataType { get; set; } + public List NewDataTypes { get; set; } public string ConnectedTaskId { get; set; } public AltinnRepoEditingContext EditingContext { get; set; } } diff --git a/backend/src/Designer/Models/Dto/DataTypeChange.cs b/backend/src/Designer/Models/Dto/DataTypeChange.cs index f80b9087f9b..2ad267c8bd3 100644 --- a/backend/src/Designer/Models/Dto/DataTypeChange.cs +++ b/backend/src/Designer/Models/Dto/DataTypeChange.cs @@ -1,7 +1,9 @@ +using System.Collections.Generic; + namespace Altinn.Studio.Designer.Models.Dto; -public class DataTypeChange +public class DataTypesChange { - public string NewDataType { get; set; } + public List NewDataTypes { get; set; } public string ConnectedTaskId { get; set; } } diff --git a/backend/tests/Designer.Tests/Controllers/ProcessModelingController/FileSync/DataTypeChangeTests/LayoutSetsFileSyncDataTypeTests.cs b/backend/tests/Designer.Tests/Controllers/ProcessModelingController/FileSync/DataTypeChangeTests/LayoutSetsFileSyncDataTypeTests.cs deleted file mode 100644 index ec903ef1f87..00000000000 --- a/backend/tests/Designer.Tests/Controllers/ProcessModelingController/FileSync/DataTypeChangeTests/LayoutSetsFileSyncDataTypeTests.cs +++ /dev/null @@ -1,143 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Net.Http; -using System.Text; -using System.Text.Json; -using System.Threading.Tasks; -using Altinn.App.Core.Models; -using Altinn.Studio.Designer.Models.Dto; -using Designer.Tests.Controllers.ApiTests; -using Designer.Tests.Utils; -using FluentAssertions; -using Microsoft.AspNetCore.Mvc.Testing; -using SharedResources.Tests; -using Xunit; - -namespace Designer.Tests.Controllers.ProcessModelingController.FileSync.DataTypeChangeTests; - -public class LayoutSetsFileSyncDataTypeTests : DisagnerEndpointsTestsBase, IClassFixture> -{ - private static string VersionPrefix(string org, string repository) => - $"/designer/api/{org}/{repository}/process-modelling/data-type"; - - public LayoutSetsFileSyncDataTypeTests(WebApplicationFactory factory) : base(factory) - { - } - - [Theory] - [MemberData(nameof(ProcessDataTypeChangedNotifyTestData))] - public async Task ProcessDataTypeChangedNotify_Task1DisconnectedFromDataType_ShouldSyncLayoutSets(string org, string app, string developer, - string layoutSetsPath, DataTypeChange dataTypeChange) - { - string targetRepository = TestDataHelper.GenerateTestRepoName(); - await CopyRepositoryForTest(org, app, developer, targetRepository); - await AddFileToRepo(layoutSetsPath, "App/ui/layout-sets.json"); - - string url = VersionPrefix(org, targetRepository); - - string dataTypeChangeString = JsonSerializer.Serialize(dataTypeChange, - new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); - using var httpRequestMessage = new HttpRequestMessage(HttpMethod.Put, url) - { - Content = new StringContent(dataTypeChangeString, Encoding.UTF8, "application/json") - }; - using var response = await HttpClient.SendAsync(httpRequestMessage); - response.StatusCode.Should().Be(HttpStatusCode.Accepted); - - string layoutSetsFromRepo = - TestDataHelper.GetFileFromRepo(org, targetRepository, developer, "App/ui/layout-sets.json"); - - LayoutSets layoutSets = JsonSerializer.Deserialize(layoutSetsFromRepo, new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); - - layoutSets.Sets.Find(set => set.Tasks[0] == dataTypeChange.ConnectedTaskId).DataType.Should().BeNull(); - } - - [Theory] - [MemberData(nameof(ProcessDataTypeChangedNotifyTestData))] - public async Task ProcessDataTypeChangedNotify_NewDataTypeForTask5IsMessage_ShouldSyncLayoutSets(string org, string app, string developer, string layoutSetsPath, DataTypeChange dataTypeChange) - { - string targetRepository = TestDataHelper.GenerateTestRepoName(); - await CopyRepositoryForTest(org, app, developer, targetRepository); - await AddFileToRepo(layoutSetsPath, "App/ui/layout-sets.json"); - string dataTypeToConnect = "message"; - string task = "Task_5"; - dataTypeChange.NewDataType = dataTypeToConnect; - dataTypeChange.ConnectedTaskId = task; - - string url = VersionPrefix(org, targetRepository); - - string dataTypeChangeString = JsonSerializer.Serialize(dataTypeChange, - new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); - using var httpRequestMessage = new HttpRequestMessage(HttpMethod.Put, url) - { - Content = new StringContent(dataTypeChangeString, Encoding.UTF8, "application/json") - }; - using var response = await HttpClient.SendAsync(httpRequestMessage); - response.StatusCode.Should().Be(HttpStatusCode.Accepted); - - string layoutSetsFromRepo = - TestDataHelper.GetFileFromRepo(org, targetRepository, developer, "App/ui/layout-sets.json"); - - LayoutSets layoutSets = JsonSerializer.Deserialize(layoutSetsFromRepo, new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); - - layoutSets.Sets.Find(set => set.Tasks[0] == task).DataType.Should().Be(dataTypeToConnect); - } - - [Theory] - [MemberData(nameof(ProcessDataTypeChangedNotifyTestData))] - public async Task ProcessDataTypeChangedNotify_NewDataTypeForCustomReceipt_ShouldSyncLayoutSets(string org, string app, string developer, string layoutSetsPath, DataTypeChange dataTypeChange) - { - string targetRepository = TestDataHelper.GenerateTestRepoName(); - await CopyRepositoryForTest(org, app, developer, targetRepository); - await AddFileToRepo(layoutSetsPath, "App/ui/layout-sets.json"); - string dataTypeToConnect = "message"; - string task = "CustomReceipt"; - dataTypeChange.NewDataType = dataTypeToConnect; - dataTypeChange.ConnectedTaskId = task; - - string url = VersionPrefix(org, targetRepository); - - string dataTypeChangeString = JsonSerializer.Serialize(dataTypeChange, - new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); - using var httpRequestMessage = new HttpRequestMessage(HttpMethod.Put, url) - { - Content = new StringContent(dataTypeChangeString, Encoding.UTF8, "application/json") - }; - using var response = await HttpClient.SendAsync(httpRequestMessage); - response.StatusCode.Should().Be(HttpStatusCode.Accepted); - - string layoutSetsFromRepo = - TestDataHelper.GetFileFromRepo(org, targetRepository, developer, "App/ui/layout-sets.json"); - - LayoutSets layoutSets = JsonSerializer.Deserialize(layoutSetsFromRepo, new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); - - layoutSets.Sets.Find(set => set.Tasks[0] == task).DataType.Should().Be(dataTypeToConnect); - } - - public static IEnumerable ProcessDataTypeChangedNotifyTestData() - { - yield return - [ - "ttd", - "empty-app", - "testUser", - "App/ui/layout-sets.json", - new DataTypeChange { NewDataType = null, ConnectedTaskId = "Task_1" } - ]; - } - - private async Task AddFileToRepo(string fileToCopyPath, string relativeCopyRepoLocation) - { - string fileContent = SharedResourcesHelper.LoadTestDataAsString(fileToCopyPath); - string filePath = Path.Combine(TestRepoPath, relativeCopyRepoLocation); - string folderPath = Path.GetDirectoryName(filePath); - if (!Directory.Exists(folderPath)) - { - Directory.CreateDirectory(folderPath); - } - - await File.WriteAllTextAsync(filePath, fileContent); - } - -} diff --git a/backend/tests/Designer.Tests/Controllers/ProcessModelingController/FileSync/DataTypeChangeTests/ApplicationMetadataFileSyncDataTypeTests.cs b/backend/tests/Designer.Tests/Controllers/ProcessModelingController/FileSync/DataTypesChangeTests/ApplicationMetadataFileSyncDataTypesTests.cs similarity index 59% rename from backend/tests/Designer.Tests/Controllers/ProcessModelingController/FileSync/DataTypeChangeTests/ApplicationMetadataFileSyncDataTypeTests.cs rename to backend/tests/Designer.Tests/Controllers/ProcessModelingController/FileSync/DataTypesChangeTests/ApplicationMetadataFileSyncDataTypesTests.cs index 4e9d5a2c53c..5ad458fd257 100644 --- a/backend/tests/Designer.Tests/Controllers/ProcessModelingController/FileSync/DataTypeChangeTests/ApplicationMetadataFileSyncDataTypeTests.cs +++ b/backend/tests/Designer.Tests/Controllers/ProcessModelingController/FileSync/DataTypesChangeTests/ApplicationMetadataFileSyncDataTypesTests.cs @@ -14,19 +14,19 @@ using SharedResources.Tests; using Xunit; -namespace Designer.Tests.Controllers.ProcessModelingController.FileSync.DataTypeChangeTests; +namespace Designer.Tests.Controllers.ProcessModelingController.FileSync.DataTypesChangeTests; -public class ApplicationMetadataFileSyncDataTypeTests : DisagnerEndpointsTestsBase, IClassFixture> +public class ApplicationMetadataFileSyncDataTypesTests : DisagnerEndpointsTestsBase, IClassFixture> { - private static string VersionPrefix(string org, string repository) => $"/designer/api/{org}/{repository}/process-modelling/data-type"; + private static string VersionPrefix(string org, string repository) => $"/designer/api/{org}/{repository}/process-modelling/data-types"; - public ApplicationMetadataFileSyncDataTypeTests(WebApplicationFactory factory) : base(factory) + public ApplicationMetadataFileSyncDataTypesTests(WebApplicationFactory factory) : base(factory) { } [Theory] [MemberData(nameof(ProcessDataTypeChangedNotifyTestData))] - public async Task ProcessDataTypeChangedNotify_TaskIsDisConnectedFromDataType_ShouldSyncApplicationMetadata(string org, string app, string developer, string applicationMetadataPath, DataTypeChange dataTypeChange) + public async Task ProcessDataTypesChangedNotify_TaskIsDisConnectedFromDataType_ShouldSyncApplicationMetadata(string org, string app, string developer, string applicationMetadataPath, DataTypesChange dataTypesChange) { string targetRepository = TestDataHelper.GenerateTestRepoName(); await CopyRepositoryForTest(org, app, developer, targetRepository); @@ -34,7 +34,7 @@ public async Task ProcessDataTypeChangedNotify_TaskIsDisConnectedFromDataType_Sh string url = VersionPrefix(org, targetRepository); - string dataTypeChangeString = JsonSerializer.Serialize(dataTypeChange, + string dataTypeChangeString = JsonSerializer.Serialize(dataTypesChange, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); using var httpRequestMessage = new HttpRequestMessage(HttpMethod.Put, url) @@ -48,29 +48,29 @@ public async Task ProcessDataTypeChangedNotify_TaskIsDisConnectedFromDataType_Sh ApplicationMetadata applicationMetadata = JsonSerializer.Deserialize(applicationMetadataFromRepo, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); - applicationMetadata.DataTypes.Should().NotContain(dataType => dataType.AppLogic != null && dataType.TaskId == dataTypeChange.ConnectedTaskId); // No data type connected to Task_1 + applicationMetadata.DataTypes.Should().NotContain(dataType => dataType.AppLogic != null && dataType.TaskId == dataTypesChange.ConnectedTaskId); // No data type connected to Task_1 } [Theory] [MemberData(nameof(ProcessDataTypeChangedNotifyTestData))] - public async Task ProcessDataTypeChangedNotify_NewDataTypeForTask5IsMessage_ShouldSyncApplicationMetadata( - string org, string app, string developer, string applicationMetadataPath, DataTypeChange dataTypeChange) + public async Task ProcessDataTypesChangedNotify_NewDataTypeForTask5IsMessage_ShouldSyncApplicationMetadata( + string org, string app, string developer, string applicationMetadataPath, DataTypesChange dataTypesChange) { string targetRepository = TestDataHelper.GenerateTestRepoName(); await CopyRepositoryForTest(org, app, developer, targetRepository); await AddFileToRepo(applicationMetadataPath, "App/config/applicationmetadata.json"); string dataTypeToConnect = "message"; string task = "Task_5"; - dataTypeChange.NewDataType = dataTypeToConnect; - dataTypeChange.ConnectedTaskId = task; + dataTypesChange.NewDataTypes = [dataTypeToConnect]; + dataTypesChange.ConnectedTaskId = task; string url = VersionPrefix(org, targetRepository); - string dataTypeChangeString = JsonSerializer.Serialize(dataTypeChange, + string dataTypesChangeString = JsonSerializer.Serialize(dataTypesChange, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); using var httpRequestMessage = new HttpRequestMessage(HttpMethod.Put, url) { - Content = new StringContent(dataTypeChangeString, Encoding.UTF8, "application/json") + Content = new StringContent(dataTypesChangeString, Encoding.UTF8, "application/json") }; using var response = await HttpClient.SendAsync(httpRequestMessage); response.StatusCode.Should().Be(HttpStatusCode.Accepted); @@ -82,26 +82,59 @@ public async Task ProcessDataTypeChangedNotify_NewDataTypeForTask5IsMessage_Shou applicationMetadata.DataTypes.Find(type => type.Id == dataTypeToConnect).TaskId.Should().Be(task); // Data type 'message' is now connected to Task_5 } + [Theory] + [MemberData(nameof(ProcessDataTypeChangedNotifyTestData))] + public async Task ProcessDataTypesChangedNotify_NewDataTypesForTask5IsMessageAndLikert_ShouldSyncApplicationMetadataBoth( + string org, string app, string developer, string applicationMetadataPath, DataTypesChange dataTypesChange) + { + string targetRepository = TestDataHelper.GenerateTestRepoName(); + await CopyRepositoryForTest(org, app, developer, targetRepository); + await AddFileToRepo(applicationMetadataPath, "App/config/applicationmetadata.json"); + string dataTypeToConnect1 = "message"; + string dataTypeToConnect2 = "likert"; + string task = "Task_5"; + dataTypesChange.NewDataTypes = [dataTypeToConnect1, dataTypeToConnect2]; + dataTypesChange.ConnectedTaskId = task; + + string url = VersionPrefix(org, targetRepository); + + string dataTypesChangeString = JsonSerializer.Serialize(dataTypesChange, + new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); + using var httpRequestMessage = new HttpRequestMessage(HttpMethod.Put, url) + { + Content = new StringContent(dataTypesChangeString, Encoding.UTF8, "application/json") + }; + using var response = await HttpClient.SendAsync(httpRequestMessage); + response.StatusCode.Should().Be(HttpStatusCode.Accepted); + + string applicationMetadataFromRepo = TestDataHelper.GetFileFromRepo(org, targetRepository, developer, "App/config/applicationmetadata.json"); + + ApplicationMetadata applicationMetadata = JsonSerializer.Deserialize(applicationMetadataFromRepo, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); + applicationMetadata.DataTypes.FindAll(type => type.TaskId == task).Count.Should().Be(2); // Original connected data type 'datalist' should be disconnected + applicationMetadata.DataTypes.Find(type => type.Id == dataTypeToConnect1).TaskId.Should().Be(task); // Data type 'message' is now connected to Task_5 + applicationMetadata.DataTypes.Find(type => type.Id == dataTypeToConnect2).TaskId.Should().Be(task); // Data type 'likert' is now connected to Task_5 + } + [Theory] [MemberData(nameof(ProcessDataTypeChangedNotifyTestData))] public async Task ProcessDataTypeChangedNotify_NewDataTypeForCustomReceipt_ShouldNotSyncApplicationMetadata( - string org, string app, string developer, string applicationMetadataPath, DataTypeChange dataTypeChange) + string org, string app, string developer, string applicationMetadataPath, DataTypesChange dataTypesChange) { string targetRepository = TestDataHelper.GenerateTestRepoName(); await CopyRepositoryForTest(org, app, developer, targetRepository); await AddFileToRepo(applicationMetadataPath, "App/config/applicationmetadata.json"); string dataTypeToConnect = "message"; string task = "CustomReceipt"; - dataTypeChange.NewDataType = dataTypeToConnect; - dataTypeChange.ConnectedTaskId = task; + dataTypesChange.NewDataTypes = [dataTypeToConnect]; + dataTypesChange.ConnectedTaskId = task; string url = VersionPrefix(org, targetRepository); - string dataTypeChangeString = JsonSerializer.Serialize(dataTypeChange, + string dataTypesChangeString = JsonSerializer.Serialize(dataTypesChange, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); using var httpRequestMessage = new HttpRequestMessage(HttpMethod.Put, url) { - Content = new StringContent(dataTypeChangeString, Encoding.UTF8, "application/json") + Content = new StringContent(dataTypesChangeString, Encoding.UTF8, "application/json") }; using var response = await HttpClient.SendAsync(httpRequestMessage); response.StatusCode.Should().Be(HttpStatusCode.Accepted); @@ -109,7 +142,6 @@ public async Task ProcessDataTypeChangedNotify_NewDataTypeForCustomReceipt_Shoul string applicationMetadataFromRepo = TestDataHelper.GetFileFromRepo(org, targetRepository, developer, "App/config/applicationmetadata.json"); ApplicationMetadata applicationMetadata = JsonSerializer.Deserialize(applicationMetadataFromRepo, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); - applicationMetadata.DataTypes.Find(type => type.Id == dataTypeToConnect).TaskId.Should().NotBe(task); // CustomReceipt has not been added to the dataType } @@ -121,7 +153,7 @@ public static IEnumerable ProcessDataTypeChangedNotifyTestData() "empty-app", "testUser", "App/config/applicationmetadata.json", - new DataTypeChange { NewDataType = null, ConnectedTaskId = "Task_1" } + new DataTypesChange { NewDataTypes = [], ConnectedTaskId = "Task_1" } ]; } diff --git a/backend/tests/Designer.Tests/Controllers/ProcessModelingController/FileSync/DataTypesChangeTests/LayoutSetsFileSyncDataTypesTests.cs b/backend/tests/Designer.Tests/Controllers/ProcessModelingController/FileSync/DataTypesChangeTests/LayoutSetsFileSyncDataTypesTests.cs new file mode 100644 index 00000000000..80624a2c6bf --- /dev/null +++ b/backend/tests/Designer.Tests/Controllers/ProcessModelingController/FileSync/DataTypesChangeTests/LayoutSetsFileSyncDataTypesTests.cs @@ -0,0 +1,198 @@ +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; +using Altinn.App.Core.Models; +using Altinn.Studio.Designer.Models.Dto; +using Designer.Tests.Controllers.ApiTests; +using Designer.Tests.Utils; +using FluentAssertions; +using Microsoft.AspNetCore.Mvc.Testing; +using SharedResources.Tests; +using Xunit; + +namespace Designer.Tests.Controllers.ProcessModelingController.FileSync.DataTypesChangeTests; + +public class LayoutSetsFileSyncDataTypesTests : DisagnerEndpointsTestsBase, IClassFixture> +{ + private static string VersionPrefix(string org, string repository) => + $"/designer/api/{org}/{repository}/process-modelling/data-types"; + + public LayoutSetsFileSyncDataTypesTests(WebApplicationFactory factory) : base(factory) + { + } + + [Theory] + [InlineData("ttd", "empty-app", "testUser", "App/ui/layout-sets.json")] + public async Task ProcessDataTypesChangedNotify_Task1DisconnectedFromDataType_ShouldSyncLayoutSets(string org, string app, string developer, + string layoutSetsPath) + { + string targetRepository = TestDataHelper.GenerateTestRepoName(); + await CopyRepositoryForTest(org, app, developer, targetRepository); + await AddFileToRepo(layoutSetsPath, "App/ui/layout-sets.json"); + DataTypesChange dataTypesChange = new DataTypesChange { NewDataTypes = [null], ConnectedTaskId = "Task_1" }; + + string url = VersionPrefix(org, targetRepository); + + string dataTypesChangeString = JsonSerializer.Serialize(dataTypesChange, + new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); + using var httpRequestMessage = new HttpRequestMessage(HttpMethod.Put, url) + { + Content = new StringContent(dataTypesChangeString, Encoding.UTF8, "application/json") + }; + using var response = await HttpClient.SendAsync(httpRequestMessage); + response.StatusCode.Should().Be(HttpStatusCode.Accepted); + + string layoutSetsFromRepo = + TestDataHelper.GetFileFromRepo(org, targetRepository, developer, "App/ui/layout-sets.json"); + + LayoutSets layoutSets = JsonSerializer.Deserialize(layoutSetsFromRepo, new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); + + layoutSets.Sets.Find(set => set.Tasks[0] == dataTypesChange.ConnectedTaskId).DataType.Should().BeNull(); + } + + [Theory] + [InlineData("ttd", "empty-app", "testUser", "App/ui/layout-sets.json")] + public async Task ProcessDataTypesChangedNotify_NewDataTypeForTask5IsMessage_ShouldSyncLayoutSets(string org, string app, string developer, string layoutSetsPath) + { + string targetRepository = TestDataHelper.GenerateTestRepoName(); + await CopyRepositoryForTest(org, app, developer, targetRepository); + await AddFileToRepo(layoutSetsPath, "App/ui/layout-sets.json"); + string dataTypeToConnect = "message"; + string task = "Task_5"; + DataTypesChange dataTypesChange = new DataTypesChange + { NewDataTypes = [dataTypeToConnect], ConnectedTaskId = task }; + + + string url = VersionPrefix(org, targetRepository); + + string dataTypesChangeString = JsonSerializer.Serialize(dataTypesChange, + new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); + using var httpRequestMessage = new HttpRequestMessage(HttpMethod.Put, url) + { + Content = new StringContent(dataTypesChangeString, Encoding.UTF8, "application/json") + }; + using var response = await HttpClient.SendAsync(httpRequestMessage); + response.StatusCode.Should().Be(HttpStatusCode.Accepted); + + string layoutSetsFromRepo = + TestDataHelper.GetFileFromRepo(org, targetRepository, developer, "App/ui/layout-sets.json"); + + LayoutSets layoutSets = JsonSerializer.Deserialize(layoutSetsFromRepo, new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); + + layoutSets.Sets.Find(set => set.Tasks[0] == task).DataType.Should().Be(dataTypeToConnect); + } + + [Theory] + [InlineData("ttd", "empty-app", "testUser", "App/ui/layout-sets.json")] + public async Task ProcessDataTypesChangedNotify_NewDataTypesForTask5IsMessageAndLikert_ShouldSyncLayoutSetsWithMessage(string org, string app, string developer, string layoutSetsPath) + { + string targetRepository = TestDataHelper.GenerateTestRepoName(); + await CopyRepositoryForTest(org, app, developer, targetRepository); + await AddFileToRepo(layoutSetsPath, "App/ui/layout-sets.json"); + string dataTypeToConnect1 = "message"; + string dataTypeToConnect2 = "likert"; + string task = "Task_5"; + DataTypesChange dataTypesChange = new DataTypesChange + { NewDataTypes = [dataTypeToConnect1, dataTypeToConnect2], ConnectedTaskId = task }; + + string url = VersionPrefix(org, targetRepository); + + string dataTypesChangeString = JsonSerializer.Serialize(dataTypesChange, + new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); + using var httpRequestMessage = new HttpRequestMessage(HttpMethod.Put, url) + { + Content = new StringContent(dataTypesChangeString, Encoding.UTF8, "application/json") + }; + using var response = await HttpClient.SendAsync(httpRequestMessage); + response.StatusCode.Should().Be(HttpStatusCode.Accepted); + + string layoutSetsFromRepo = + TestDataHelper.GetFileFromRepo(org, targetRepository, developer, "App/ui/layout-sets.json"); + + LayoutSets layoutSets = JsonSerializer.Deserialize(layoutSetsFromRepo, new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); + + layoutSets.Sets.Find(set => set.Tasks[0] == task).DataType.Should().Be(dataTypeToConnect1); + } + + [Theory] + [InlineData("ttd", "empty-app", "testUser", "App/ui/layout-sets.json")] + public async Task ProcessDataTypesChangedNotify_NewDataTypesForTask5IsMessageAndDatalist_ShouldSyncLayoutSetsWithExisting(string org, string app, string developer, string layoutSetsPath) + { + string targetRepository = TestDataHelper.GenerateTestRepoName(); + await CopyRepositoryForTest(org, app, developer, targetRepository); + await AddFileToRepo(layoutSetsPath, "App/ui/layout-sets.json"); + string dataTypeToConnect1 = "message"; + string dataTypeToConnect2 = "datalist"; + string task = "Task_5"; + DataTypesChange dataTypesChange = new DataTypesChange + { NewDataTypes = [dataTypeToConnect1, dataTypeToConnect2], ConnectedTaskId = task }; + + string url = VersionPrefix(org, targetRepository); + + string dataTypesChangeString = JsonSerializer.Serialize(dataTypesChange, + new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); + using var httpRequestMessage = new HttpRequestMessage(HttpMethod.Put, url) + { + Content = new StringContent(dataTypesChangeString, Encoding.UTF8, "application/json") + }; + using var response = await HttpClient.SendAsync(httpRequestMessage); + response.StatusCode.Should().Be(HttpStatusCode.Accepted); + + string layoutSetsFromRepo = + TestDataHelper.GetFileFromRepo(org, targetRepository, developer, "App/ui/layout-sets.json"); + + LayoutSets layoutSets = JsonSerializer.Deserialize(layoutSetsFromRepo, new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); + + layoutSets.Sets.Find(set => set.Tasks[0] == task).DataType.Should().Be(dataTypeToConnect2); + } + + [Theory] + [InlineData("ttd", "app-with-layoutsets", "testUser", "App/ui/layout-sets.json")] + public async Task ProcessDataTypeChangedNotify_NewDataTypeForCustomReceipt_ShouldSyncLayoutSets(string org, string app, string developer, string layoutSetsPath) + { + string targetRepository = TestDataHelper.GenerateTestRepoName(); + await CopyRepositoryForTest(org, app, developer, targetRepository); + await AddFileToRepo(layoutSetsPath, "App/ui/layout-sets.json"); + string dataTypeToConnect = "message"; + string task = "CustomReceipt"; + DataTypesChange dataTypesChange = new DataTypesChange + { NewDataTypes = [dataTypeToConnect], ConnectedTaskId = task }; + + string url = VersionPrefix(org, targetRepository); + + string dataTypeChangeString = JsonSerializer.Serialize(dataTypesChange, + new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); + using var httpRequestMessage = new HttpRequestMessage(HttpMethod.Put, url) + { + Content = new StringContent(dataTypeChangeString, Encoding.UTF8, "application/json") + }; + using var response = await HttpClient.SendAsync(httpRequestMessage); + response.StatusCode.Should().Be(HttpStatusCode.Accepted); + + string layoutSetsFromRepo = + TestDataHelper.GetFileFromRepo(org, targetRepository, developer, "App/ui/layout-sets.json"); + + LayoutSets layoutSets = JsonSerializer.Deserialize(layoutSetsFromRepo, new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); + + layoutSets.Sets.Find(set => set.Tasks[0] == task).DataType.Should().Be(dataTypeToConnect); + } + + private async Task AddFileToRepo(string fileToCopyPath, string relativeCopyRepoLocation) + { + string fileContent = SharedResourcesHelper.LoadTestDataAsString(fileToCopyPath); + string filePath = Path.Combine(TestRepoPath, relativeCopyRepoLocation); + string folderPath = Path.GetDirectoryName(filePath); + if (!Directory.Exists(folderPath)) + { + Directory.CreateDirectory(folderPath); + } + + await File.WriteAllTextAsync(filePath, fileContent); + } + +} + diff --git a/backend/tests/Designer.Tests/Controllers/ProcessModelingController/ProcessDataTypeChangedNotifyTests.cs b/backend/tests/Designer.Tests/Controllers/ProcessModelingController/ProcessDataTypesChangedNotifyTests.cs similarity index 75% rename from backend/tests/Designer.Tests/Controllers/ProcessModelingController/ProcessDataTypeChangedNotifyTests.cs rename to backend/tests/Designer.Tests/Controllers/ProcessModelingController/ProcessDataTypesChangedNotifyTests.cs index 2220ee62df6..c64814b6c76 100644 --- a/backend/tests/Designer.Tests/Controllers/ProcessModelingController/ProcessDataTypeChangedNotifyTests.cs +++ b/backend/tests/Designer.Tests/Controllers/ProcessModelingController/ProcessDataTypesChangedNotifyTests.cs @@ -14,17 +14,17 @@ namespace Designer.Tests.Controllers.ProcessModelingController; -public class ProcessDataTypeChangedNotifyTests : DisagnerEndpointsTestsBase, IClassFixture> +public class ProcessDataTypesChangedNotifyTests : DisagnerEndpointsTestsBase, IClassFixture> { - private static string VersionPrefix(string org, string repository) => $"/designer/api/{org}/{repository}/process-modelling/data-type"; + private static string VersionPrefix(string org, string repository) => $"/designer/api/{org}/{repository}/process-modelling/data-types"; - public ProcessDataTypeChangedNotifyTests(WebApplicationFactory factory) : base(factory) + public ProcessDataTypesChangedNotifyTests(WebApplicationFactory factory) : base(factory) { } [Theory] [MemberData(nameof(ProcessDataTypeChangedNotifyTestData))] - public async Task ProcessDataTypeChangedNotify_ShouldReturnOk(string org, string app, string developer, DataTypeChange metadata) + public async Task ProcessDataTypesChangedNotify_ShouldReturnOk(string org, string app, string developer, DataTypesChange metadata) { string targetRepository = TestDataHelper.GenerateTestRepoName(); await CopyRepositoryForTest(org, app, developer, targetRepository); @@ -48,7 +48,7 @@ public static IEnumerable ProcessDataTypeChangedNotifyTestData() "ttd", "empty-app", "testUser", - new DataTypeChange { NewDataType = "model", ConnectedTaskId = "Task_1" } + new DataTypesChange { NewDataTypes = ["model"], ConnectedTaskId = "Task_1" } ]; } } diff --git a/frontend/app-development/features/processEditor/ProcessEditor.tsx b/frontend/app-development/features/processEditor/ProcessEditor.tsx index 7cd8f364c67..fccbfb34340 100644 --- a/frontend/app-development/features/processEditor/ProcessEditor.tsx +++ b/frontend/app-development/features/processEditor/ProcessEditor.tsx @@ -17,8 +17,8 @@ import { useCustomReceiptLayoutSetName } from 'app-shared/hooks/useCustomReceipt import { useLayoutSetsQuery } from 'app-shared/hooks/queries/useLayoutSetsQuery'; import { useDeleteLayoutSetMutation } from '../../hooks/mutations/useDeleteLayoutSetMutation'; import { useAppMetadataModelIdsQuery } from 'app-shared/hooks/queries/useAppMetadataModelIdsQuery'; -import { useUpdateProcessDataTypeMutation } from '../../hooks/mutations/useUpdateProcessDataTypeMutation'; -import type { MetaDataForm } from 'app-shared/types/BpmnMetaDataForm'; +import { useUpdateProcessDataTypesMutation } from '../../hooks/mutations/useUpdateProcessDataTypesMutation'; +import type { MetadataForm } from 'app-shared/types/BpmnMetadataForm'; import { useAddDataTypeToAppMetadata } from '../../hooks/mutations/useAddDataTypeToAppMetadata'; import { useDeleteDataTypeFromAppMetadata } from '../../hooks/mutations/useDeleteDataTypeFromAppMetadata'; import { SyncSuccessQueriesInvalidator } from 'app-shared/queryInvalidator/SyncSuccessQueriesInvalidator'; @@ -55,8 +55,8 @@ export const ProcessEditor = (): React.ReactElement => { org, app, ); - const { mutate: mutateDataType, isPending: updateDataTypePending } = - useUpdateProcessDataTypeMutation(org, app); + const { mutate: mutateDataTypes, isPending: updateDataTypePending } = + useUpdateProcessDataTypesMutation(org, app); const existingCustomReceiptId: string | undefined = useCustomReceiptLayoutSetName(org, app); @@ -104,10 +104,10 @@ export const ProcessEditor = (): React.ReactElement => { } }); - const saveBpmnXml = async (xml: string, metaData?: MetaDataForm): Promise => { + const saveBpmnXml = async (xml: string, metadata?: MetadataForm): Promise => { const formData = new FormData(); formData.append('content', new Blob([xml]), 'process.bpmn'); - formData.append('metadata', JSON.stringify(metaData)); + formData.append('metadata', JSON.stringify(metadata)); mutateBpmn( { form: formData }, @@ -162,7 +162,7 @@ export const ProcessEditor = (): React.ReactElement => { mutateLayoutSetId={mutateLayoutSetId} appLibVersion={appLibData.backendVersion} bpmnXml={hasBpmnQueryError ? null : bpmnXml} - mutateDataType={mutateDataType} + mutateDataTypes={mutateDataTypes} saveBpmn={saveBpmnXml} openPolicyEditor={() => { setSettingsModalSelectedTab('policy'); diff --git a/frontend/app-development/hooks/mutations/useUpdateProcessDataTypesMutation.test.ts b/frontend/app-development/hooks/mutations/useUpdateProcessDataTypesMutation.test.ts new file mode 100644 index 00000000000..435d8b7591c --- /dev/null +++ b/frontend/app-development/hooks/mutations/useUpdateProcessDataTypesMutation.test.ts @@ -0,0 +1,55 @@ +import { queriesMock } from 'app-shared/mocks/queriesMock'; +import { renderHookWithMockStore } from '../../test/mocks'; +import { useUpdateProcessDataTypesMutation } from './useUpdateProcessDataTypesMutation'; +import { waitFor } from '@testing-library/react'; +import { QueryKey } from 'app-shared/types/QueryKey'; +import { createQueryClientMock } from 'app-shared/mocks/queryClientMock'; +import type { QueryClient } from '@tanstack/react-query'; +import { app, org } from '@studio/testing/testids'; +import type { DataTypesChange } from 'app-shared/types/api/DataTypesChange'; + +// Test data +const newDataTypes = ['data-model']; +const connectedTaskId = 'Task_1'; +const metadata: DataTypesChange = { + newDataTypes, + connectedTaskId, +}; + +const renderHook = async ({ + queryClient, +}: { + queryClient?: QueryClient; +} = {}) => { + const updateProcessDataTypesResult = renderHookWithMockStore( + {}, + {}, + queryClient, + )(() => useUpdateProcessDataTypesMutation(org, app)).renderHookResult.result; + await waitFor(() => updateProcessDataTypesResult.current.mutateAsync(metadata)); + expect(updateProcessDataTypesResult.current.isSuccess).toBe(true); +}; + +describe('useUpdateProcessDataTypeMutation', () => { + it('calls updateProcessDataTypes with correct arguments and payload', async () => { + await renderHook(); + + expect(queriesMock.updateProcessDataTypes).toHaveBeenCalledTimes(1); + expect(queriesMock.updateProcessDataTypes).toHaveBeenCalledWith(org, app, metadata); + }); + + it('invalidates metadata queries when update is successful', async () => { + const queryClient = createQueryClientMock(); + const invalidateQueriesSpy = jest.spyOn(queryClient, 'invalidateQueries'); + + await renderHook({ queryClient }); + + expect(invalidateQueriesSpy).toHaveBeenCalledTimes(2); + expect(invalidateQueriesSpy).toHaveBeenCalledWith({ + queryKey: [QueryKey.AppMetadataModelIds, org, app], + }); + expect(invalidateQueriesSpy).toHaveBeenCalledWith({ + queryKey: [QueryKey.LayoutSets, org, app], + }); + }); +}); diff --git a/frontend/app-development/hooks/mutations/useUpdateProcessDataTypeMutation.ts b/frontend/app-development/hooks/mutations/useUpdateProcessDataTypesMutation.ts similarity index 52% rename from frontend/app-development/hooks/mutations/useUpdateProcessDataTypeMutation.ts rename to frontend/app-development/hooks/mutations/useUpdateProcessDataTypesMutation.ts index 29cadde6990..8e2dea1b706 100644 --- a/frontend/app-development/hooks/mutations/useUpdateProcessDataTypeMutation.ts +++ b/frontend/app-development/hooks/mutations/useUpdateProcessDataTypesMutation.ts @@ -1,12 +1,13 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { updateProcessDataType } from 'app-shared/api/mutations'; import { QueryKey } from 'app-shared/types/QueryKey'; -import type { DataTypeChange } from 'app-shared/types/api/DataTypeChange'; +import type { DataTypesChange } from 'app-shared/types/api/DataTypesChange'; +import { useServicesContext } from 'app-shared/contexts/ServicesContext'; -export const useUpdateProcessDataTypeMutation = (org: string, app: string) => { +export const useUpdateProcessDataTypesMutation = (org: string, app: string) => { const queryClient = useQueryClient(); + const { updateProcessDataTypes } = useServicesContext(); return useMutation({ - mutationFn: (metadata: DataTypeChange) => updateProcessDataType(org, app, metadata), + mutationFn: (metadata: DataTypesChange) => updateProcessDataTypes(org, app, metadata), onSuccess: async () => { await queryClient.invalidateQueries({ queryKey: [QueryKey.AppMetadataModelIds, org, app] }); await queryClient.invalidateQueries({ queryKey: [QueryKey.LayoutSets, org, app] }); diff --git a/frontend/app-development/layout/SettingsModalButton/SettingsModal/components/Tabs/AboutTab/AboutTab.test.tsx b/frontend/app-development/layout/SettingsModalButton/SettingsModal/components/Tabs/AboutTab/AboutTab.test.tsx index a905f76a520..48950c747f5 100644 --- a/frontend/app-development/layout/SettingsModalButton/SettingsModal/components/Tabs/AboutTab/AboutTab.test.tsx +++ b/frontend/app-development/layout/SettingsModalButton/SettingsModal/components/Tabs/AboutTab/AboutTab.test.tsx @@ -70,7 +70,7 @@ describe('AboutTab', () => { expect(getAppConfig).toHaveBeenCalledTimes(1); }); - it('fetches repoMetaData on mount', () => { + it('fetches repoMetadata on mount', () => { renderAboutTab(); expect(getRepoMetadata).toHaveBeenCalledTimes(1); }); diff --git a/frontend/language/src/nb.json b/frontend/language/src/nb.json index b6480ea03e3..84a30c7f80e 100644 --- a/frontend/language/src/nb.json +++ b/frontend/language/src/nb.json @@ -843,7 +843,7 @@ "process_editor.sequence_flow_configuration_panel_explanation": "Med Flytkontroll-verktøyet kan du kontrollere flyten ut av en gateway basert på brukerhandling utført ved hjelp av et utrykk.", "process_editor.sequence_flow_configuration_panel_title": "Flytkontroll", "process_editor.sync_error.unknown_error": "En ukjent feil oppsto under synkronisering av oppgave-ID. Vennligst prøv igjen.", - "process_editor.sync_error_application_metadata_data_type": "En feil oppsto under synkronisering av datatype i filen 'applicationmetadata.json'. Vennligst forsikre deg om at 'applicationmetadata.json' kun inneholder gyldig JSON-struktur og prøv igjen.", + "process_editor.sync_error_application_metadata_data_type": "En feil oppsto under synkronisering av datatyper i filen 'applicationmetadata.json'. Vennligst forsikre deg om at 'applicationmetadata.json' kun inneholder gyldig JSON-struktur og prøv igjen.", "process_editor.sync_error_application_metadata_task_id": "En feil oppsto under synkronisering av oppgave-ID i filen 'applicationmetadata.json'. Vennligst forsikre deg om at 'applicationmetadata.json' kun inneholder gyldig JSON-struktur og prøv igjen.", "process_editor.sync_error_layout_sets_data_type": "En feil oppsto under synkronisering av datatype i filen 'layoutsets.json'. Vennligst forsikre deg om at 'layoutsets.json' kun inneholder gyldig JSON-struktur og prøv igjen.", "process_editor.sync_error_layout_sets_task_id": "En feil oppsto under synkronisering av oppgave-ID i filen 'layoutsets.json'. Vennligst forsikre deg om at 'layoutsets.json' kun inneholder gyldig JSON-struktur og prøv igjen.", diff --git a/frontend/packages/process-editor/src/ProcessEditor.test.tsx b/frontend/packages/process-editor/src/ProcessEditor.test.tsx index 713758eef18..093474ed669 100644 --- a/frontend/packages/process-editor/src/ProcessEditor.test.tsx +++ b/frontend/packages/process-editor/src/ProcessEditor.test.tsx @@ -23,7 +23,7 @@ const defaultProps: ProcessEditorProps = { addLayoutSet: jest.fn(), deleteLayoutSet: jest.fn(), mutateLayoutSetId: jest.fn(), - mutateDataType: jest.fn(), + mutateDataTypes: jest.fn(), openPolicyEditor: jest.fn(), onProcessTaskRemove: jest.fn(), onProcessTaskAdd: jest.fn(), diff --git a/frontend/packages/process-editor/src/ProcessEditor.tsx b/frontend/packages/process-editor/src/ProcessEditor.tsx index b1b902237be..0841c4e7cda 100644 --- a/frontend/packages/process-editor/src/ProcessEditor.tsx +++ b/frontend/packages/process-editor/src/ProcessEditor.tsx @@ -11,7 +11,7 @@ import classes from './ProcessEditor.module.css'; import type { BpmnApiContextProps } from './contexts/BpmnApiContext'; import { BpmnApiContextProvider } from './contexts/BpmnApiContext'; import { BpmnConfigPanelFormContextProvider } from './contexts/BpmnConfigPanelContext'; -import type { MetaDataForm } from 'app-shared/types/BpmnMetaDataForm'; +import type { MetadataForm } from 'app-shared/types/BpmnMetadataForm'; export type ProcessEditorProps = { appLibVersion: string; @@ -25,8 +25,8 @@ export type ProcessEditorProps = { addLayoutSet: BpmnApiContextProps['addLayoutSet']; deleteLayoutSet: BpmnApiContextProps['deleteLayoutSet']; mutateLayoutSetId: BpmnApiContextProps['mutateLayoutSetId']; - mutateDataType: BpmnApiContextProps['mutateDataType']; - saveBpmn: (bpmnXml: string, metaData?: MetaDataForm) => void; + mutateDataTypes: BpmnApiContextProps['mutateDataTypes']; + saveBpmn: (bpmnXml: string, metadata?: MetadataForm) => void; openPolicyEditor: BpmnApiContextProps['openPolicyEditor']; onProcessTaskAdd: BpmnApiContextProps['onProcessTaskAdd']; onProcessTaskRemove: BpmnApiContextProps['onProcessTaskRemove']; @@ -44,7 +44,7 @@ export const ProcessEditor = ({ addLayoutSet, deleteLayoutSet, mutateLayoutSetId, - mutateDataType, + mutateDataTypes, saveBpmn, openPolicyEditor, onProcessTaskAdd, @@ -72,7 +72,7 @@ export const ProcessEditor = ({ addLayoutSet={addLayoutSet} deleteLayoutSet={deleteLayoutSet} mutateLayoutSetId={mutateLayoutSetId} - mutateDataType={mutateDataType} + mutateDataTypes={mutateDataTypes} saveBpmn={saveBpmn} openPolicyEditor={openPolicyEditor} onProcessTaskAdd={onProcessTaskAdd} diff --git a/frontend/packages/process-editor/src/components/ConfigPanel/ConfigContent/ConfigContent.tsx b/frontend/packages/process-editor/src/components/ConfigPanel/ConfigContent/ConfigContent.tsx index b5e5d946acf..5a263b02190 100644 --- a/frontend/packages/process-editor/src/components/ConfigPanel/ConfigContent/ConfigContent.tsx +++ b/frontend/packages/process-editor/src/components/ConfigPanel/ConfigContent/ConfigContent.tsx @@ -6,7 +6,7 @@ import { EditTaskId } from './EditTaskId/EditTaskId'; import { StudioDisplayTile, StudioSectionHeader } from '@studio/components'; import { getConfigTitleKey, getConfigTitleHelpTextKey } from '../../../utils/configPanelUtils'; import { ConfigIcon } from './ConfigIcon'; -import { EditDataType } from '../EditDataType'; +import { EditDataTypes } from '../EditDataTypes'; import { useBpmnApiContext } from '../../../contexts/BpmnApiContext'; import { Accordion } from '@digdir/design-system-react'; import { EditActions } from './EditActions'; @@ -46,7 +46,7 @@ export const ConfigContent = (): React.ReactElement => { className={classes.displayTile} /> {taskHasConnectedLayoutSet && ( - ({ })); (useBpmnConfigPanelFormContext as jest.Mock).mockReturnValue({ - metaDataFormRef: { current: undefined }, + metadataFormRef: { current: undefined }, }); jest.mock('../../../../utils/bpmn/StudioModeler', () => { @@ -64,12 +64,12 @@ describe('EditTaskId', () => { ).toBeInTheDocument(); }); - it('should update metaDataFromRef and updateId (implicitly calling setBpmnDetails) when changing task id', async () => { + it('should update metadataFromRef and updateId (implicitly calling setBpmnDetails) when changing task id', async () => { const user = userEvent.setup(); const newId = 'newId'; - const metaDataFormRefMock = { current: undefined }; + const metadataFormRefMock = { current: undefined }; (useBpmnConfigPanelFormContext as jest.Mock).mockReturnValue({ - metaDataFormRef: metaDataFormRefMock, + metadataFormRef: metadataFormRefMock, }); render(); @@ -87,7 +87,7 @@ describe('EditTaskId', () => { await user.type(input, newId); await user.tab(); - expect(metaDataFormRefMock.current).toEqual( + expect(metadataFormRefMock.current).toEqual( expect.objectContaining({ taskIdChange: { newId: newId, oldId: 'testId' } }), ); expect(setBpmnDetailsMock).toHaveBeenCalledTimes(1); @@ -160,9 +160,9 @@ describe('EditTaskId', () => { it('should not update id if new id is the same as the old id', async () => { const user = userEvent.setup(); - const metaDataFormRefMock = { current: undefined }; + const metadataFormRefMock = { current: undefined }; (useBpmnConfigPanelFormContext as jest.Mock).mockReturnValue({ - metaDataFormRef: metaDataFormRefMock, + metadataFormRef: metadataFormRefMock, }); render(); @@ -180,7 +180,7 @@ describe('EditTaskId', () => { await user.type(input, 'testId'); await user.tab(); - expect(metaDataFormRefMock.current).toBeUndefined(); + expect(metadataFormRefMock.current).toBeUndefined(); expect(setBpmnDetailsMock).not.toHaveBeenCalled(); }); }); diff --git a/frontend/packages/process-editor/src/components/ConfigPanel/ConfigContent/EditTaskId/EditTaskId.tsx b/frontend/packages/process-editor/src/components/ConfigPanel/ConfigContent/EditTaskId/EditTaskId.tsx index 21f611fef22..704385be59c 100644 --- a/frontend/packages/process-editor/src/components/ConfigPanel/ConfigContent/EditTaskId/EditTaskId.tsx +++ b/frontend/packages/process-editor/src/components/ConfigPanel/ConfigContent/EditTaskId/EditTaskId.tsx @@ -8,12 +8,12 @@ import { useBpmnConfigPanelFormContext } from '../../../../contexts/BpmnConfigPa import type Modeling from 'bpmn-js/lib/features/modeling/Modeling'; import classes from './EditTaskId.module.css'; import { useTaskIds } from '../../../../hooks/useTaskIds'; -import type { MetaDataForm } from 'app-shared/types/BpmnMetaDataForm'; +import type { MetadataForm } from 'app-shared/types/BpmnMetadataForm'; export const EditTaskId = (): React.ReactElement => { const { t } = useTranslation(); const { bpmnDetails, modelerRef, setBpmnDetails } = useBpmnContext(); - const { metaDataFormRef } = useBpmnConfigPanelFormContext(); + const { metadataFormRef } = useBpmnConfigPanelFormContext(); const modelerInstance = modelerRef.current; const modeling: Modeling = modelerInstance.get('modeling'); @@ -34,13 +34,13 @@ export const EditTaskId = (): React.ReactElement => { if (newId === bpmnDetails.id) return; - const newMetadata: MetaDataForm = { + const newMetadata: MetadataForm = { taskIdChange: { newId, oldId: bpmnDetails.id, }, }; - metaDataFormRef.current = Object.assign({}, metaDataFormRef.current, newMetadata); + metadataFormRef.current = Object.assign({}, metadataFormRef.current, newMetadata); updateId(newId); }; diff --git a/frontend/packages/process-editor/src/components/ConfigPanel/ConfigEndEvent/CustomReceiptContent/CreateCustomReceiptForm/CreateCustomReceiptForm.test.tsx b/frontend/packages/process-editor/src/components/ConfigPanel/ConfigEndEvent/CustomReceiptContent/CreateCustomReceiptForm/CreateCustomReceiptForm.test.tsx index 5c20c780dfb..155ce6f0706 100644 --- a/frontend/packages/process-editor/src/components/ConfigPanel/ConfigEndEvent/CustomReceiptContent/CreateCustomReceiptForm/CreateCustomReceiptForm.test.tsx +++ b/frontend/packages/process-editor/src/components/ConfigPanel/ConfigEndEvent/CustomReceiptContent/CreateCustomReceiptForm/CreateCustomReceiptForm.test.tsx @@ -4,7 +4,7 @@ import { type CreateCustomReceiptFormProps, } from './CreateCustomReceiptForm'; import { render, screen, waitFor } from '@testing-library/react'; -import { textMock } from '../../../../../../../../testing/mocks/i18nMock'; +import { textMock } from '@studio/testing/mocks/i18nMock'; import { BpmnContext, type BpmnContextProps } from '../../../../../contexts/BpmnContext'; import userEvent from '@testing-library/user-event'; import { BpmnApiContext, type BpmnApiContextProps } from '../../../../../contexts/BpmnApiContext'; @@ -17,7 +17,6 @@ import { queryOptionMock } from 'app-shared/mocks/queryOptionMock'; import { PROTECTED_TASK_NAME_CUSTOM_RECEIPT } from 'app-shared/constants'; const mockAddLayoutSet = jest.fn().mockImplementation(queryOptionMock); - const mockOnCloseForm = jest.fn(); const mockAllDataModelIds: string[] = ['model1', 'model2']; @@ -34,7 +33,7 @@ const defaultBpmnApiContextProps: BpmnApiContextProps = { describe('CreateCustomReceiptForm', () => { afterEach(() => jest.clearAllMocks()); - it('Submits the form with valid inputs and calls "addLayoutSet", "mutateDataType", and "onCloseForm" when submit button is clicked', async () => { + it('Submits the form with valid inputs and calls "addLayoutSet", "mutateDataTypes", and "onCloseForm" when submit button is clicked', async () => { const user = userEvent.setup(); renderCreateCustomReceiptForm(); diff --git a/frontend/packages/process-editor/src/components/ConfigPanel/ConfigEndEvent/CustomReceiptContent/CustomReceipt/CustomReceipt.test.tsx b/frontend/packages/process-editor/src/components/ConfigPanel/ConfigEndEvent/CustomReceiptContent/CustomReceipt/CustomReceipt.test.tsx index c916dc25893..fe7fb019b37 100644 --- a/frontend/packages/process-editor/src/components/ConfigPanel/ConfigEndEvent/CustomReceiptContent/CustomReceipt/CustomReceipt.test.tsx +++ b/frontend/packages/process-editor/src/components/ConfigPanel/ConfigEndEvent/CustomReceiptContent/CustomReceipt/CustomReceipt.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { CustomReceipt } from './CustomReceipt'; import { render, screen } from '@testing-library/react'; -import { textMock } from '../../../../../../../../testing/mocks/i18nMock'; +import { textMock } from '@studio/testing/mocks/i18nMock'; import { BpmnContext } from '../../../../../contexts/BpmnContext'; import userEvent from '@testing-library/user-event'; import { BpmnApiContext, type BpmnApiContextProps } from '../../../../../contexts/BpmnApiContext'; @@ -72,7 +72,7 @@ describe('CustomReceipt', () => { }); }); - it('calls "mutateDataType" when the data model id is changed', async () => { + it('calls "mutateDataTypes" when the data model id is changed', async () => { const user = userEvent.setup(); renderCustomReceipt(); @@ -89,10 +89,10 @@ describe('CustomReceipt', () => { const option = screen.getByRole('option', { name: newOption }); await user.click(option); - expect(mockBpmnApiContextValue.mutateDataType).toHaveBeenCalledTimes(1); - expect(mockBpmnApiContextValue.mutateDataType).toHaveBeenCalledWith({ + expect(mockBpmnApiContextValue.mutateDataTypes).toHaveBeenCalledTimes(1); + expect(mockBpmnApiContextValue.mutateDataTypes).toHaveBeenCalledWith({ connectedTaskId: PROTECTED_TASK_NAME_CUSTOM_RECEIPT, - newDataType: newOption, + newDataTypes: [newOption], }); }); diff --git a/frontend/packages/process-editor/src/components/ConfigPanel/ConfigEndEvent/CustomReceiptContent/CustomReceipt/CustomReceipt.tsx b/frontend/packages/process-editor/src/components/ConfigPanel/ConfigEndEvent/CustomReceiptContent/CustomReceipt/CustomReceipt.tsx index 5de39ebee93..feee64b6fa5 100644 --- a/frontend/packages/process-editor/src/components/ConfigPanel/ConfigEndEvent/CustomReceiptContent/CustomReceipt/CustomReceipt.tsx +++ b/frontend/packages/process-editor/src/components/ConfigPanel/ConfigEndEvent/CustomReceiptContent/CustomReceipt/CustomReceipt.tsx @@ -7,7 +7,7 @@ import { useBpmnApiContext } from '../../../../../contexts/BpmnApiContext'; import { getDataTypeFromLayoutSetsWithExistingId } from '../../../../../utils/configPanelUtils'; import { RedirectToCreatePageButton } from '../RedirectToCreatePageButton'; import { useTranslation } from 'react-i18next'; -import { EditDataType } from '../../../EditDataType'; +import { EditDataTypes } from '../../../EditDataTypes'; import { PROTECTED_TASK_NAME_CUSTOM_RECEIPT } from 'app-shared/constants'; import { getLayoutSetIdValidationErrorKey } from 'app-shared/utils/layoutSetsUtils'; @@ -77,7 +77,7 @@ export const CustomReceipt = (): React.ReactElement => { 'aria-label': t('process_editor.configuration_panel_custom_receipt_textfield_label'), }} /> - { +describe('EditDataTypes', () => { afterEach(jest.clearAllMocks); it('should display a button to add data model when task has no data model', () => { - renderEditDataType({ + renderEditDataTypes({ bpmnApiContextProps: { layoutSets: layoutSetsWithoutDataTypeConnection }, }); expect( @@ -45,7 +45,7 @@ describe('EditDataType', () => { it('should display a combobox without value and a description that data models are missing when clicking "add data model" when there are no data models', async () => { const user = userEvent.setup(); - renderEditDataType({ + renderEditDataTypes({ bpmnApiContextProps: { layoutSets: layoutSetsWithoutDataTypeConnection, }, @@ -75,7 +75,7 @@ describe('EditDataType', () => { const user = userEvent.setup(); const availableDataModelIds = ['dataModel1', 'dataModel2']; const existingDataType = mockBpmnApiContextValue.layoutSets.sets[0].dataType; - renderEditDataType({ + renderEditDataTypes({ bpmnApiContextProps: { availableDataModelIds }, componentProps: { existingDataTypeForTask: existingDataType, @@ -106,7 +106,7 @@ describe('EditDataType', () => { const user = userEvent.setup(); const existingDataType = mockBpmnApiContextValue.layoutSets.sets[0].dataType; - renderEditDataType({ + renderEditDataTypes({ componentProps: { existingDataTypeForTask: existingDataType, dataModelIds: [existingDataType], @@ -127,7 +127,7 @@ describe('EditDataType', () => { it('should display the existing data type in preview when clicking the close button after edit mode and task has data type', async () => { const user = userEvent.setup(); - renderEditDataType({ + renderEditDataTypes({ componentProps: { existingDataTypeForTask: mockBpmnApiContextValue.layoutSets.sets[0].dataType, }, @@ -149,7 +149,7 @@ describe('EditDataType', () => { it('should display the button to add data model when clicking the close button after edit mode and task has no data type', async () => { const user = userEvent.setup(); - renderEditDataType({ + renderEditDataTypes({ bpmnApiContextProps: { layoutSets: layoutSetsWithoutDataTypeConnection }, componentProps: { existingDataTypeForTask: '' }, }); @@ -170,17 +170,17 @@ describe('EditDataType', () => { type RenderProps = { bpmnApiContextProps: Partial; - componentProps: Partial; + componentProps: Partial; }; -const renderEditDataType = (props: Partial = {}) => { +const renderEditDataTypes = (props: Partial = {}) => { const { bpmnApiContextProps, componentProps } = props; return render( - + , diff --git a/frontend/packages/process-editor/src/components/ConfigPanel/EditDataType/EditDataType.tsx b/frontend/packages/process-editor/src/components/ConfigPanel/EditDataTypes/EditDataTypes.tsx similarity index 89% rename from frontend/packages/process-editor/src/components/ConfigPanel/EditDataType/EditDataType.tsx rename to frontend/packages/process-editor/src/components/ConfigPanel/EditDataTypes/EditDataTypes.tsx index ca1738f702b..271cfa57661 100644 --- a/frontend/packages/process-editor/src/components/ConfigPanel/EditDataType/EditDataType.tsx +++ b/frontend/packages/process-editor/src/components/ConfigPanel/EditDataTypes/EditDataTypes.tsx @@ -2,23 +2,23 @@ import React, { useEffect, useState } from 'react'; import { StudioProperty } from '@studio/components'; import { useTranslation } from 'react-i18next'; import { LinkIcon } from '@studio/icons'; -import { SelectDataType } from './SelectDataType'; -import classes from './EditDataType.module.css'; +import { SelectDataTypes } from './SelectDataTypes'; +import classes from './EditDataTypes.module.css'; import { useBpmnContext } from '../../../contexts/BpmnContext'; -export type EditDataTypeProps = { +export type EditDataTypesProps = { dataModelIds: string[]; connectedTaskId: string; existingDataTypeForTask: string | undefined; hideDeleteButton?: boolean; }; -export const EditDataType = ({ +export const EditDataTypes = ({ dataModelIds, connectedTaskId, existingDataTypeForTask, hideDeleteButton = false, -}: EditDataTypeProps) => { +}: EditDataTypesProps) => { const { t } = useTranslation(); const { bpmnDetails } = useBpmnContext(); const [dataModelSelectVisible, setDataModelSelectVisible] = useState(false); @@ -43,7 +43,7 @@ export const EditDataType = ({ icon={} /> ) : dataModelSelectVisible ? ( - { +describe('SelectDataTypes', () => { afterEach(jest.clearAllMocks); - it('should call updateDataType with new data type when new option is clicked', async () => { + it('should call updateDataTypes with new data type when new option is clicked', async () => { const user = userEvent.setup(); - const mutateDataTypeMock = jest.fn(); + const mutateDataTypesMock = jest.fn(); const dataTypeToConnect = 'dataModel0'; const dataModelIds = [dataTypeToConnect, 'dataModel1', 'dataModel2']; - renderEditDataType( + renderSelectDataTypes( { dataModelIds }, { - mutateDataType: mutateDataTypeMock, + mutateDataTypes: mutateDataTypesMock, }, ); const combobox = screen.getByRole('combobox', { @@ -44,9 +44,9 @@ describe('SelectDataType', () => { await user.click(combobox); await user.click(screen.getByRole('option', { name: dataTypeToConnect })); - expect(mutateDataTypeMock).toHaveBeenCalledWith({ + expect(mutateDataTypesMock).toHaveBeenCalledWith({ connectedTaskId, - newDataType: dataTypeToConnect, + newDataTypes: [dataTypeToConnect], }); }); @@ -54,7 +54,7 @@ describe('SelectDataType', () => { const user = userEvent.setup(); const existingDataType = 'dataModel0'; const dataModelIds = ['dataModel1', 'dataModel2']; - renderEditDataType({ dataModelIds, existingDataType }); + renderSelectDataTypes({ dataModelIds, existingDataType }); const combobox = screen.getByRole('combobox', { name: textMock('process_editor.configuration_panel_set_data_model'), @@ -66,16 +66,16 @@ describe('SelectDataType', () => { expect(addedOption).toBeInTheDocument(); }); - it('should call updateDataType with new data type when data type is changed', async () => { + it('should call updateDataTypes with new data type when data type is changed', async () => { const user = userEvent.setup(); - const mutateDataTypeMock = jest.fn(); + const mutateDataTypesMock = jest.fn(); const existingDataType = 'dataModel0'; const dataTypeToConnect = 'dataModel1'; const dataModelIds = [existingDataType, dataTypeToConnect, 'dataModel2']; - renderEditDataType( + renderSelectDataTypes( { dataModelIds, existingDataType }, { - mutateDataType: mutateDataTypeMock, + mutateDataTypes: mutateDataTypesMock, }, ); const combobox = screen.getByRole('combobox', { @@ -84,44 +84,44 @@ describe('SelectDataType', () => { await user.click(combobox); await user.click(screen.getByRole('option', { name: dataTypeToConnect })); - expect(mutateDataTypeMock).toHaveBeenCalledWith({ + expect(mutateDataTypesMock).toHaveBeenCalledWith({ connectedTaskId, - newDataType: dataTypeToConnect, + newDataTypes: [dataTypeToConnect], }); expect(mockOnClose).toHaveBeenCalled(); }); - it('should call updateDataType with no data type when data type is deleted', async () => { + it('should call updateDataTypes with no data type when data type is deleted', async () => { const user = userEvent.setup(); - const mutateDataTypeMock = jest.fn(); + const mutateDataTypesMock = jest.fn(); const existingDataType = 'dataModel0'; const dataModelIds = [existingDataType, 'dataModel1', 'dataModel2']; - renderEditDataType( + renderSelectDataTypes( { dataModelIds, existingDataType }, { - mutateDataType: mutateDataTypeMock, + mutateDataTypes: mutateDataTypesMock, }, ); const deleteDataTypeButton = screen.getByRole('button', { name: textMock('general.delete'), }); await user.click(deleteDataTypeButton); - expect(mutateDataTypeMock).toHaveBeenCalledWith({ + expect(mutateDataTypesMock).toHaveBeenCalledWith({ connectedTaskId, - newDataType: undefined, + newDataTypes: [undefined], }); expect(mockOnClose).toHaveBeenCalled(); }); - it('should not call updateDataType when data type is set to existing', async () => { + it('should not call updateDataTypes when data type is set to existing', async () => { const user = userEvent.setup(); - const mutateDataTypeMock = jest.fn(); + const mutateDataTypesMock = jest.fn(); const existingDataType = 'dataModel0'; const dataModelIds = [existingDataType, 'dataModel1', 'dataModel2']; - renderEditDataType( + renderSelectDataTypes( { dataModelIds, existingDataType }, { - mutateDataType: mutateDataTypeMock, + mutateDataTypes: mutateDataTypesMock, }, ); const combobox = screen.getByRole('combobox', { @@ -130,20 +130,20 @@ describe('SelectDataType', () => { await user.click(combobox); await user.click(screen.getByRole('option', { name: existingDataType })); - expect(mutateDataTypeMock).not.toHaveBeenCalled(); + expect(mutateDataTypesMock).not.toHaveBeenCalled(); expect(mockOnClose).toHaveBeenCalled(); }); }); -const renderEditDataType = ( - props: Partial = {}, +const renderSelectDataTypes = ( + props: Partial = {}, bpmnApiContextProps: Partial = {}, ) => { return render( - + , diff --git a/frontend/packages/process-editor/src/components/ConfigPanel/EditDataType/SelectDataType/SelectDataType.tsx b/frontend/packages/process-editor/src/components/ConfigPanel/EditDataTypes/SelectDataTypes/SelectDataTypes.tsx similarity index 83% rename from frontend/packages/process-editor/src/components/ConfigPanel/EditDataType/SelectDataType/SelectDataType.tsx rename to frontend/packages/process-editor/src/components/ConfigPanel/EditDataTypes/SelectDataTypes/SelectDataTypes.tsx index f42cd6a2bb0..2ebcab5f799 100644 --- a/frontend/packages/process-editor/src/components/ConfigPanel/EditDataType/SelectDataType/SelectDataType.tsx +++ b/frontend/packages/process-editor/src/components/ConfigPanel/EditDataTypes/SelectDataTypes/SelectDataTypes.tsx @@ -4,10 +4,10 @@ import { StudioButton, StudioDeleteButton } from '@studio/components'; import { useBpmnApiContext } from '../../../../contexts/BpmnApiContext'; import { useTranslation } from 'react-i18next'; import { XMarkIcon } from '@studio/icons'; -import classes from './SelectDataType.module.css'; -import type { DataTypeChange } from 'app-shared/types/api/DataTypeChange'; +import classes from './SelectDataTypes.module.css'; +import type { DataTypesChange } from 'app-shared/types/api/DataTypesChange'; -export interface SelectDataTypeProps { +export interface SelectDataTypesProps { dataModelIds: string[]; existingDataType: string; connectedTaskId: string; @@ -15,26 +15,25 @@ export interface SelectDataTypeProps { hideDeleteButton?: boolean; } -export const SelectDataType = ({ +export const SelectDataTypes = ({ dataModelIds, existingDataType, connectedTaskId, onClose, hideDeleteButton, -}: SelectDataTypeProps): React.ReactElement => { +}: SelectDataTypesProps): React.ReactElement => { const { t } = useTranslation(); - const { mutateDataType } = useBpmnApiContext(); - + const { mutateDataTypes } = useBpmnApiContext(); const currentValue = existingDataType ? [existingDataType] : []; const handleChangeDataModel = (newDataModelIds?: string[]) => { const newDataModelId = newDataModelIds ? newDataModelIds[0] : undefined; if (newDataModelId !== existingDataType) { - const dataTypeChange: DataTypeChange = { - newDataType: newDataModelId, + const dataTypesChange: DataTypesChange = { + newDataTypes: [newDataModelId], connectedTaskId, }; - mutateDataType(dataTypeChange); + mutateDataTypes(dataTypesChange); } onClose(); }; diff --git a/frontend/packages/process-editor/src/components/ConfigPanel/EditDataTypes/SelectDataTypes/index.ts b/frontend/packages/process-editor/src/components/ConfigPanel/EditDataTypes/SelectDataTypes/index.ts new file mode 100644 index 00000000000..d89e3f204a8 --- /dev/null +++ b/frontend/packages/process-editor/src/components/ConfigPanel/EditDataTypes/SelectDataTypes/index.ts @@ -0,0 +1 @@ +export { SelectDataTypes } from './SelectDataTypes'; diff --git a/frontend/packages/process-editor/src/components/ConfigPanel/EditDataTypes/index.ts b/frontend/packages/process-editor/src/components/ConfigPanel/EditDataTypes/index.ts new file mode 100644 index 00000000000..fb2c5739d68 --- /dev/null +++ b/frontend/packages/process-editor/src/components/ConfigPanel/EditDataTypes/index.ts @@ -0,0 +1 @@ +export { EditDataTypes } from './EditDataTypes'; diff --git a/frontend/packages/process-editor/src/contexts/BpmnApiContext.tsx b/frontend/packages/process-editor/src/contexts/BpmnApiContext.tsx index d93ca8c089a..b6089a1ea49 100644 --- a/frontend/packages/process-editor/src/contexts/BpmnApiContext.tsx +++ b/frontend/packages/process-editor/src/contexts/BpmnApiContext.tsx @@ -1,8 +1,8 @@ import type { LayoutSets, LayoutSetConfig } from 'app-shared/types/api/LayoutSetsResponse'; import React, { createContext, useContext } from 'react'; -import type { MetaDataForm } from 'app-shared/types/BpmnMetaDataForm'; -import type { DataTypeChange } from 'app-shared/types/api/DataTypeChange'; +import type { MetadataForm } from 'app-shared/types/BpmnMetadataForm'; import type { OnProcessTaskEvent } from '../types/OnProcessTask'; +import type { DataTypesChange } from 'app-shared/types/api/DataTypesChange'; type QueryOptions = { onSuccess: () => void; @@ -21,8 +21,8 @@ export type BpmnApiContextProps = { ) => void; deleteLayoutSet: (data: { layoutSetIdToUpdate: string }) => void; mutateLayoutSetId: (data: { layoutSetIdToUpdate: string; newLayoutSetId: string }) => void; - mutateDataType: (dataTypeChange: DataTypeChange, options?: QueryOptions) => void; - saveBpmn: (bpmnXml: string, metaData?: MetaDataForm) => void; + mutateDataTypes: (dataTypesChange: DataTypesChange, options?: QueryOptions) => void; + saveBpmn: (bpmnXml: string, metadata?: MetadataForm) => void; openPolicyEditor: () => void; onProcessTaskAdd: (taskMetadata: OnProcessTaskEvent) => void; onProcessTaskRemove: (taskMetadata: OnProcessTaskEvent) => void; diff --git a/frontend/packages/process-editor/src/contexts/BpmnConfigPanelContext.test.tsx b/frontend/packages/process-editor/src/contexts/BpmnConfigPanelContext.test.tsx index c0022fc86e1..e7d5bcbf1f9 100644 --- a/frontend/packages/process-editor/src/contexts/BpmnConfigPanelContext.test.tsx +++ b/frontend/packages/process-editor/src/contexts/BpmnConfigPanelContext.test.tsx @@ -22,8 +22,8 @@ describe('BpmnConfigPanelContext', () => { it('should provide a useBpmnConfigPanelFormContext hook', () => { const TestComponent = () => { - const { metaDataFormRef } = useBpmnConfigPanelFormContext(); - return
{JSON.stringify(metaDataFormRef.current)}
; + const { metadataFormRef } = useBpmnConfigPanelFormContext(); + return
{JSON.stringify(metadataFormRef.current)}
; }; render( @@ -52,26 +52,26 @@ describe('BpmnConfigPanelContext', () => { it('should provide method to reset meta data', async () => { const user = userEvent.setup(); const TestComponent = () => { - const { metaDataFormRef, resetForm } = useBpmnConfigPanelFormContext(); - // Need to update state to trigger a rerender since metaDataFormRef is a mutable object that does not trigger rerender + const { metadataFormRef, resetForm } = useBpmnConfigPanelFormContext(); + // Need to update state to trigger a rerender since metadataFormRef is a mutable object that does not trigger rerender const [, setState] = useState(undefined); - const handleSetMetaData = () => { + const handleSetMetadata = () => { setState('test'); - metaDataFormRef.current = { taskIdChange: { oldId: 'old', newId: 'new' } }; + metadataFormRef.current = { taskIdChange: { oldId: 'old', newId: 'new' } }; }; - const handleResetMetaData = () => { + const handleResetMetadata = () => { setState(undefined); resetForm(); }; return (
- - + +
- {metaDataFormRef.current ? JSON.stringify(metaDataFormRef.current) : 'Empty'} + {metadataFormRef.current ? JSON.stringify(metadataFormRef.current) : 'Empty'}
); diff --git a/frontend/packages/process-editor/src/contexts/BpmnConfigPanelContext.tsx b/frontend/packages/process-editor/src/contexts/BpmnConfigPanelContext.tsx index 4ba35b1b297..811a51135b1 100644 --- a/frontend/packages/process-editor/src/contexts/BpmnConfigPanelContext.tsx +++ b/frontend/packages/process-editor/src/contexts/BpmnConfigPanelContext.tsx @@ -1,8 +1,8 @@ import React, { createContext, useContext, useRef } from 'react'; -import type { MetaDataForm } from 'app-shared/types/BpmnMetaDataForm'; +import type { MetadataForm } from 'app-shared/types/BpmnMetadataForm'; type BpmnConfigPanelContextType = { - metaDataFormRef: React.MutableRefObject; + metadataFormRef: React.MutableRefObject; resetForm: () => void; }; @@ -15,13 +15,13 @@ export type BpmnConfigPanelFormContextProviderProps = { export const BpmnConfigPanelFormContextProvider = ({ children, }: BpmnConfigPanelFormContextProviderProps): React.ReactElement => { - const metaDataFormRef = useRef(undefined); + const metadataFormRef = useRef(undefined); const resetForm = (): void => { - metaDataFormRef.current = undefined; + metadataFormRef.current = undefined; }; return ( - + {children} ); diff --git a/frontend/packages/process-editor/src/hooks/useBpmnEditor.test.tsx b/frontend/packages/process-editor/src/hooks/useBpmnEditor.test.tsx index 89935df6da8..3dcdfe410a0 100644 --- a/frontend/packages/process-editor/src/hooks/useBpmnEditor.test.tsx +++ b/frontend/packages/process-editor/src/hooks/useBpmnEditor.test.tsx @@ -55,7 +55,7 @@ jest.mock('../utils/hookUtils', () => ({ jest.mock('../contexts/BpmnConfigPanelContext', () => ({ useBpmnConfigPanelFormContext: jest.fn(() => ({ - metaDataFormRef: { current: null }, + metadataFormRef: { current: null }, resetForm: jest.fn(), })), })); diff --git a/frontend/packages/process-editor/src/hooks/useBpmnEditor.ts b/frontend/packages/process-editor/src/hooks/useBpmnEditor.ts index e6390e72bda..7535bc3c857 100644 --- a/frontend/packages/process-editor/src/hooks/useBpmnEditor.ts +++ b/frontend/packages/process-editor/src/hooks/useBpmnEditor.ts @@ -17,13 +17,13 @@ type UseBpmnViewerResult = { export const useBpmnEditor = (): UseBpmnViewerResult => { const { getUpdatedXml, bpmnXml, modelerRef, setBpmnDetails } = useBpmnContext(); const canvasRef = useRef(null); - const { metaDataFormRef, resetForm } = useBpmnConfigPanelFormContext(); + const { metadataFormRef, resetForm } = useBpmnConfigPanelFormContext(); const { getModeler, destroyModeler } = useBpmnModeler(); const { saveBpmn, onProcessTaskAdd, onProcessTaskRemove } = useBpmnApiContext(); const handleCommandStackChanged = async () => { - saveBpmn(await getUpdatedXml(), metaDataFormRef.current || null); + saveBpmn(await getUpdatedXml(), metadataFormRef.current || null); resetForm(); }; diff --git a/frontend/packages/process-editor/test/mocks/bpmnContextMock.ts b/frontend/packages/process-editor/test/mocks/bpmnContextMock.ts index 0d07c6ae5df..43e2eb54a52 100644 --- a/frontend/packages/process-editor/test/mocks/bpmnContextMock.ts +++ b/frontend/packages/process-editor/test/mocks/bpmnContextMock.ts @@ -42,7 +42,7 @@ export const mockBpmnApiContextValue: BpmnApiContextProps = { addLayoutSet: jest.fn(), deleteLayoutSet: jest.fn(), mutateLayoutSetId: jest.fn(), - mutateDataType: jest.fn(), + mutateDataTypes: jest.fn(), saveBpmn: jest.fn(), openPolicyEditor: jest.fn(), onProcessTaskRemove: jest.fn(), diff --git a/frontend/packages/shared/src/api/mutations.ts b/frontend/packages/shared/src/api/mutations.ts index 7bd8513b17a..f09c36a5213 100644 --- a/frontend/packages/shared/src/api/mutations.ts +++ b/frontend/packages/shared/src/api/mutations.ts @@ -36,7 +36,7 @@ import { processEditorPathPut, layoutSetPath, processEditorDataTypePath, - processEditorDataTypeChangePath, + processEditorDataTypesChangePath, dataModelsUploadPath, } from 'app-shared/api/paths'; import type { AddLanguagePayload } from 'app-shared/types/api/AddLanguagePayload'; @@ -61,7 +61,7 @@ import type { AppConfig } from 'app-shared/types/AppConfig'; import type { Repository } from 'app-shared/types/Repository'; import type { PipelineDeployment } from 'app-shared/types/api/PipelineDeployment'; import type { AddLayoutSetResponse } from 'app-shared/types/api/AddLayoutSetResponse'; -import type { DataTypeChange } from 'app-shared/types/api/DataTypeChange'; +import type { DataTypesChange } from 'app-shared/types/api/DataTypesChange'; const headers = { Accept: 'application/json', @@ -137,4 +137,4 @@ export const updateBpmnXml = (org: string, app: string, form: any) => }, }); -export const updateProcessDataType = (org: string, app: string, dataTypeChange: DataTypeChange) => put(processEditorDataTypeChangePath(org, app), dataTypeChange); +export const updateProcessDataTypes = (org: string, app: string, dataTypesChange: DataTypesChange) => put(processEditorDataTypesChangePath(org, app), dataTypesChange); diff --git a/frontend/packages/shared/src/api/paths.js b/frontend/packages/shared/src/api/paths.js index dee6a6c8ddd..dfa838ecac9 100644 --- a/frontend/packages/shared/src/api/paths.js +++ b/frontend/packages/shared/src/api/paths.js @@ -4,7 +4,7 @@ import { APP_DEVELOPMENT_BASENAME, PREVIEW_MOCK_PARTY_ID, PREVIEW_MOCK_INSTANCE_ // Base path const basePath = '/designer/api'; -// ApplicationMetaData +// ApplicationMetadata export const appMetadataPath = (org, app) => `${basePath}/${org}/${app}/metadata`; // Get, Put, Post export const appMetadataAttachmentPath = (org, app) => `${basePath}/${org}/${app}/metadata/attachment-component`; // Post, Put, Delete @@ -150,6 +150,6 @@ export const resourceAccessListPath = (org, resourceId, listId, env) => `${baseP export const processEditorPath = (org, app) => `${basePath}/${org}/${app}/process-modelling/process-definition`; export const processEditorWebSocketHub = () => '/sync-hub'; export const processEditorPathPut = (org, app) => `${basePath}/${org}/${app}/process-modelling/process-definition-latest`; -export const processEditorDataTypeChangePath = (org, app) => `${basePath}/${org}/${app}/process-modelling/data-type`; +export const processEditorDataTypesChangePath = (org, app) => `${basePath}/${org}/${app}/process-modelling/data-types`; export const processTaskTypePath = (org, app, taskId) => `${basePath}/${org}/${app}/process-modelling/task-type/${taskId}`; // Get export const processEditorDataTypePath = (org, app, dataTypeId, taskId) => `${basePath}/${org}/${app}/process-modelling/data-type/${dataTypeId}?${s({ taskId })}`; diff --git a/frontend/packages/shared/src/components/GiteaHeader/VersionControlButtons/VersionControlButtons.test.tsx b/frontend/packages/shared/src/components/GiteaHeader/VersionControlButtons/VersionControlButtons.test.tsx index f05de4d9925..5520d1589ed 100644 --- a/frontend/packages/shared/src/components/GiteaHeader/VersionControlButtons/VersionControlButtons.test.tsx +++ b/frontend/packages/shared/src/components/GiteaHeader/VersionControlButtons/VersionControlButtons.test.tsx @@ -242,7 +242,7 @@ const renderVersionControlButtons = ( hasPushRights = true, ) => { const queryClient = createQueryClientMock(); - queryClient.setQueryData([QueryKey.RepoMetaData, org, app], { + queryClient.setQueryData([QueryKey.RepoMetadata, org, app], { ...repository, permissions: { ...repository.permissions, push: hasPushRights }, }); diff --git a/frontend/packages/shared/src/hooks/queries/useRepoMetadataQuery.ts b/frontend/packages/shared/src/hooks/queries/useRepoMetadataQuery.ts index 7946f4af796..aea8389ba0d 100644 --- a/frontend/packages/shared/src/hooks/queries/useRepoMetadataQuery.ts +++ b/frontend/packages/shared/src/hooks/queries/useRepoMetadataQuery.ts @@ -20,7 +20,7 @@ export const useRepoMetadataQuery = ( ): UseQueryResult => { const { getRepoMetadata } = useServicesContext(); return useQuery({ - queryKey: [QueryKey.RepoMetaData, owner, app], + queryKey: [QueryKey.RepoMetadata, owner, app], queryFn: () => getRepoMetadata(owner, app), meta, }); diff --git a/frontend/packages/shared/src/mocks/queriesMock.ts b/frontend/packages/shared/src/mocks/queriesMock.ts index 5491fde333c..528a72e4758 100644 --- a/frontend/packages/shared/src/mocks/queriesMock.ts +++ b/frontend/packages/shared/src/mocks/queriesMock.ts @@ -225,5 +225,5 @@ export const queriesMock: ServicesContextProps = { // Mutations - ProcessEditor updateBpmnXml: jest.fn().mockImplementation(() => Promise.resolve()), - updateProcessDataType: jest.fn().mockImplementation(() => Promise.resolve()), + updateProcessDataTypes: jest.fn().mockImplementation(() => Promise.resolve()), }; diff --git a/frontend/packages/shared/src/types/BpmnMetaDataForm.ts b/frontend/packages/shared/src/types/BpmnMetadataForm.ts similarity index 77% rename from frontend/packages/shared/src/types/BpmnMetaDataForm.ts rename to frontend/packages/shared/src/types/BpmnMetadataForm.ts index cb922983694..975e57caa1b 100644 --- a/frontend/packages/shared/src/types/BpmnMetaDataForm.ts +++ b/frontend/packages/shared/src/types/BpmnMetadataForm.ts @@ -3,6 +3,6 @@ export type TaskIdChange = { newId: string; }; -export type MetaDataForm = { +export type MetadataForm = { taskIdChange?: TaskIdChange; }; diff --git a/frontend/packages/shared/src/types/QueryKey.ts b/frontend/packages/shared/src/types/QueryKey.ts index e73cb4f89c0..a3f663995a8 100644 --- a/frontend/packages/shared/src/types/QueryKey.ts +++ b/frontend/packages/shared/src/types/QueryKey.ts @@ -28,7 +28,7 @@ export enum QueryKey { OrgList = 'OrgList', Organizations = 'Organizations', ProcessTaskDataType = 'ProcessTaskDataType', - RepoMetaData = 'RepoMetaData', + RepoMetadata = 'RepoMetadata', RepoPullData = 'RepoPullData', RepoReset = 'RepoReset', RepoStatus = 'RepoStatus', diff --git a/frontend/packages/shared/src/types/api/DataTypeChange.ts b/frontend/packages/shared/src/types/api/DataTypeChange.ts deleted file mode 100644 index 2f03f1424b0..00000000000 --- a/frontend/packages/shared/src/types/api/DataTypeChange.ts +++ /dev/null @@ -1,4 +0,0 @@ -export type DataTypeChange = { - newDataType: string; - connectedTaskId: string; -}; diff --git a/frontend/packages/shared/src/types/api/DataTypesChange.ts b/frontend/packages/shared/src/types/api/DataTypesChange.ts new file mode 100644 index 00000000000..699cb7c4b75 --- /dev/null +++ b/frontend/packages/shared/src/types/api/DataTypesChange.ts @@ -0,0 +1,4 @@ +export type DataTypesChange = { + newDataTypes: string[]; + connectedTaskId: string; +}; diff --git a/frontend/packages/ux-editor-v3/src/hooks/mutations/useAddItemToLayoutMutation.test.ts b/frontend/packages/ux-editor-v3/src/hooks/mutations/useAddItemToLayoutMutation.test.ts index b8fcd0eb772..f4a20dc78ac 100644 --- a/frontend/packages/ux-editor-v3/src/hooks/mutations/useAddItemToLayoutMutation.test.ts +++ b/frontend/packages/ux-editor-v3/src/hooks/mutations/useAddItemToLayoutMutation.test.ts @@ -39,7 +39,7 @@ const appStateMockCopy = (layoutSetName: string): Partial => ({ }, }); -const applicationAttachmentMetaDataMock: ApplicationAttachmentMetadata = { +const applicationAttachmentMetadataMock: ApplicationAttachmentMetadata = { id, taskId: 'some-task-id', maxCount: 1, @@ -84,7 +84,7 @@ describe('useAddItemToLayoutMutation', () => { result.current.mutate({ ...defaultArgs, componentType: ComponentTypeV3.FileUpload }); await waitFor(() => expect(result.current.isSuccess).toBe(true)); expect(queriesMock.addAppAttachmentMetadata).toHaveBeenCalledWith(org, app, { - ...applicationAttachmentMetaDataMock, + ...applicationAttachmentMetadataMock, taskId: 'Task_2', }); }); @@ -94,7 +94,7 @@ describe('useAddItemToLayoutMutation', () => { result.current.mutate({ ...defaultArgs, componentType: ComponentTypeV3.FileUpload }); await waitFor(() => expect(result.current.isSuccess).toBe(true)); expect(queriesMock.addAppAttachmentMetadata).toHaveBeenCalledWith(org, app, { - ...applicationAttachmentMetaDataMock, + ...applicationAttachmentMetadataMock, taskId: 'Task_1', }); }); diff --git a/frontend/packages/ux-editor/src/hooks/mutations/useAddItemToLayoutMutation.test.ts b/frontend/packages/ux-editor/src/hooks/mutations/useAddItemToLayoutMutation.test.ts index ad3f3016797..a2415ee70c1 100644 --- a/frontend/packages/ux-editor/src/hooks/mutations/useAddItemToLayoutMutation.test.ts +++ b/frontend/packages/ux-editor/src/hooks/mutations/useAddItemToLayoutMutation.test.ts @@ -27,7 +27,7 @@ const defaultArgs: AddFormItemMutationArgs = { index: 0, }; -const applicationAttachmentMetaDataMock: ApplicationAttachmentMetadata = { +const applicationAttachmentMetadataMock: ApplicationAttachmentMetadata = { id, taskId: 'some-task-id', maxCount: 1, @@ -72,7 +72,7 @@ describe('useAddItemToLayoutMutation', () => { result.current.mutate({ ...defaultArgs, componentType: ComponentType.FileUpload }); await waitFor(() => expect(result.current.isSuccess).toBe(true)); expect(queriesMock.addAppAttachmentMetadata).toHaveBeenCalledWith(org, app, { - ...applicationAttachmentMetaDataMock, + ...applicationAttachmentMetadataMock, taskId: 'Task_2', }); }); @@ -82,7 +82,7 @@ describe('useAddItemToLayoutMutation', () => { result.current.mutate({ ...defaultArgs, componentType: ComponentType.FileUpload }); await waitFor(() => expect(result.current.isSuccess).toBe(true)); expect(queriesMock.addAppAttachmentMetadata).toHaveBeenCalledWith(org, app, { - ...applicationAttachmentMetaDataMock, + ...applicationAttachmentMetadataMock, taskId: 'Task_1', }); });