Skip to content

Commit

Permalink
Merge branch 'main' into feat/podmanSupport
Browse files Browse the repository at this point in the history
  • Loading branch information
Øvrelid committed Feb 2, 2024
2 parents ed0ccd8 + c2113ca commit 4a03275
Show file tree
Hide file tree
Showing 593 changed files with 38,967 additions and 1,221 deletions.
9 changes: 6 additions & 3 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ on:
- main
paths:
- 'frontend/**'
- '.github/workflow/playwright.yml'
workflow_dispatch:
- '.github/workflows/playwright.yml'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
playwright-run:
Expand Down Expand Up @@ -37,7 +40,7 @@ jobs:
restore-keys: |
${{ runner.os }}-yarn-
- name: Attempt to wait for deploy to environment (10 minutes sleep)
- name: Attempt to wait for deploy to environment (12 minutes sleep)
run: sleep 10m
shell: bash

Expand Down
28 changes: 28 additions & 0 deletions backend/src/Designer/Controllers/PreviewController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,24 @@ public IActionResult Index(string org, string app)
return View();
}

/// <summary>
/// Endpoint to fetch the cshtml to render app-frontend specific to what is defined in the app-repo
/// </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>
/// <returns>The cshtml modified to ignore this route path added in the iframe.</returns>
[HttpGet]
[Route("/app-specific-preview/{org}/{app:regex(^(?!datamodels$)[[a-z]][[a-z0-9-]]{{1,28}}[[a-z0-9]]$)}")]
public async Task<IActionResult> AppFrontendSpecificPreview(string org, string app)
{
string developer = AuthenticationHelper.GetDeveloperUserName(_httpContextAccessor.HttpContext);
AltinnAppGitRepository altinnAppGitRepository = _altinnGitRepositoryFactory.GetAltinnAppGitRepository(org, app, developer);
var appFrontendCshtml = await altinnAppGitRepository.GetAppFrontendCshtml();
var modifiedContent = ReplaceIndexToFetchCorrectOrgAppInCshtml(appFrontendCshtml);

return Content(modifiedContent, "text/html");
}

/// <summary>
/// Action for getting local app-images
/// </summary>
Expand Down Expand Up @@ -877,5 +895,15 @@ private string GetSelectedLayoutSetInEditorFromRefererHeader(string refererHeade

return string.IsNullOrEmpty(layoutSetName) ? null : layoutSetName;
}

private string ReplaceIndexToFetchCorrectOrgAppInCshtml(string originalContent)
{
// Replace the array indexes in the script in the cshtml that retrieves the org and app name since
// /app-specific-preview/ is added when fetching the cshtml file from endpoint instead of designer wwwroot
string modifiedContent = originalContent.Replace("window.org = appId[1];", "window.org = appId[2];");
modifiedContent = modifiedContent.Replace("window.app = appId[2];", "window.app = appId[3];");

return modifiedContent;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public class AltinnAppGitRepository : AltinnGitRepository
private const string LANGUAGE_RESOURCE_FOLDER_NAME = "texts/";
private const string MARKDOWN_TEXTS_FOLDER_NAME = "md/";
private const string PROCESS_DEFINITION_FOLDER_PATH = "App/config/process/";
private const string CSHTML_PATH = "App/views/Home/index.cshtml";

private const string SERVICE_CONFIG_FILENAME = "config.json";
private const string LAYOUT_SETTINGS_FILENAME = "Settings.json";
Expand Down Expand Up @@ -701,6 +702,23 @@ public async Task<LayoutSets> CreateLayoutSetFile(string layoutSetName)
return layoutSets;
}

/// <summary>
/// Gets the cshtml file for the app
/// </summary>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> that observes if operation is cancelled.</param>
/// <returns>The content of Index.cshtml</returns>
public async Task<string> GetAppFrontendCshtml(CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
if (FileExistsByRelativePath(CSHTML_PATH))
{
string cshtml = await ReadTextByRelativePathAsync(CSHTML_PATH, cancellationToken);
return cshtml;
}

throw new FileNotFoundException("Index.cshtml was not found.");
}

/// <summary>
/// Gets the options list with the provided id.
/// <param name="optionsListId">The id of the options list to fetch.</param>
Expand Down Expand Up @@ -854,8 +872,6 @@ private static string GetPathToRuleConfiguration(string layoutSetName)
Path.Combine(LAYOUTS_FOLDER_NAME, layoutSetName, RULE_CONFIGURATION_FILENAME);
}



