Skip to content

Commit

Permalink
feat(SupportV4): Support using v4 app template in Studio (#12449)
Browse files Browse the repository at this point in the history
* Support v4 template
  • Loading branch information
framitdavid authored Mar 6, 2024
1 parent 54bc31f commit 974d961
Show file tree
Hide file tree
Showing 10 changed files with 49 additions and 63 deletions.
4 changes: 2 additions & 2 deletions backend/src/Designer/Controllers/PreviewController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public class PreviewController : Controller

// This value will be overridden to act as the task number for apps that use layout sets
private const int PartyId = 51001;
private const string MINIMUM_NUGET_VERSION = "8.0.0.102";
private const string MINIMUM_NUGET_VERSION = "8.0.0.0";
private const int MINIMUM_PREVIEW_NUGET_VERSION = 15;

/// <summary>
Expand Down Expand Up @@ -580,7 +580,7 @@ public ActionResult ValidateInstance()
[Route("instances/{partyId}/{instanceGuId}/data/test-datatask-id/validate")]
public ActionResult ValidateInstanceForDataTask()
{
return Ok();
return Ok(new List<string>());
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,24 @@ public async Task CreateApplicationMetadata(string org, string app, string appTi
{
Id = "ref-data-as-pdf",
AllowedContentTypes = new List<string>() { "application/pdf" },
},
new()
{
Id = "model",
AllowedContentTypes = new List<string>() { "application/xml" },
AppLogic = new ApplicationLogic()
{
AutoCreate = true,
ClassRef = "Altinn.App.Models.model.model",
AllowAnonymousOnStateless = false,
AutoDeleteOnProcessEnd = false
},
TaskId = "Task_1",
MaxCount = 1,
MinCount = 1,
EnablePdfCreation = true,
EnableFileScan = false,
ValidationErrorOnPendingFileScan = false
}
},
PartyTypesAllowed = new PartyTypesAllowed()
Expand Down
33 changes: 2 additions & 31 deletions backend/src/Designer/Services/Implementation/RepositorySI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.Net;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Threading.Tasks;
using System.Xml;
using Altinn.Authorization.ABAC.Utils;
Expand Down Expand Up @@ -264,8 +263,6 @@ public bool DeleteLanguage(AltinnRepoEditingContext altinnRepoEditingContext, st
await _applicationMetadataService.CreateApplicationMetadata(org, serviceConfig.RepositoryName, serviceConfig.ServiceName);
await _textsService.CreateLanguageResources(org, serviceConfig.RepositoryName, developer);
var editingContext = AltinnRepoEditingContext.FromOrgRepoDeveloper(org, serviceConfig.RepositoryName, developer);
await _appDevelopmentService.SaveFormLayout(editingContext, null, InitialLayout, GetInitialLayout());
await _appDevelopmentService.SaveLayoutSettings(editingContext, GetInitialLayoutSettings(InitialLayout), null);
await CreateRepositorySettings(org, serviceConfig.RepositoryName, developer);

CommitInfo commitInfo = new() { Org = org, Repository = serviceConfig.RepositoryName, Message = "App created" };
Expand All @@ -276,34 +273,6 @@ public bool DeleteLanguage(AltinnRepoEditingContext altinnRepoEditingContext, st
return repository;
}

private static JsonNode GetInitialLayout()
{
var layout = new JsonObject
{
["$schema"] = AltinnAppGitRepository.LayoutSchemaUrl,
["data"] = new JsonObject
{
["layout"] = new JsonArray()
}
};
return layout;
}

private static JsonNode GetInitialLayoutSettings(string initialLayout)
{

var layoutSettings = new JsonObject
{
["$schema"] = AltinnAppGitRepository.LayoutSettingsSchemaUrl,
["pages"] = new JsonObject
{
["order"] = new JsonArray { initialLayout }
}
};

return layoutSettings;
}

private async Task CreateRepositorySettings(string org, string repository, string developer)
{
var altinnGitRepository = _altinnGitRepositoryFactory.GetAltinnGitRepository(org, repository, developer);
Expand Down Expand Up @@ -409,6 +378,8 @@ private void CopyFolderToApp(string org, string app, string sourcePath, string p
// Create the app deployment folder
Directory.CreateDirectory(targetPath);

var files = Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories);

// Create all of the directories
foreach (string dirPath in Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public async Task Get_ApplicationMetadata_With_V8_Altinn_Nuget_Version_Ok()

string responseBody = await response.Content.ReadAsStringAsync();
ApplicationMetadata expectedApplicationMetadata = JsonSerializer.Deserialize<ApplicationMetadata>(expectedApplicationMetadataString, SerializerOptions);
expectedApplicationMetadata.AltinnNugetVersion = "8.0.0.102";
expectedApplicationMetadata.AltinnNugetVersion = "8.0.0.0";
string expectedJson = JsonSerializer.Serialize(expectedApplicationMetadata, SerializerOptions);
JsonUtils.DeepEquals(expectedJson, responseBody).Should().BeTrue();
}
Expand Down
7 changes: 1 addition & 6 deletions frontend/packages/shared/src/api/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ import type { RuleConfig } from 'app-shared/types/RuleConfig';

import type { WidgetSettingsResponse } from 'app-shared/types/widgetTypes';
import { buildQueryParams } from 'app-shared/utils/urlUtils';
import { componentSchemaUrl, expressionSchemaUrl, layoutSchemaUrl, newsListUrl, numberFormatSchemaUrl, orgsListUrl } from '../cdn-paths';
import { newsListUrl, orgsListUrl } from '../cdn-paths';
import type { JsonSchema } from 'app-shared/types/JsonSchema';
import type { PolicyAction, Policy, PolicySubject } from '@altinn/policy-editor';
import type { BrregPartySearchResult, BrregSubPartySearchResult, AccessList, Resource, ResourceListItem, ResourceVersionStatus, Validation, AccessListsResponse } from 'app-shared/types/ResourceAdm';
Expand All @@ -76,25 +76,20 @@ import type { FormLayoutsResponseV3 } from 'app-shared/types/api/FormLayoutsResp
export const getAppReleases = (owner: string, app: string) => get<AppReleasesResponse>(releasesPath(owner, app, 'Descending'));
export const getAppVersion = (org: string, app: string) => get<AppVersion>(appVersionPath(org, app));
export const getBranchStatus = (owner: string, app: string, branch: string) => get<BranchStatus>(branchStatusPath(owner, app, branch));
export const getComponentSchema = (component: string) => get<string[]>(componentSchemaUrl(component));
export const getComponentsCommonDefsSchema = () => get<string[]>(componentSchemaUrl('common-defs'));
export const getDatamodel = (owner: string, app: string, modelPath: string) => get<JsonSchema>(datamodelPath(owner, app, modelPath));
export const getDatamodelMetadata = (owner: string, app: string, layoutSetName: string) => get<DatamodelMetadataResponse>(datamodelMetadataPath(owner, app, layoutSetName));
export const getDatamodelsJson = (owner: string, app: string) => get<DatamodelMetadataJson[]>(datamodelsPath(owner, app));
export const getDatamodelsXsd = (owner: string, app: string) => get<DatamodelMetadataXsd[]>(datamodelsXsdPath(owner, app));
export const getDeployPermissions = (owner: string, app: string) => get<string[]>(deployPermissionsPath(owner, app));
export const getDeployments = (owner: string, app: string) => get<AppDeploymentsResponse>(deploymentsPath(owner, app, 'Descending'));
export const getEnvironments = () => get<DeployEnvironment[]>(envConfigPath());
export const getExpressionSchema = () => get<string[]>(expressionSchemaUrl());
export const getFormLayoutSettings = (owner: string, app: string, layoutSetName: string) => get<ILayoutSettings>(layoutSettingsPath(owner, app, layoutSetName));
export const getFormLayouts = (owner: string, app: string, layoutSetName: string) => get<FormLayoutsResponse>(formLayoutsPath(owner, app, layoutSetName));
export const getFormLayoutsV3 = (owner: string, app: string, layoutSetName: string) => get<FormLayoutsResponseV3>(formLayoutsPath(owner, app, layoutSetName));
export const getFrontEndSettings = (owner: string, app: string) => get<IFrontEndSettings>(frontEndSettingsPath(owner, app));
export const getInstanceIdForPreview = (owner: string, app: string) => get<string>(instanceIdForPreviewPath(owner, app));
export const getLayoutSchema = () => get<string[]>(layoutSchemaUrl());
export const getLayoutSets = (owner: string, app: string) => get<LayoutSets>(layoutSetsPath(owner, app));
export const getNewsList = (language: 'nb' | 'en') => get<NewsList>(newsListUrl(language));
export const getNumberFormatSchema = () => get<string[]>(numberFormatSchemaUrl());
export const getOptionListIds = (owner: string, app: string) => get<string[]>(optionListIdsPath(owner, app));
export const getOrgList = () => get<OrgsState>(orgsListUrl());
export const getOrganizations = () => get<Organization[]>(orgsListPath());
Expand Down
27 changes: 16 additions & 11 deletions frontend/packages/shared/src/cdn-paths.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
export const expressionSchemaUrl = () =>
'https://altinncdn.no/schemas/json/layout/expression.schema.v1.json';
// V4 Schema Paths
export const footerSchemaUrl = () =>
'https://altinncdn.no/schemas/json/layout/footer.schema.v1.json';
'https://altinncdn.no/toolkits/altinn-app-frontend/4/schemas/json/layout/footer.schema.v1.json';
export const layoutSetsSchemaUrl = () =>
'https://altinncdn.no/schemas/json/layout/layout-sets.schema.v1.json';
'https://altinncdn.no/toolkits/altinn-app-frontend/4/schemas/json/layout/layout-sets.schema.v1.json';
export const layoutSchemaUrl = () =>
'https://altinncdn.no/schemas/json/layout/layout.schema.v1.json';
'https://altinncdn.no/toolkits/altinn-app-frontend/4/schemas/json/layout/layout.schema.v1.json';
export const layoutSettingsSchemaUrl = () =>
'https://altinncdn.no/toolkits/altinn-app-frontend/4/schemas/json/layout/layoutSettings.schema.v1.json';

// V3 Schema Paths
export const footerSchemaUrlV3 = () =>
'https://altinncdn.no/schemas/json/layout/footer.schema.v1.json';
export const layoutSetsSchemaUrlV3 = () =>
'https://altinncdn.no/schemas/json/layout/layout-sets.schema.v1.json';
export const layoutSchemaUrlV3 = () =>
'https://altinncdn.no/schemas/json/layout/layout.schema.v1.json';
export const layoutSettingsSchemaUrlV3 = () =>
'https://altinncdn.no/schemas/json/layout/layoutSettings.schema.v1.json';
export const numberFormatSchemaUrl = () =>
'https://altinncdn.no/schemas/json/component/number-format.schema.v1.json';
export const componentSchemaUrl = (component) =>
`https://altinncdn.no/schemas/json/component/${component}.schema.v1.json`;

// General Paths
export const orgsListUrl = () => 'https://altinncdn.no/orgs/altinn-orgs.json';
export const altinnImgLogoHeaderUrl = () => 'https://altinncdn.no/img/Altinn-logo-blue.svg';
export const widgetUrl = () => 'https://altinncdn.no/altinn-apps/widgets/message.json';
export const newsListUrl = (langage = 'nb') =>
`https://altinncdn.no/studio/designer/news/news.${langage}.json`;
5 changes: 0 additions & 5 deletions frontend/packages/shared/src/mocks/queriesMock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,6 @@ export const queriesMock: ServicesContextProps = {
.mockImplementation(() => Promise.resolve<AppReleasesResponse>(appReleasesResponse)),
getAppVersion: jest.fn().mockImplementation(() => Promise.resolve<AppVersion>(appVersion)),
getBranchStatus: jest.fn().mockImplementation(() => Promise.resolve<BranchStatus>(branchStatus)),
getComponentSchema: jest.fn().mockImplementation(() => Promise.resolve<string[]>([])),
getComponentsCommonDefsSchema: jest.fn().mockImplementation(() => Promise.resolve<string[]>([])),
getDatamodel: jest.fn().mockImplementation(() => Promise.resolve<JsonSchema>({})),
getDatamodelMetadata: jest
.fn()
Expand All @@ -95,16 +93,13 @@ export const queriesMock: ServicesContextProps = {
.fn()
.mockImplementation(() => Promise.resolve<AppDeploymentsResponse>(appDeploymentsResponse)),
getEnvironments: jest.fn().mockImplementation(() => Promise.resolve<DeployEnvironment[]>([])),
getExpressionSchema: jest.fn().mockImplementation(() => Promise.resolve<string[]>([])),
getFormLayoutSettings: jest.fn().mockImplementation(() => Promise.resolve<ILayoutSettings>({})),
getFormLayouts: jest.fn().mockImplementation(() => Promise.resolve<FormLayoutsResponse>({})),
getFormLayoutsV3: jest.fn().mockImplementation(() => Promise.resolve<FormLayoutsResponseV3>({})),
getFrontEndSettings: jest.fn().mockImplementation(() => Promise.resolve<IFrontEndSettings>({})),
getInstanceIdForPreview: jest.fn().mockImplementation(() => Promise.resolve<string>('')),
getLayoutSchema: jest.fn().mockImplementation(() => Promise.resolve<string[]>([])),
getLayoutSets: jest.fn().mockImplementation(() => Promise.resolve<LayoutSets>(layoutSets)),
getNewsList: jest.fn().mockImplementation(() => Promise.resolve<NewsList>(newsList)),
getNumberFormatSchema: jest.fn().mockImplementation(() => Promise.resolve<string[]>([])),
getOptionListIds: jest.fn().mockImplementation(() => Promise.resolve<string[]>([])),
getOrgList: jest.fn().mockImplementation(() => Promise.resolve<OrgsState>(orgsState)),
getOrganizations: jest.fn().mockImplementation(() => Promise.resolve<Organization[]>([])),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
import { createEmptyLayout } from '../../utils/formLayoutUtils';
import type { ExternalFormLayoutV3 } from 'app-shared/types/api';
import type { IInternalLayout } from '../../types/global';
import { layoutSchemaUrl } from 'app-shared/cdn-paths';
import { layoutSchemaUrlV3 } from 'app-shared/cdn-paths';

describe('externalLayoutToInternal', () => {
it('Converts an external layout to an internal layout', () => {
Expand All @@ -23,7 +23,7 @@ describe('externalLayoutToInternal', () => {
const customProperty1 = 'test1';
const customProperty2 = 'test2';
const externalLayout: ExternalFormLayoutV3 = {
$schema: layoutSchemaUrl(),
$schema: layoutSchemaUrlV3(),
data: null,
customProperty1,
customProperty2,
Expand All @@ -45,7 +45,7 @@ describe('externalLayoutToInternal', () => {
const dataCustomProperty1 = 'test3';
const dataCustomProperty2 = 'test4';
const externalLayout: ExternalFormLayoutV3 = {
$schema: layoutSchemaUrl(),
$schema: layoutSchemaUrlV3(),
data: {
layout: null,
dataCustomProperty1,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { IInternalLayout } from '../../types/global';
import type { ExternalComponentV3, ExternalFormLayoutV3 } from 'app-shared/types/api';
import { layoutSchemaUrl } from 'app-shared/cdn-paths';
import { layoutSchemaUrlV3 } from 'app-shared/cdn-paths';
import type { ExternalContainerComponent } from '../../types/ExternalContainerComponent';
import { internalContainerComponentToExternal } from '../containerComponentConverters';
import type { FormContainer } from '../../types/FormContainer';
Expand All @@ -13,7 +13,7 @@ import type { FormComponent } from '../../types/FormComponent';
export const internalLayoutToExternal = (
internalLayout: IInternalLayout,
): ExternalFormLayoutV3 => ({
$schema: layoutSchemaUrl(),
$schema: layoutSchemaUrlV3(),
data: {
layout: generateExternalComponents(internalLayout),
...internalLayout.customDataProperties,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ describe('useAddLayoutMutation', () => {
layoutName,
selectedLayoutSet,
{
$schema: 'https://altinncdn.no/schemas/json/layout/layout.schema.v1.json',
$schema:
'https://altinncdn.no/toolkits/altinn-app-frontend/4/schemas/json/layout/layout.schema.v1.json',
data: {
layout: [expect.objectContaining({ type: ComponentType.NavigationButtons })],
hidden: undefined,
Expand Down Expand Up @@ -66,7 +67,8 @@ describe('useAddLayoutMutation', () => {
formLayoutSettingsMock.receiptLayoutName,
selectedLayoutSet,
{
$schema: 'https://altinncdn.no/schemas/json/layout/layout.schema.v1.json',
$schema:
'https://altinncdn.no/toolkits/altinn-app-frontend/4/schemas/json/layout/layout.schema.v1.json',
data: {
layout: [],
hidden: undefined,
Expand Down

0 comments on commit 974d961

Please sign in to comment.