Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: backend endpoints for instance creation and dataelement operations #14154

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
a3bcbc5
Backend endpoints for instance creation and dataelement operations
Jondyr Nov 25, 2024
dd80e1f
Use ApplicationMetadataService instead of gitea repo directly from co…
Jondyr Nov 27, 2024
cb02b02
Delete no longer needed backToEditingHref
Jondyr Nov 27, 2024
f507520
Add errormessage to preview when instance creation fails
Jondyr Nov 27, 2024
07c0acb
Move legacy v3 support to own controllers
Jondyr Nov 27, 2024
042dadf
Revert "Delete no longer needed backToEditingHref"
Jondyr Nov 27, 2024
fb445f7
Remove layout from backtoeditinghref
Jondyr Nov 27, 2024
117e80e
Test fixes for preview mutation
Jondyr Nov 28, 2024
4c83dc3
Remove unused imports
Jondyr Nov 28, 2024
24e387c
Make v3 tests use v3 url directly instead of waiting for redirect
Jondyr Dec 2, 2024
a5fba66
Redo tests to test v3 and v4 more consistently
Jondyr Dec 2, 2024
90fdd2f
Merge branch 'main' into 11-25-backend_endpoints_for_instance_creatio…
Jondyr Dec 5, 2024
c7cdfe8
Fix preview test
Jondyr Dec 5, 2024
7e08b0b
update navigation link
Jondyr Dec 5, 2024
30f755d
Fix createPreviewInstance definition
Jondyr Dec 5, 2024
6d4124c
Use isPending instead of checking for undefined object
Jondyr Dec 5, 2024
27f4e24
remove comment
Jondyr Dec 5, 2024
a82b640
Try defining default headers for preview instance mutations
Jondyr Dec 9, 2024
70f737b
test
Jondyr Dec 9, 2024
fc526ed
remove even more?
Jondyr Dec 9, 2024
07a3d4c
Use servicesContext for mutation path
Jondyr Dec 9, 2024
155a940
Add waitforelementtoberemoved for preview tests
Jondyr Dec 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 76 additions & 67 deletions backend/src/Designer/Controllers/Preview/DataController.cs
Original file line number Diff line number Diff line change
@@ -1,50 +1,101 @@
using System;
using System.Collections.Generic;
using System.Text.Json.Nodes;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using Altinn.Platform.Storage.Interface.Models;
using Altinn.Studio.Designer.Filters;
using Altinn.Studio.Designer.Helpers;
using Altinn.Studio.Designer.Models;
using Altinn.Studio.Designer.Infrastructure.GitRepository;
using Altinn.Studio.Designer.Models.Preview;
using Altinn.Studio.Designer.Services.Implementation;
using Altinn.Studio.Designer.Services.Interfaces;
using Altinn.Studio.Designer.Services.Interfaces.Preview;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Routing;

