Skip to content

Commit

Permalink
Fetch model metadata based on selected layoutset (#12411)
Browse files Browse the repository at this point in the history
* Use selectedLayoutSet in payload when fetching model metadata to get corresponding metadata for corresponding task in layoutsets-file

* Fix tests
  • Loading branch information
standeren authored Mar 6, 2024
1 parent 6361594 commit d0e8cfe
Show file tree
Hide file tree
Showing 36 changed files with 478 additions and 154 deletions.
26 changes: 24 additions & 2 deletions backend/src/DataModeling/Metamodel/ElementMetadata.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

Expand All @@ -23,129 +24,150 @@ public ElementMetadata()
/// Gets or sets the ID of the element
/// </summary>
[JsonProperty(PropertyName = "id")]
[JsonPropertyName("id")]
public string ID { get; set; }

/// <summary>
/// Gets or sets the ID of the parent element. If a
/// </summary>
[JsonProperty(PropertyName = "parentElement")]
[JsonPropertyName("parentElement")]
public string ParentElement { get; set; }

/// <summary>
/// Gets or sets the type of this element
/// </summary>
[JsonProperty(PropertyName = "typeName")]
[JsonPropertyName("typeName")]
public string TypeName { get; set; }

/// <summary>
/// Gets or sets the element name. The Name should not contain '-'
/// </summary>
[JsonProperty(PropertyName = "name")]
[JsonPropertyName("name")]
public string Name { get; set; }

/// <summary>
/// Gets or sets the data binding name for the element. If an DataBindingName is null it cannot be used for a data-field.
/// It is used by the frontend to filter elements that can be used in single-field ux-components.
/// </summary>
[JsonProperty(PropertyName = "dataBindingName")]
[JsonPropertyName("dataBindingName")]
public string DataBindingName { get; set; }

/// <summary>
/// Gets or sets the element xpath
/// </summary>
[JsonProperty(PropertyName = "xPath")]
[JsonPropertyName("xPath")]
public string XPath { get; set; }

/// <summary>
/// Gets or sets the restrictions for this element (<see cref="Restriction"/>)
/// </summary>
[JsonProperty(PropertyName = "restrictions")]
[JsonPropertyName("restrictions")]
public Dictionary<string, Restriction> Restrictions { get; set; }

/// <summary>
/// Gets or sets the <see cref="ElementType"/>
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
[Newtonsoft.Json.JsonConverter(typeof(StringEnumConverter))]
[JsonProperty(PropertyName = "type")]
[JsonPropertyName("type")]
public ElementType Type { get; set; }

/// <summary>
/// Gets or sets the <see cref="BaseValueType">xsd value type</see> of this element
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
[Newtonsoft.Json.JsonConverter(typeof(StringEnumConverter))]
[JsonProperty(PropertyName = "xsdValueType")]
[JsonPropertyName("xsdValueType")]
public BaseValueType? XsdValueType { get; set; }

/// <summary>
/// Gets or sets any text associated with this element
/// </summary>
[JsonProperty(PropertyName = "texts")]
[JsonPropertyName("texts")]
public Dictionary<string, string> Texts { get; set; }

/// <summary>
/// Gets or sets custom properties for this element
/// </summary>
[JsonProperty(PropertyName = "customProperties")]
[JsonPropertyName("customProperties")]
public Dictionary<string, string> CustomProperties { get; set; }

/// <summary>
/// Gets or sets the maximum number of times this element can be repeated
/// </summary>
[JsonProperty(PropertyName = "maxOccurs")]
[JsonPropertyName("maxOccurs")]
public int MaxOccurs { get; set; }

/// <summary>
/// Gets or sets the minimum number of times this element can be repeated
/// </summary>
[JsonProperty(PropertyName = "minOccurs")]
[JsonPropertyName("minOccurs")]
public int MinOccurs { get; set; }

/// <summary>
/// Gets or sets the XName for this element. The XML name.
/// </summary>
[JsonProperty(PropertyName = "xName")]
[JsonPropertyName("xName")]
public string XName { get; set; }

/// <summary>
/// Gets or sets a value indicating whether this element is the content of the parent tag. Special case of SimpleContent.
/// </summary>
[JsonProperty(PropertyName = "isTagContent")]
[JsonPropertyName("isTagContent")]
public bool IsTagContent { get; set; }

/// <summary>
/// Gets or sets the fixed value of an element
/// </summary>
[JsonProperty(PropertyName = "fixedValue")]
[JsonPropertyName("fixedValue")]
public string FixedValue { get; set; }

/// <summary>
/// Gets or sets a value indicating whether this element is read only
/// </summary>
[JsonProperty(PropertyName = "isReadOnly")]
[JsonPropertyName("isReadOnly")]
public bool IsReadOnly { get; set; }

/// <summary>
/// The reference to the Xml Schema declaration
/// </summary>
[JsonProperty(PropertyName = "xmlSchemaXPath")]
[JsonPropertyName("xmlSchemaXPath")]
public string XmlSchemaXPath { get; set; }

/// <summary>
/// Used to point to the reference to the Json Schema declaration
/// </summary>
[JsonProperty(PropertyName = "jsonSchemaPointer")]
[JsonPropertyName("jsonSchemaPointer")]
public string JsonSchemaPointer { get; set; }

/// <summary>
/// Used to display the property in a view. Contains name, cardinality and type. Example: melding.person.name: [0..1] string
/// </summary>
[JsonProperty(PropertyName = "displayString")]
[JsonPropertyName("displayString")]
public string DisplayString { get; set; }

/// <summary>
/// Used for xsd context. Indicates if nillable is set in xsd schema.
/// </summary>
[JsonProperty(PropertyName = "nillable")]
[JsonPropertyName("nillable")]
public bool? Nillable { get; set; }
}
}
2 changes: 2 additions & 0 deletions backend/src/DataModeling/Metamodel/ModelMetadata.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using Newtonsoft.Json;