/// <summary>
/// String writer that ensures UTF8 is used.
/// </summary>
Expand Down
27 changes: 0 additions & 27 deletions backend/src/Designer/wwwroot/designer/html/preview.html

This file was deleted.

30 changes: 25 additions & 5 deletions frontend/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,48 @@
"plugin:react/recommended",
"plugin:react-hooks/recommended"
],
"plugins": ["jsx-a11y", "react", "react-hooks", "@typescript-eslint"],
"plugins": ["jsx-a11y", "react", "react-hooks", "@typescript-eslint", "import"],
"parser": "@typescript-eslint/parser",
"rules": {
"react/destructuring-assignment": "off",
"react/prop-types": "error",
"react/require-default-props": "off",
"import/prefer-default-export": "off",
"react/jsx-key": "error",
"react/jsx-filename-extension": ["warn", { "extensions": [".tsx"] }],
"react/jsx-filename-extension": [
"warn",
{
"extensions": [".tsx"]
}
],
"prefer-const": "error",
"object-curly-spacing": ["error", "always"],
"@typescript-eslint/consistent-type-imports": "error",
"@typescript-eslint/no-use-before-define": "off",
"@typescript-eslint/no-explicit-any": "off"
"@typescript-eslint/no-explicit-any": "off",
"no-restricted-imports": [
"error",
{
"patterns": [
{
"group": ["**/libs/**"],
"message": "Use the package name, not the relative path, when importing from a @studio library."
}
]
}
]
},