namespace Altinn.Studio.Designer.Controllers.Preview
{
[Authorize]
[AutoValidateAntiforgeryToken]
[Route("{org:regex(^(?!designer))}/{app:regex(^(?!datamodels$)[[a-z]][[a-z0-9-]]{{1,28}}[[a-z0-9]]$)}/instances/{partyId}/{instanceGuid}/data")]
public class DataController(IHttpContextAccessor httpContextAccessor,
IPreviewService previewService,
ISchemaModelService schemaModelService,
IDataService dataService
public class DataController(
IInstanceService instanceService,
IDataService dataService,
IAltinnGitRepositoryFactory altinnGitRepositoryFactory

) : Controller
{
// <summary>
// Redirect requests from older versions of Studio to old controller
// </summary>
public override void OnActionExecuting(ActionExecutingContext context)
{
string org = context.RouteData.Values["org"] as string;
string app = context.RouteData.Values["app"] as string;
string developer = AuthenticationHelper.GetDeveloperUserName(HttpContext);
AltinnAppGitRepository altinnAppGitRepository = altinnGitRepositoryFactory.GetAltinnAppGitRepository(org, app, developer);
if (!altinnAppGitRepository.AppUsesLayoutSets())
{
RouteValueDictionary routeData = context.RouteData.Values;
foreach (var queryParam in context.HttpContext.Request.Query)
{
routeData[queryParam.Key] = queryParam.Value.ToString();
}
context.Result = base.RedirectToActionPreserveMethod(controllerName: "OldData", routeValues: routeData);
}
base.OnActionExecuting(context);
}

[HttpGet("{dataGuid}")]
public ActionResult Get([FromRoute] Guid dataGuid)
[UseSystemTextJson]
public ActionResult Get(
[FromRoute] Guid dataGuid
)
{
JsonNode dataItem = dataService.GetDataElement(dataGuid);
return Ok(dataItem);
}

[HttpPost]
public ActionResult Post(
[UseSystemTextJson]
public ActionResult<DataElement> Post(
[FromRoute] int partyId,
[FromRoute] Guid instanceGuid,
[FromQuery] string dataType
)
{
DataElement dataElement = dataService.CreateDataElement(partyId, instanceGuid, dataType);
instanceService.AddDataElement(instanceGuid, dataElement);
return Created("link-to-app-placeholder", dataElement);
}

[HttpPatch]
[UseSystemTextJson]
public ActionResult<DataPatchResponseMultiple> PatchMultiple(
[FromRoute] string org,
[FromRoute] string app,
[FromRoute] int partyId,
[FromRoute] Guid instanceGuid,
[FromBody] DataPatchRequestMultiple dataPatch
)
{
Instance instance = instanceService.GetInstance(instanceGuid);

List<DataModelPairResponse> newDataModels = [];
dataPatch.Patches.ForEach(patch =>
{
JsonNode dataItem = dataService.PatchDataElement(patch.DataElementId, patch.Patch);
newDataModels.Add(new DataModelPairResponse(patch.DataElementId, dataItem));
});

return Ok(new DataPatchResponseMultiple()
{
ValidationIssues = [],
NewDataModels = newDataModels,
Instance = instance,
});
}

[HttpPatch("{dataGuid}")]
[UseSystemTextJson]
public ActionResult<DataPatchResponse> Patch(
Expand All @@ -60,72 +111,30 @@ [FromBody] DataPatchRequest dataPatch
});
}

[HttpDelete("{dataTypeId}")]
public ActionResult DeleteAttachment([FromRoute] Guid dataGuid)
[HttpDelete("{dataGuid}")]
public ActionResult<DataPostResponse> Delete(
[FromRoute] Guid instanceGuid,
[FromRoute] Guid dataGuid
)
{
instanceService.RemoveDataElement(instanceGuid, dataGuid);
return Ok();
}

[HttpGet("{dataGuid}/validate")]
public ActionResult ValidateInstanceForData([FromRoute] Guid dataGuid)
public ActionResult ValidateInstanceForData(
[FromRoute] Guid dataGuid
)
{
return Ok(new List<string>());
}

[HttpPost("{dataTypeId}/tags")]
public ActionResult UpdateTagsForAttachment([FromBody] string tag)
{
return Created("link-to-app-placeholder", tag);
}

[HttpGet(PreviewService.MockDataTaskId)]
public async Task<ActionResult> GetDefaultFormData(
[FromRoute] string org,
[FromRoute] string app,
[FromRoute] int partyId,
CancellationToken cancellationToken
[HttpPost("{dataGuid}/tags")]
public ActionResult UpdateTagsForAttachment(
[FromBody] string tag
)
{
string developer = AuthenticationHelper.GetDeveloperUserName(httpContextAccessor.HttpContext);
string refererHeader = Request.Headers.Referer;
string layoutSetName = GetSelectedLayoutSetInEditorFromRefererHeader(refererHeader);
DataType dataType = await previewService.GetDataTypeForLayoutSetName(org, app, developer, layoutSetName, cancellationToken);
// For apps that does not have a datamodel
if (dataType == null)
{
Instance mockInstance = await previewService.GetMockInstance(org, app, developer, partyId, layoutSetName, cancellationToken);
return Ok(mockInstance.Id);
}
string modelPath = $"/App/models/{dataType.Id}.schema.json";
string decodedPath = Uri.UnescapeDataString(modelPath);
string formData = await schemaModelService.GetSchema(AltinnRepoEditingContext.FromOrgRepoDeveloper(org, app, developer), decodedPath, cancellationToken);
return Ok(formData);
}

[HttpPut(PreviewService.MockDataTaskId)]
public async Task<ActionResult> UpdateFormData(
[FromRoute] string org,
[FromRoute] string app,
[FromRoute] int partyId,
CancellationToken cancellationToken
)
{
return await GetDefaultFormData(org, app, partyId, cancellationToken);
}

[HttpPatch(PreviewService.MockDataTaskId)]
public ActionResult PatchFormData()
{
return Ok();
}

private static string GetSelectedLayoutSetInEditorFromRefererHeader(string refererHeader)
{
Uri refererUri = new(refererHeader);
string layoutSetName = HttpUtility.ParseQueryString(refererUri.Query)["selectedLayoutSet"];

return string.IsNullOrEmpty(layoutSetName) ? null : layoutSetName;
return Created("link-to-app-placeholder", tag);
}
}
}

Loading
Loading