namespace Altinn.Studio.DataModeling.Metamodel
Expand Down Expand Up @@ -41,6 +42,7 @@ public class ModelMetadata
/// Gets or sets all elements for the service (<see cref="ElementMetadata"/>)
/// </summary>
[JsonProperty(PropertyName = "elements")]
[JsonPropertyName("elements")]
public Dictionary<string, ElementMetadata> Elements { get; set; } = new Dictionary<string, ElementMetadata>();
}
}
18 changes: 18 additions & 0 deletions backend/src/Designer/Controllers/AppDevelopmentController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,24 @@ public async Task<IActionResult> GetLayoutSettings(string org, string app, [From
}
}

/// <summary>
/// Return JSON presentation of the model
/// </summary>
/// <param name="org">Unique identifier of the organisation responsible for the app.</param>
/// <param name="app">Application identifier which is unique within an organisation.</param>
/// <param name="layoutSetName">Name of current layoutSet in ux-editor that edited layout belongs to</param>
/// <param name="cancellationToken">An <see cref="CancellationToken"/> that observes if operation is cancelled.</param>
/// <returns>The model as JSON</returns>
[HttpGet]
[UseSystemTextJson]
[Route("model-metadata")]
public async Task<IActionResult> GetModelMetadata(string org, string app, [FromQuery] string layoutSetName, CancellationToken cancellationToken)
{
string developer = AuthenticationHelper.GetDeveloperUserName(HttpContext);
JsonNode modelMetadata = await _appDevelopmentService.GetModelMetadata(AltinnRepoEditingContext.FromOrgRepoDeveloper(org, app, developer), layoutSetName, cancellationToken);
return Ok(modelMetadata);
}

/// <summary>
/// Get all layoutsets in the layout-set.json file
/// </summary>
Expand Down
62 changes: 0 additions & 62 deletions backend/src/Designer/Controllers/ModelController.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using Altinn.Studio.DataModeling.Metamodel;
using Altinn.Studio.Designer.Configuration;
using Altinn.Studio.Designer.Helpers;
using Altinn.Studio.Designer.Models;
Expand Down Expand Up @@ -134,17 +135,18 @@ public async Task<ServiceConfiguration> GetAppMetadataConfig()
}