"overrides": [
{
"files": ["*.tsx"],
"rules": {
"react/react-in-jsx-scope": "off",
"react/jsx-no-useless-fragment": ["error", { "allowExpressions": true }],
"react/jsx-no-useless-fragment": [
"error",
{
"allowExpressions": true
}
],
"no-use-before-define": "off",
"no-shadow": "off",
"react/function-component-definition": "off",
Expand Down
61 changes: 61 additions & 0 deletions frontend/app-development/router/routes.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { render, screen } from '@testing-library/react';
import { routerRoutes } from './routes';
import { RoutePaths } from '../enums/RoutePaths';
import React from 'react';
import { createQueryClientMock } from 'app-shared/mocks/queryClientMock';
import { QueryKey } from 'app-shared/types/QueryKey';
import type { AppVersion } from 'app-shared/types/AppVersion';
import { ServicesContextProvider } from 'app-shared/contexts/ServicesContext';
import { queriesMock } from 'app-shared/mocks/queriesMock';

// Mocks:
jest.mock('../../packages/ux-editor-v3/src/SubApp', () => ({
SubApp: () => <div data-testid='version 3' />,
}));
jest.mock('../../packages/ux-editor/src/SubApp', () => ({
SubApp: () => <div data-testid='latest version' />,
}));

// Test data
const org = 'org';
const app = 'app';

describe('routes', () => {
describe(RoutePaths.UIEditor, () => {
type FrontendVersion = null | '3.0.0' | '4.0.0';
type PackageVersion = 'version 3' | 'latest version';
type TestCase = [PackageVersion, FrontendVersion];

const testCases: TestCase[] = [
['version 3', null],
['version 3', '3.0.0'],
['latest version', '4.0.0'],
];

it.each(testCases)(
'Renders the %s schema editor page when the app frontend version is %s',
(expectedPackage, frontendVersion) => {
renderUiEditor(frontendVersion);
expect(screen.getByTestId(expectedPackage)).toBeInTheDocument();
},
);

const renderUiEditor = (frontendVersion: string | null) =>
renderSubapp(RoutePaths.UIEditor, frontendVersion);
});
});

const renderSubapp = (path: RoutePaths, frontendVersion: string = null) => {
const Subapp = routerRoutes.find((route) => route.path === path)!.subapp;
const appVersion: AppVersion = {
frontendVersion,
backendVersion: '7.0.0',
};
const queryClient = createQueryClientMock();
queryClient.setQueryData([QueryKey.AppVersion, org, app], appVersion);
return render(
<ServicesContextProvider {...queriesMock} client={queryClient}>
<Subapp />
</ServicesContextProvider>,
);
};
19 changes: 17 additions & 2 deletions frontend/app-development/router/routes.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { SubApp } from '../../packages/ux-editor/src/SubApp';
import { SubApp as UiEditorLatest } from '../../packages/ux-editor/src/SubApp';
import { SubApp as UiEditorV3 } from '../../packages/ux-editor-v3/src/SubApp';
import { Overview } from '../features/overview/components/Overview';
import { TextEditor } from '../features/textEditor/TextEditor';
import DataModellingContainer from '../features/dataModelling/containers/DataModellingContainer';
import { DeployPage } from '../features/appPublish/pages/deployPage';
import { ProcessEditor } from 'app-development/features/processEditor';
import { RoutePaths } from 'app-development/enums/RoutePaths';
import type { AppVersion } from 'app-shared/types/AppVersion';
import { useStudioUrlParams } from 'app-shared/hooks/useStudioUrlParams';
import { useAppVersionQuery } from 'app-shared/hooks/queries';
import React from 'react';

interface IRouteProps {
headerTextKey?: string;
Expand All @@ -25,10 +30,20 @@ interface RouterRoute {
props?: IRouteProps;
}

const latestFrontendVersion = '4';
const isLatestFrontendVersion = (version: AppVersion): boolean =>
version?.frontendVersion?.startsWith(latestFrontendVersion);

const UiEditor = () => {
const { org, app } = useStudioUrlParams();
const { data } = useAppVersionQuery(org, app);
return isLatestFrontendVersion(data) ? <UiEditorLatest /> : <UiEditorV3 />;
};

export const routerRoutes: RouterRoute[] = [
{
path: RoutePaths.UIEditor,
subapp: SubApp,
subapp: UiEditor,
},
{
path: RoutePaths.Overview,
Expand Down
10 changes: 8 additions & 2 deletions frontend/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ const config = {
},
transformIgnorePatterns: [
`node_modules(\\\\|/)(?!${packagesToTransform})`,
'frontend/packages/ux-editor/src/testing/schemas/',
'\\.schema\\.v1\\.json$',
'nb.json$',
'en.json$',
],
reporters: ['default', 'jest-junit'],
moduleNameMapper: {
Expand All @@ -44,6 +46,7 @@ const config = {
'^@altinn/schema-editor/(.*)': path.join(__dirname, 'packages/schema-editor/src/$1'),
'^@altinn/schema-model/(.*)': path.join(__dirname, 'packages/schema-model/src/$1'),
'^@altinn/ux-editor/(.*)': path.join(__dirname, 'packages/ux-editor/src/$1'),
'^@altinn/ux-editor-v3/(.*)': path.join(__dirname, 'packages/ux-editor-v3/src/$1'),
'^@altinn/process-editor/(.*)': path.join(__dirname, 'packages/process-editor/src/$1'),
'^@altinn/policy-editor/(.*)': path.join(__dirname, 'packages/policy-editor/src/$1'),
'^@studio/icons': path.join(__dirname, 'libs/studio-icons/src/$1'),
Expand All @@ -60,6 +63,9 @@ if (process.env.CI) {
config.reporters.push('github-actions');
config.collectCoverage = true;
config.coverageReporters = ['lcov'];
config.coveragePathIgnorePatterns = ['frontend/packages/ux-editor/src/testing/'];
config.coveragePathIgnorePatterns = [
'frontend/packages/ux-editor/src/testing/',
'frontend/packages/ux-editor-v3/src/testing/',
];
}
module.exports = config;
5 changes: 4 additions & 1 deletion frontend/language/src/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,8 @@
"left_menu.pages_error_format": "Must consist of letters (a-z), numbers, or \"-\", \"_\" and \".\"",
"left_menu.pages_error_length": "Can not be more than 30 characters",
"left_menu.pages_error_unique": "Must be unique",
"local_changes.modal_download_only_changed_button": "Download zip-file with only locally changed files.",
"local_changes_modal.download_all_button": "Download zip-file of the entire repo.",
"merge_conflict.body1": "There are breaking changes in the application that blocks further work.",
"merge_conflict.body2": "You can fix these by either download the application as a zip-file and delete the changes, or just blast the application directly.",
"merge_conflict.download": "Download",
Expand Down Expand Up @@ -918,6 +920,7 @@
"sync_header.no_changes_to_share": "Push",
"sync_header.nothing_to_push": "You have pushed your latest changes",
"sync_header.repo_is_offline": "Repo is offline",
"sync_header.repository": "Repository",
"sync_header.service_updated_to_latest": "Your app is updated to the latest version",
"sync_header.service_updated_to_latest_submessage": "It is important to fetch changes often if there are multiple people working on the same app. This reduces the chances of merge conflicts.",
"sync_header.share_changes": "Push",
Expand All @@ -932,6 +935,7 @@
"testing.testing_in_testenv_title": "Testing in test environment",
"top_menu.about": "About",
"top_menu.create": "Create",
"top_menu.dashboard": "Dashboard",
"top_menu.datamodel": "Data model",
"top_menu.deploy": "Deploy",
"top_menu.policy-editor": "Policy",
Expand Down Expand Up @@ -987,7 +991,6 @@
"ux_editor.component_dropdown_set_preselected": "Set pre-selected value in dropdown list",
"ux_editor.component_file_upload": "Attachment",
"ux_editor.component_group": "Group",
"ux_editor.component_group_header": "Group - {{id}}",
"ux_editor.component_header": "Title",
"ux_editor.component_image": "Image",
"ux_editor.component_information_panel": "Informative message",
Expand Down
5 changes: 4 additions & 1 deletion frontend/language/src/nb.json
Original file line number Diff line number Diff line change
Expand Up @@ -1068,6 +1068,7 @@
"schema_editor.custom_props_help": "Dette er egenskaper som ikke støttes av Altinn Studio, men som er satt inn på datamodellen ved hjelp av andre verktøy. Her kan man slette egenskepene eller endre deres verdier, men det er ikke mulig å legge til nye. Vær oppmerksom på at egenskaper som slettes fra denne listen ikke kan legges til igjen ved hjelp av Altinn Studio.",
"schema_editor.custom_props_unknown_format": "Ukjent format",
"schema_editor.custom_props_unknown_format_help": "Denne egenskapen har et format som ikke kan forhåndsvises eller redigeres i Altinn Studio.",
"schema_editor.datamodel_definition_field_deletion_text": "Feltet du vil slette tilhører en aktiv type og vil påvirke alle tilknyttede områder. Er du sikker på slettingen?",
"schema_editor.datamodel_field_deletion_confirm": "Ja, slett feltet",
"schema_editor.datamodel_field_deletion_info": "Forsikre deg om at feltet ikke er knyttet til noen oppsett eller regler før du sletter det.",
"schema_editor.datamodel_field_deletion_text": "Er du sikker på at du vil slette dette feltet?",
Expand Down Expand Up @@ -1122,6 +1123,7 @@
"schema_editor.import": "Importer",
"schema_editor.in_use_error": "Kan ikke slettes, er i bruk.",
"schema_editor.integer": "Heltall",
"schema_editor.invalid_child_error": "Det er ikke mulig å plassere den komponenttypen i denne gruppen.",
"schema_editor.keyword": "Nøkkelord",
"schema_editor.language": "Språk",
"schema_editor.language_add_language": "Legg til språk:",
Expand Down Expand Up @@ -1264,6 +1266,7 @@
"sync_header.no_changes_to_share": "Last opp dine endringer",
"sync_header.nothing_to_push": "Du har delt dine siste endringer",
"sync_header.repo_is_offline": "Repo er utilgjengelig",
"sync_header.repository": "Repository",
"sync_header.service_updated_to_latest": "Appen din er oppdatert til siste versjon",
"sync_header.service_updated_to_latest_submessage": "Hvis det er flere personer som jobber på samme app er det viktig å hente endringer ofte. På denne måten reduserer du sjansen for mergekonflikter.",
"sync_header.settings": "Innstillinger",
Expand All @@ -1289,6 +1292,7 @@
"text_editor.variables_editing_not_supported": "Det, er ikke lagt til støtte for redigering av variabler i Studio.",
"top_menu.about": "Oversikt",
"top_menu.create": "Lage",
"top_menu.dashboard": "Dashboard",
"top_menu.datamodel": "Datamodell",
"top_menu.deploy": "Publiser",
"top_menu.preview": "Forhåndsvis",
Expand Down Expand Up @@ -1340,7 +1344,6 @@
"ux_editor.component_deletion_confirm": "Ja, slett komponenten",
"ux_editor.component_deletion_text": "Er du sikker på at du vil slette denne komponenten?",
"ux_editor.component_dropdown_set_preselected": "Sett forhåndsvalgt verdi for nedtrekksliste",
"ux_editor.component_group_header": "Gruppe - {{id}}",
"ux_editor.component_help_text.Accordion": "Med Accordion kan du presentere mye innhold på liten plass i en eller flere rader. Hele raden er klikkbar og lar brukere åpne eller lukke visningen av innholdet under.",
"ux_editor.component_help_text.AccordionGroup": "En samling med Accordions som vises vertikalt. Brukes for å gruppere Accordions som hører sammen.",
"ux_editor.component_help_text.ActionButton": "Knapp for å trigge en spesifisert aksjon knyttet til prosess-steget sluttbruker befinner seg i. Eksempler inkluderer 'sign', 'confirm', 'reject'.",
Expand Down
Loading

0 comments on commit 4a03275

Please sign in to comment.