From 4d74063f0d331229dd8bb392dab9c6264c26f3ad Mon Sep 17 00:00:00 2001 From: Konrad-Simso Date: Wed, 5 Feb 2025 11:04:39 +0100 Subject: [PATCH 1/7] Initial implementation of TextController for org level. --- .../Organisation/TextController.cs | 112 ++++++++++++++++++ .../GitRepository/AltinnOrgGitRepository.cs | 76 ++++++++++++ .../Infrastructure/ServiceRegistration.cs | 3 + .../Organisation/OrgTextsService.cs | 101 ++++++++++++++++ .../Interfaces/IAltinnGitRepositoryFactory.cs | 12 +- .../Organisation/IOrgTextsService.cs | 41 +++++++ 6 files changed, 343 insertions(+), 2 deletions(-) create mode 100644 backend/src/Designer/Controllers/Organisation/TextController.cs create mode 100644 backend/src/Designer/Infrastructure/GitRepository/AltinnOrgGitRepository.cs create mode 100644 backend/src/Designer/Services/Implementation/Organisation/OrgTextsService.cs create mode 100644 backend/src/Designer/Services/Interfaces/Organisation/IOrgTextsService.cs diff --git a/backend/src/Designer/Controllers/Organisation/TextController.cs b/backend/src/Designer/Controllers/Organisation/TextController.cs new file mode 100644 index 00000000000..166b693fdbd --- /dev/null +++ b/backend/src/Designer/Controllers/Organisation/TextController.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Altinn.Studio.Designer.Helpers; +using Altinn.Studio.Designer.Models; +using Altinn.Studio.Designer.Services.Interfaces.Organisation; +using LibGit2Sharp; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace Altinn.Studio.Designer.Controllers.Organisation; + +/// +/// Controller for text resources on organisation level +/// +[ApiController] +[Authorize] +[Route("designer/api/{org}/text")] +public class TextController : ControllerBase +{ + private readonly IOrgTextsService _orgTextsService; + private const string Repo = "content"; + + /// + /// Initializes a new instance of the /> class. + /// + /// The texts service. + public TextController(IOrgTextsService orgTextsService) + { + _orgTextsService = orgTextsService; + } + + /// + /// Returns a JSON resource file for the given language code + /// + /// Unique identifier of the organisation responsible for the app. + /// The resource language id (for example nb, en) + /// The JSON config + [HttpGet] + [Route("language/{languageCode}")] + public async Task> GetResource(string org, string languageCode) + { + try + { + string developer = AuthenticationHelper.GetDeveloperUserName(HttpContext); + TextResource textResource = await _orgTextsService.GetText(org, Repo, developer, languageCode); + return Ok(textResource); + } + catch (NotFoundException) + { + return NotFound($"Text resource, resource.{languageCode}.json, could not be found."); + } + + } + + /// + /// Save a resource file + /// + /// The JSON Data + /// The resource language id (for example nb, en ) + /// Unique identifier of the organisation responsible for the app. + /// The updated resource file + [HttpPost] + [Route("language/{languageCode}")] + public async Task> CreateResource([FromBody] TextResource jsonData, string languageCode, string org) + { + try + { + string developer = AuthenticationHelper.GetDeveloperUserName(HttpContext); + await _orgTextsService.SaveText(org, Repo, developer, jsonData, languageCode); + + TextResource textResource = await _orgTextsService.GetText(org, Repo, developer, languageCode); + return Ok(textResource); + } + catch (ArgumentException e) + { + return BadRequest(e.Message); + } + } + + /// + /// Method to update multiple texts for given keys and a given + /// language in the text resource files in the old format. + /// Non-existing keys will be added. + /// + /// Unique identifier of the organisation responsible for the app. + /// List of Key/Value pairs that should be updated or added if not present. + /// The languageCode for the text resource file that is being edited. + /// Temporary method that should live until old text format is replaced by the new. + /// The updated resource file + [HttpPut] + [Route("language/{languageCode}")] + public async Task> UpdateResource(string org, [FromBody] Dictionary keysTexts, string languageCode) + { + try + { + string developer = AuthenticationHelper.GetDeveloperUserName(HttpContext); + await _orgTextsService.UpdateTextsForKeys(org, Repo, developer, keysTexts, languageCode); + + TextResource textResource = await _orgTextsService.GetText(org, Repo, developer, languageCode); + return Ok(textResource); + } + catch (ArgumentException exception) + { + return BadRequest(exception.Message); + } + catch (Exception) + { + return BadRequest($"The text resource, resource.{languageCode}.json, could not be updated."); + } + } +} diff --git a/backend/src/Designer/Infrastructure/GitRepository/AltinnOrgGitRepository.cs b/backend/src/Designer/Infrastructure/GitRepository/AltinnOrgGitRepository.cs new file mode 100644 index 00000000000..b121dd42409 --- /dev/null +++ b/backend/src/Designer/Infrastructure/GitRepository/AltinnOrgGitRepository.cs @@ -0,0 +1,76 @@ +using System.IO; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Threading; +using System.Threading.Tasks; +using Altinn.Studio.Designer.Models; +using LibGit2Sharp; +using JsonSerializer = System.Text.Json.JsonSerializer; + +namespace Altinn.Studio.Designer.Infrastructure.GitRepository; + +public class AltinnOrgGitRepository : AltinnGitRepository +{ + private const string LanguageResourceFolderName = "texts/"; + + + private static readonly JsonSerializerOptions JsonOptions = new() + { + WriteIndented = true, + Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + PropertyNameCaseInsensitive = true + }; + + /// + /// Initializes a new instance of the class. + /// + /// Organization owning the repository identified by it's short name. + /// Repository name to search for schema files. + /// Developer that is working on the repository. + /// Base path (full) for where the repository resides on-disk. + /// Full path to the root directory of this repository on-disk. + public AltinnOrgGitRepository(string org, string repository, string developer, string repositoriesRootDirectory, string repositoryDirectory) : base(org, repository, developer, repositoriesRootDirectory, repositoryDirectory) + { + } + + /// + /// Returns a specific text resource written in the old text format + /// based on language code from the application. + /// + /// + /// Format of the dictionary is: <textResourceElementId <language, textResourceElement>> + /// + public async Task GetText(string language, CancellationToken cancellationToken = default) + { + cancellationToken.ThrowIfCancellationRequested(); + string resourcePath = GetPathToJsonTextsFile($"resource.{language}.json"); + if (!FileExistsByRelativePath(resourcePath)) + { + throw new NotFoundException("Text resource file not found."); + } + string fileContent = await ReadTextByRelativePathAsync(resourcePath, cancellationToken); + TextResource textResource = JsonSerializer.Deserialize(fileContent, JsonOptions); + + return textResource; + } + + /// + /// Saves the text resource based on language code from the application. + /// + /// Language code + /// text resource + public async Task SaveText(string languageCode, TextResource jsonTexts) + { + string fileName = $"resource.{languageCode}.json"; + string textsFileRelativeFilePath = GetPathToJsonTextsFile(fileName); + string texts = JsonSerializer.Serialize(jsonTexts, JsonOptions); + await WriteTextByRelativePathAsync(textsFileRelativeFilePath, texts); + } + + private static string GetPathToJsonTextsFile(string fileName) + { + return string.IsNullOrEmpty(fileName) ? LanguageResourceFolderName : Path.Combine(LanguageResourceFolderName, fileName); + } +} diff --git a/backend/src/Designer/Infrastructure/ServiceRegistration.cs b/backend/src/Designer/Infrastructure/ServiceRegistration.cs index 1a17d20b015..990d9aeb1d0 100644 --- a/backend/src/Designer/Infrastructure/ServiceRegistration.cs +++ b/backend/src/Designer/Infrastructure/ServiceRegistration.cs @@ -12,9 +12,11 @@ using Altinn.Studio.Designer.Repository.ORMImplementation; using Altinn.Studio.Designer.Repository.ORMImplementation.Data; using Altinn.Studio.Designer.Services.Implementation; +using Altinn.Studio.Designer.Services.Implementation.Organisation; using Altinn.Studio.Designer.Services.Implementation.Preview; using Altinn.Studio.Designer.Services.Implementation.ProcessModeling; using Altinn.Studio.Designer.Services.Interfaces; +using Altinn.Studio.Designer.Services.Interfaces.Organisation; using Altinn.Studio.Designer.Services.Interfaces.Preview; using Altinn.Studio.Designer.TypedHttpClients.ImageClient; using Microsoft.EntityFrameworkCore; @@ -76,6 +78,7 @@ public static IServiceCollection RegisterServiceImplementations(this IServiceCol services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.RegisterDatamodeling(configuration); return services; diff --git a/backend/src/Designer/Services/Implementation/Organisation/OrgTextsService.cs b/backend/src/Designer/Services/Implementation/Organisation/OrgTextsService.cs new file mode 100644 index 00000000000..e7864095abd --- /dev/null +++ b/backend/src/Designer/Services/Implementation/Organisation/OrgTextsService.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Altinn.Studio.Designer.Infrastructure.GitRepository; +using Altinn.Studio.Designer.Models; +using Altinn.Studio.Designer.Services.Interfaces; +using Altinn.Studio.Designer.Services.Interfaces.Organisation; + +namespace Altinn.Studio.Designer.Services.Implementation.Organisation; + +public class OrgTextsService : IOrgTextsService +{ + private readonly IAltinnGitRepositoryFactory _altinnGitRepositoryFactory; + private readonly IApplicationMetadataService _applicationMetadataService; + + /// + /// Constructor + /// + /// IAltinnGitRepository + /// IApplicationMetadataService + public OrgTextsService(IAltinnGitRepositoryFactory altinnGitRepositoryFactory, IApplicationMetadataService applicationMetadataService) + { + _altinnGitRepositoryFactory = altinnGitRepositoryFactory; + _applicationMetadataService = applicationMetadataService; + } + + /// + public async Task GetText(string org, string repo, string developer, string languageCode) + { + AltinnOrgGitRepository altinnOrgGitRepository = _altinnGitRepositoryFactory.GetAltinnOrgGitRepository(org, repo, developer); + + TextResource texts = await altinnOrgGitRepository.GetText(languageCode); + + return texts; + } + + /// + public async Task SaveText(string org, string repo, string developer, TextResource textResource, string languageCode) + { + AltinnOrgGitRepository altinnOrgGitRepository = _altinnGitRepositoryFactory.GetAltinnOrgGitRepository(org, repo, developer); + + string[] duplicateKeys = textResource.Resources.GroupBy(tre => tre.Id).Where(grp => grp.Count() > 1).Select(grp => grp.Key).ToArray(); + if (duplicateKeys.Length > 0) + { + throw new ArgumentException($"Text keys must be unique. Please review keys: {string.Join(", ", duplicateKeys)}"); + } + + // updating application metadata with appTitle. + TextResourceElement appTitleResourceElement = textResource.Resources.FirstOrDefault(tre => tre.Id == "appName" || tre.Id == "ServiceName"); + + if (appTitleResourceElement != null && !string.IsNullOrEmpty(appTitleResourceElement.Value)) + { + await _applicationMetadataService.UpdateAppTitleInAppMetadata(org, repo, "nb", appTitleResourceElement.Value); + } + else + { + throw new ArgumentException("The application name must be a value."); + } + + await altinnOrgGitRepository.SaveText(languageCode, textResource); + } + + /// + public async Task UpdateTextsForKeys(string org, string repo, string developer, Dictionary keysTexts, string languageCode) + { + AltinnOrgGitRepository altinnOrgGitRepository = _altinnGitRepositoryFactory.GetAltinnOrgGitRepository(org, repo, developer); + TextResource textResourceObject = await altinnOrgGitRepository.GetText(languageCode); + + // handle if file not already exist + + foreach (KeyValuePair kvp in keysTexts) + { + if ((kvp.Key == "appName" || kvp.Key == "serviceName") && string.IsNullOrEmpty(kvp.Value)) + { + throw new ArgumentException("The application name must be a value."); + } + + TextResourceElement textResourceContainsKey = textResourceObject.Resources.Find(textResourceElement => textResourceElement.Id == kvp.Key); + if (textResourceContainsKey is null) + { + textResourceObject.Resources.Insert(0, new TextResourceElement() { Id = kvp.Key, Value = kvp.Value }); + } + else + { + int indexTextResourceElementUpdateKey = textResourceObject.Resources.IndexOf(textResourceContainsKey); + if (textResourceContainsKey.Variables == null) + { + textResourceObject.Resources[indexTextResourceElementUpdateKey] = new TextResourceElement { Id = kvp.Key, Value = kvp.Value }; + } + else + { + List variables = textResourceContainsKey.Variables; + textResourceObject.Resources[indexTextResourceElementUpdateKey] = new TextResourceElement { Id = kvp.Key, Value = kvp.Value, Variables = variables }; + } + } + } + + await altinnOrgGitRepository.SaveText(languageCode, textResourceObject); + } +} diff --git a/backend/src/Designer/Services/Interfaces/IAltinnGitRepositoryFactory.cs b/backend/src/Designer/Services/Interfaces/IAltinnGitRepositoryFactory.cs index d1590ffd096..c99be324d5d 100644 --- a/backend/src/Designer/Services/Interfaces/IAltinnGitRepositoryFactory.cs +++ b/backend/src/Designer/Services/Interfaces/IAltinnGitRepositoryFactory.cs @@ -9,7 +9,7 @@ public interface IAltinnGitRepositoryFactory { /// /// Creates an instance of - /// + /// /// The organization owning the repository identfied by it's short name as defined in Gitea. /// The name of the repository as specified in Gitea. /// The user name of the developer working on the repository. @@ -17,10 +17,18 @@ public interface IAltinnGitRepositoryFactory /// /// Creates an instance of - /// + /// /// The organization owning the repository identfied by it's short name as defined in Gitea. /// The name of the repository as specified in Gitea. /// The user name of the developer working on the repository. AltinnAppGitRepository GetAltinnAppGitRepository(string org, string repository, string developer); + + /// + /// Creates an instance of + /// + /// The organization owning the repository identfied by it's short name as defined in Gitea. + /// The name of the repository as specified in Gitea. + /// The user name of the developer working on the repository. + AltinnOrgGitRepository GetAltinnOrgGitRepository(string org, string repository, string developer); } } diff --git a/backend/src/Designer/Services/Interfaces/Organisation/IOrgTextsService.cs b/backend/src/Designer/Services/Interfaces/Organisation/IOrgTextsService.cs new file mode 100644 index 00000000000..2001b6dbdc5 --- /dev/null +++ b/backend/src/Designer/Services/Interfaces/Organisation/IOrgTextsService.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Altinn.Studio.Designer.Models; + +namespace Altinn.Studio.Designer.Services.Interfaces.Organisation; + +public interface IOrgTextsService +{ + /// + /// Gets texts file in old format in app repository according to + /// specified languageCode. + /// + /// Organisation + /// Repository + /// Username of developer + /// LanguageCode + /// The text file + public Task GetText(string org, string repo, string developer, string languageCode); + + /// + /// Saves text resource in old format. + /// + /// Organisation + /// Repository + /// Username of developer + /// The text resource to be saved + /// LanguageCode + /// + public Task SaveText(string org, string repo, string developer, TextResource textResource, string languageCode); + + /// + /// Updates values for + /// + /// Organisation + /// Repository + /// Username of developer + /// KeysTexts + /// LanguageCode + /// + public Task UpdateTextsForKeys(string org, string repo, string developer, Dictionary keysTexts, string languageCode); +} From 1bf3909b792803a5f0aaa7245d1854bb3d874641 Mon Sep 17 00:00:00 2001 From: Konrad-Simso Date: Wed, 5 Feb 2025 16:02:25 +0100 Subject: [PATCH 2/7] Add GetAltinnOrgRepository to Factory --- .../Designer/Factories/AltinnGitRepositoryFactory.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/backend/src/Designer/Factories/AltinnGitRepositoryFactory.cs b/backend/src/Designer/Factories/AltinnGitRepositoryFactory.cs index b28a46e0ab2..b08495dd8f5 100644 --- a/backend/src/Designer/Factories/AltinnGitRepositoryFactory.cs +++ b/backend/src/Designer/Factories/AltinnGitRepositoryFactory.cs @@ -62,5 +62,15 @@ public string GetRepositoryPath(string org, string repository, string developer) string[] paths = { _repositoriesRootDirectory, developer.AsFileName(), org.AsFileName(), repository.AsFileName() }; return Path.Combine(paths); } + + /// + /// Creates an instance of + /// + /// + public AltinnOrgGitRepository GetAltinnOrgGitRepository(string org, string repository, string developer) + { + var repositoryDirectory = GetRepositoryPath(org, repository, developer); + return new AltinnOrgGitRepository(org, repository, developer, _repositoriesRootDirectory, repositoryDirectory); + } } } From 53d7662bf5738898791d53069793d8698576d057 Mon Sep 17 00:00:00 2001 From: Konrad-Simso Date: Thu, 6 Feb 2025 10:01:51 +0100 Subject: [PATCH 3/7] Updating exception handling and remove app specific update logic --- .../src/Designer/Controllers/Organisation/TextController.cs | 2 +- .../Services/Implementation/Organisation/OrgTextsService.cs | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/backend/src/Designer/Controllers/Organisation/TextController.cs b/backend/src/Designer/Controllers/Organisation/TextController.cs index 166b693fdbd..7c7dc2e52e7 100644 --- a/backend/src/Designer/Controllers/Organisation/TextController.cs +++ b/backend/src/Designer/Controllers/Organisation/TextController.cs @@ -104,7 +104,7 @@ public async Task> UpdateResource(string org, [FromBo { return BadRequest(exception.Message); } - catch (Exception) + catch (NotFoundException) { return BadRequest($"The text resource, resource.{languageCode}.json, could not be updated."); } diff --git a/backend/src/Designer/Services/Implementation/Organisation/OrgTextsService.cs b/backend/src/Designer/Services/Implementation/Organisation/OrgTextsService.cs index e7864095abd..7ef091b1010 100644 --- a/backend/src/Designer/Services/Implementation/Organisation/OrgTextsService.cs +++ b/backend/src/Designer/Services/Implementation/Organisation/OrgTextsService.cs @@ -68,14 +68,8 @@ public async Task UpdateTextsForKeys(string org, string repo, string developer, TextResource textResourceObject = await altinnOrgGitRepository.GetText(languageCode); // handle if file not already exist - foreach (KeyValuePair kvp in keysTexts) { - if ((kvp.Key == "appName" || kvp.Key == "serviceName") && string.IsNullOrEmpty(kvp.Value)) - { - throw new ArgumentException("The application name must be a value."); - } - TextResourceElement textResourceContainsKey = textResourceObject.Resources.Find(textResourceElement => textResourceElement.Id == kvp.Key); if (textResourceContainsKey is null) { From 2670720e822ecc2ef9a324eded7f65261976ea4c Mon Sep 17 00:00:00 2001 From: Konrad-Simso Date: Thu, 6 Feb 2025 12:03:51 +0100 Subject: [PATCH 4/7] Fix Nitpick comments by coderabbit --- .../Infrastructure/GitRepository/AltinnAppGitRepository.cs | 2 +- .../Services/Interfaces/IAltinnGitRepositoryFactory.cs | 6 +++--- .../Services/Interfaces/Organisation/IOrgTextsService.cs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/src/Designer/Infrastructure/GitRepository/AltinnAppGitRepository.cs b/backend/src/Designer/Infrastructure/GitRepository/AltinnAppGitRepository.cs index 7cdb3cae19a..332503873a5 100644 --- a/backend/src/Designer/Infrastructure/GitRepository/AltinnAppGitRepository.cs +++ b/backend/src/Designer/Infrastructure/GitRepository/AltinnAppGitRepository.cs @@ -75,7 +75,7 @@ public class AltinnAppGitRepository : AltinnGitRepository }; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// Organization owning the repository identified by it's short name. /// Repository name to search for schema files. diff --git a/backend/src/Designer/Services/Interfaces/IAltinnGitRepositoryFactory.cs b/backend/src/Designer/Services/Interfaces/IAltinnGitRepositoryFactory.cs index c99be324d5d..ade5221180b 100644 --- a/backend/src/Designer/Services/Interfaces/IAltinnGitRepositoryFactory.cs +++ b/backend/src/Designer/Services/Interfaces/IAltinnGitRepositoryFactory.cs @@ -10,7 +10,7 @@ public interface IAltinnGitRepositoryFactory /// /// Creates an instance of /// - /// The organization owning the repository identfied by it's short name as defined in Gitea. + /// The organization owning the repository identified by it's short name as defined in Gitea. /// The name of the repository as specified in Gitea. /// The user name of the developer working on the repository. AltinnGitRepository GetAltinnGitRepository(string org, string repository, string developer); @@ -18,7 +18,7 @@ public interface IAltinnGitRepositoryFactory /// /// Creates an instance of /// - /// The organization owning the repository identfied by it's short name as defined in Gitea. + /// The organization owning the repository identified by it's short name as defined in Gitea. /// The name of the repository as specified in Gitea. /// The user name of the developer working on the repository. AltinnAppGitRepository GetAltinnAppGitRepository(string org, string repository, string developer); @@ -26,7 +26,7 @@ public interface IAltinnGitRepositoryFactory /// /// Creates an instance of /// - /// The organization owning the repository identfied by it's short name as defined in Gitea. + /// The organization owning the repository identified by it's short name as defined in Gitea. /// The name of the repository as specified in Gitea. /// The user name of the developer working on the repository. AltinnOrgGitRepository GetAltinnOrgGitRepository(string org, string repository, string developer); diff --git a/backend/src/Designer/Services/Interfaces/Organisation/IOrgTextsService.cs b/backend/src/Designer/Services/Interfaces/Organisation/IOrgTextsService.cs index 2001b6dbdc5..eccfb9e3bed 100644 --- a/backend/src/Designer/Services/Interfaces/Organisation/IOrgTextsService.cs +++ b/backend/src/Designer/Services/Interfaces/Organisation/IOrgTextsService.cs @@ -29,7 +29,7 @@ public interface IOrgTextsService public Task SaveText(string org, string repo, string developer, TextResource textResource, string languageCode); /// - /// Updates values for + /// Updates values for specified keys in the text resouce. /// /// Organisation /// Repository From 16c7d5f3d86c06506a7b6429cfb66e16e88286ee Mon Sep 17 00:00:00 2001 From: Konrad-Simso Date: Thu, 6 Feb 2025 12:24:37 +0100 Subject: [PATCH 5/7] Add parameter `createDirectory` as true to let `SaveText` create the parent directory if it does not already exist --- .../Infrastructure/GitRepository/AltinnOrgGitRepository.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/Designer/Infrastructure/GitRepository/AltinnOrgGitRepository.cs b/backend/src/Designer/Infrastructure/GitRepository/AltinnOrgGitRepository.cs index b121dd42409..fc8905b35c8 100644 --- a/backend/src/Designer/Infrastructure/GitRepository/AltinnOrgGitRepository.cs +++ b/backend/src/Designer/Infrastructure/GitRepository/AltinnOrgGitRepository.cs @@ -66,7 +66,7 @@ public async Task SaveText(string languageCode, TextResource jsonTexts) string fileName = $"resource.{languageCode}.json"; string textsFileRelativeFilePath = GetPathToJsonTextsFile(fileName); string texts = JsonSerializer.Serialize(jsonTexts, JsonOptions); - await WriteTextByRelativePathAsync(textsFileRelativeFilePath, texts); + await WriteTextByRelativePathAsync(textsFileRelativeFilePath, texts, true); } private static string GetPathToJsonTextsFile(string fileName) From ae5ea28ba3a930e3057476b91352f1bd2c049aaa Mon Sep 17 00:00:00 2001 From: Konrad-Simso Date: Tue, 11 Feb 2025 12:32:12 +0100 Subject: [PATCH 6/7] Fix PR comments --- .../{TextController.cs => OrgTextController.cs} | 6 +++--- .../Infrastructure/GitRepository/AltinnOrgGitRepository.cs | 4 ++-- .../Services/Interfaces/IAltinnGitRepositoryFactory.cs | 6 +++--- .../Services/Interfaces/Organisation/IOrgTextsService.cs | 5 ++--- 4 files changed, 10 insertions(+), 11 deletions(-) rename backend/src/Designer/Controllers/Organisation/{TextController.cs => OrgTextController.cs} (95%) diff --git a/backend/src/Designer/Controllers/Organisation/TextController.cs b/backend/src/Designer/Controllers/Organisation/OrgTextController.cs similarity index 95% rename from backend/src/Designer/Controllers/Organisation/TextController.cs rename to backend/src/Designer/Controllers/Organisation/OrgTextController.cs index 7c7dc2e52e7..5216e21d318 100644 --- a/backend/src/Designer/Controllers/Organisation/TextController.cs +++ b/backend/src/Designer/Controllers/Organisation/OrgTextController.cs @@ -16,16 +16,16 @@ namespace Altinn.Studio.Designer.Controllers.Organisation; [ApiController] [Authorize] [Route("designer/api/{org}/text")] -public class TextController : ControllerBase +public class OrgTextController : ControllerBase { private readonly IOrgTextsService _orgTextsService; private const string Repo = "content"; /// - /// Initializes a new instance of the /> class. + /// Initializes a new instance of the class. /// /// The texts service. - public TextController(IOrgTextsService orgTextsService) + public OrgTextController(IOrgTextsService orgTextsService) { _orgTextsService = orgTextsService; } diff --git a/backend/src/Designer/Infrastructure/GitRepository/AltinnOrgGitRepository.cs b/backend/src/Designer/Infrastructure/GitRepository/AltinnOrgGitRepository.cs index fc8905b35c8..e79cc3dcb05 100644 --- a/backend/src/Designer/Infrastructure/GitRepository/AltinnOrgGitRepository.cs +++ b/backend/src/Designer/Infrastructure/GitRepository/AltinnOrgGitRepository.cs @@ -24,7 +24,7 @@ public class AltinnOrgGitRepository : AltinnGitRepository }; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// Organization owning the repository identified by it's short name. /// Repository name to search for schema files. @@ -36,7 +36,7 @@ public AltinnOrgGitRepository(string org, string repository, string developer, s } /// - /// Returns a specific text resource written in the old text format + /// Returns a specific text resource /// based on language code from the application. /// /// diff --git a/backend/src/Designer/Services/Interfaces/IAltinnGitRepositoryFactory.cs b/backend/src/Designer/Services/Interfaces/IAltinnGitRepositoryFactory.cs index ade5221180b..ce1e385e3dd 100644 --- a/backend/src/Designer/Services/Interfaces/IAltinnGitRepositoryFactory.cs +++ b/backend/src/Designer/Services/Interfaces/IAltinnGitRepositoryFactory.cs @@ -10,7 +10,7 @@ public interface IAltinnGitRepositoryFactory /// /// Creates an instance of /// - /// The organization owning the repository identified by it's short name as defined in Gitea. + /// The organization owning the repository identified by its short name as defined in Gitea. /// The name of the repository as specified in Gitea. /// The user name of the developer working on the repository. AltinnGitRepository GetAltinnGitRepository(string org, string repository, string developer); @@ -18,7 +18,7 @@ public interface IAltinnGitRepositoryFactory /// /// Creates an instance of /// - /// The organization owning the repository identified by it's short name as defined in Gitea. + /// The organization owning the repository identified by its short name as defined in Gitea. /// The name of the repository as specified in Gitea. /// The user name of the developer working on the repository. AltinnAppGitRepository GetAltinnAppGitRepository(string org, string repository, string developer); @@ -26,7 +26,7 @@ public interface IAltinnGitRepositoryFactory /// /// Creates an instance of /// - /// The organization owning the repository identified by it's short name as defined in Gitea. + /// The organization owning the repository identified by its short name as defined in Gitea. /// The name of the repository as specified in Gitea. /// The user name of the developer working on the repository. AltinnOrgGitRepository GetAltinnOrgGitRepository(string org, string repository, string developer); diff --git a/backend/src/Designer/Services/Interfaces/Organisation/IOrgTextsService.cs b/backend/src/Designer/Services/Interfaces/Organisation/IOrgTextsService.cs index eccfb9e3bed..88617d5e68d 100644 --- a/backend/src/Designer/Services/Interfaces/Organisation/IOrgTextsService.cs +++ b/backend/src/Designer/Services/Interfaces/Organisation/IOrgTextsService.cs @@ -7,8 +7,7 @@ namespace Altinn.Studio.Designer.Services.Interfaces.Organisation; public interface IOrgTextsService { /// - /// Gets texts file in old format in app repository according to - /// specified languageCode. + /// Gets texts file in organisation repository according to specified language Code. /// /// Organisation /// Repository @@ -18,7 +17,7 @@ public interface IOrgTextsService public Task GetText(string org, string repo, string developer, string languageCode); /// - /// Saves text resource in old format. + /// Saves text resource. /// /// Organisation /// Repository From 562eb50f86cb70ee67f23cd8d13dfaefde9d97bf Mon Sep 17 00:00:00 2001 From: Konrad-Simso Date: Tue, 11 Feb 2025 13:48:09 +0100 Subject: [PATCH 7/7] Remove more mentions of old format and extract logic in service updating application metadata. --- .../Controllers/Organisation/OrgTextController.cs | 3 +-- .../Implementation/Organisation/OrgTextsService.cs | 10 +++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/backend/src/Designer/Controllers/Organisation/OrgTextController.cs b/backend/src/Designer/Controllers/Organisation/OrgTextController.cs index 5216e21d318..92a3f60051e 100644 --- a/backend/src/Designer/Controllers/Organisation/OrgTextController.cs +++ b/backend/src/Designer/Controllers/Organisation/OrgTextController.cs @@ -80,13 +80,12 @@ public async Task> CreateResource([FromBody] TextReso /// /// Method to update multiple texts for given keys and a given - /// language in the text resource files in the old format. + /// language in the text resource files. /// Non-existing keys will be added. /// /// Unique identifier of the organisation responsible for the app. /// List of Key/Value pairs that should be updated or added if not present. /// The languageCode for the text resource file that is being edited. - /// Temporary method that should live until old text format is replaced by the new. /// The updated resource file [HttpPut] [Route("language/{languageCode}")] diff --git a/backend/src/Designer/Services/Implementation/Organisation/OrgTextsService.cs b/backend/src/Designer/Services/Implementation/Organisation/OrgTextsService.cs index 7ef091b1010..be9a0edcb65 100644 --- a/backend/src/Designer/Services/Implementation/Organisation/OrgTextsService.cs +++ b/backend/src/Designer/Services/Implementation/Organisation/OrgTextsService.cs @@ -46,7 +46,13 @@ public async Task SaveText(string org, string repo, string developer, TextResour throw new ArgumentException($"Text keys must be unique. Please review keys: {string.Join(", ", duplicateKeys)}"); } - // updating application metadata with appTitle. + await UpdateAppTitleInApplicationMetadata(textResource, org, repo); + + await altinnOrgGitRepository.SaveText(languageCode, textResource); + } + + private async Task UpdateAppTitleInApplicationMetadata(TextResource textResource, string org, string repo) + { TextResourceElement appTitleResourceElement = textResource.Resources.FirstOrDefault(tre => tre.Id == "appName" || tre.Id == "ServiceName"); if (appTitleResourceElement != null && !string.IsNullOrEmpty(appTitleResourceElement.Value)) @@ -57,8 +63,6 @@ public async Task SaveText(string org, string repo, string developer, TextResour { throw new ArgumentException("The application name must be a value."); } - - await altinnOrgGitRepository.SaveText(languageCode, textResource); } ///