/// <summary>
/// Get the Json Schema file representing the application model to disk.
/// Gets the model metadata content based on model name. If no model metadata found for the model name an empty model metadata is returned.
/// </summary>
/// <param name="modelName">The name of the model without extensions. This will be used as filename.</param>
/// <returns>A string containing content of the json schema.</returns>
[Obsolete("Generic method GetJsonSchema is deprecated. Use a dedicated one instead.")]
public async Task<string> GetJsonSchema(string modelName)
/// <param name="modelName">The model metadata as string</param>
public async Task<string> GetModelMetadata(string modelName)
{
string relativeFilePath = GetRelativeModelFilePath(modelName);
string jsonSchemaContent = await ReadTextByRelativePathAsync(relativeFilePath);

return jsonSchemaContent;
string modelMetadataFileName = GetPathToModelMetadata(modelName);
if (!FileExistsByRelativePath(modelMetadataFileName))
{
ModelMetadata emptyModel = JsonSerializer.Deserialize<ModelMetadata>("{}");
return JsonSerializer.Serialize(emptyModel);
}
return await ReadTextByRelativePathAsync(modelMetadataFileName);
}

/// <summary>
Expand All @@ -155,7 +157,7 @@ public async Task<string> GetJsonSchema(string modelName)
/// <param name="modelName">The name of the model. </param>
public async Task SaveModelMetadata(string modelMetadata, string modelName)
{
string modelMetadataRelativeFilePath = Path.Combine(MODEL_FOLDER_PATH, $"{modelName}.metadata.json");
string modelMetadataRelativeFilePath = GetPathToModelMetadata(modelName);
await WriteTextByRelativePathAsync(modelMetadataRelativeFilePath, modelMetadata, true);
}

Expand All @@ -166,8 +168,8 @@ public async Task SaveModelMetadata(string modelMetadata, string modelName)
/// <param name="modelName">The name of the model, will be used as filename.</param>
public async Task SaveCSharpClasses(string csharpClasses, string modelName)
{
string modelMetadataRelativeFilePath = Path.Combine(MODEL_FOLDER_PATH, $"{modelName}.cs");
await WriteTextByRelativePathAsync(modelMetadataRelativeFilePath, csharpClasses, true);
string csharpModelRelativeFilePath = Path.Combine(MODEL_FOLDER_PATH, $"{modelName}.cs");
await WriteTextByRelativePathAsync(csharpModelRelativeFilePath, csharpClasses, true);
}

/// <summary>
Expand All @@ -178,7 +180,7 @@ public async Task SaveCSharpClasses(string csharpClasses, string modelName)
/// <returns>A string containing the relative path to the file saved.</returns>
public override async Task<string> SaveJsonSchema(string jsonSchema, string modelName)
{
string relativeFilePath = GetRelativeModelFilePath(modelName);
string relativeFilePath = GetPathToModelJsonSchema(modelName);
await WriteTextByRelativePathAsync(relativeFilePath, jsonSchema, true);

return relativeFilePath;
Expand Down Expand Up @@ -798,15 +800,20 @@ public Stream GetImage(string imageFilePath, CancellationToken cancellationToken
}

/// <summary>
/// Gets the relative path to a model.
/// Gets the relative path to a json schema model.
/// </summary>
/// <param name="modelName">The name of the model without extensions.</param>
/// <returns>A string with the relative path to the model file, including file extension. </returns>
private string GetRelativeModelFilePath(string modelName)
private string GetPathToModelJsonSchema(string modelName)
{
return Path.Combine(MODEL_FOLDER_PATH, $"{modelName}.schema.json");
}

private string GetPathToModelMetadata(string modelName)
{
return Path.Combine(MODEL_FOLDER_PATH, $"{modelName}.metadata.json");
}

private static string GetPathToTexts()
{
return Path.Combine(CONFIG_FOLDER_PATH, LANGUAGE_RESOURCE_FOLDER_NAME);
Expand Down
Loading

0 comments on commit d0e8cfe

Please sign in to comment.