Skip to content

Commit

Permalink
Implementing PagesRouter to navigate between packages (#11883)
Browse files Browse the repository at this point in the history
* Implementing PagesRouter to navigate between packages

* fixing feedback from PR

* fixing feedback from PR
  • Loading branch information
WilliamThorenfeldt authored Dec 19, 2023
1 parent d77979f commit 705fb4c
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 21 deletions.
10 changes: 5 additions & 5 deletions frontend/app-development/layout/PageHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { AltinnHeader } from 'app-shared/components/altinnHeader/AltinnHeader';
import { getFilteredTopBarMenu } from './AppBar/appBarConfig';
import { getRepositoryType } from 'app-shared/utils/repository';
import { useAppSelector } from 'app-development/hooks';
import { previewPath, publishPath } from 'app-shared/api/paths';
import { AltinnButtonActionItem } from 'app-shared/components/altinnHeader/types';
import { GiteaHeader } from 'app-shared/components/GiteaHeader';
import { SettingsModalButton } from './SettingsModalButton';
import { TopBarMenu } from 'app-shared/enums/TopBarMenu';
import { User } from 'app-shared/types/User';
import { PackagesRouter } from 'app-shared/navigation/PackagesRouter';

type SubMenuContentProps = {
org: string;
Expand All @@ -27,23 +27,23 @@ export const subMenuContent = ({ org, app }: SubMenuContentProps) => {
};

export const buttonActions = (org: string, app: string): AltinnButtonActionItem[] => {
const packagesRouter = new PackagesRouter({ org, app });

const actions: AltinnButtonActionItem[] = [
{
title: 'top_menu.preview',
path: previewPath,
menuKey: TopBarMenu.Preview,
buttonVariant: 'secondary',
buttonColor: 'inverted',
headerButtonsClasses: undefined,
handleClick: () => (window.location.href = previewPath(org, app)),
handleClick: () => packagesRouter.navigateToPackage('preview'),
},
{
title: 'top_menu.deploy',
path: publishPath,
menuKey: TopBarMenu.Deploy,
buttonVariant: 'secondary',
headerButtonsClasses: undefined,
handleClick: () => (window.location.href = publishPath(org, app)),
handleClick: () => packagesRouter.navigateToPackage('editorPublish'),
},
];
return actions;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react';
import { RepositoryType } from 'app-shared/types/global';
import { TFunction } from 'i18next';
import { editorPath } from 'app-shared/api/paths';
import { Button, Select, LegacyToggleButtonGroup } from '@digdir/design-system-react';
import { AltinnButtonActionItem } from 'app-shared/components/altinnHeader/types';
import classes from '../AppPreviewSubMenu.module.css';
Expand All @@ -12,7 +11,7 @@ import { useLayoutSetsQuery } from '../../../../packages/ux-editor/src/hooks/que
import { useStudioUrlParams } from 'app-shared/hooks/useStudioUrlParams';
import { TopBarMenu } from 'app-shared/enums/TopBarMenu';
import { TopBarMenuItem } from 'app-shared/types/TopBarMenuItem';
import { RoutePaths } from '../../enums/RoutePaths';
import { PackagesRouter } from 'app-shared/navigation/PackagesRouter';

export interface AppPreviewMenuItem {
key: string;
Expand Down Expand Up @@ -102,18 +101,16 @@ export const appPreviewButtonActions = (
app: string,
instanceId: string,
): AltinnButtonActionItem[] => {
const subUrl = `/${RoutePaths.UIEditor}?layout=`;
const packagesRouter = new PackagesRouter({ org, app });
const queryParams = `?layout=${window.localStorage.getItem(instanceId)}`;

const action: AltinnButtonActionItem[] = [
{
title: 'top_menu.preview_back_to_editing',
path: editorPath,
menuKey: TopBarMenu.Preview,
buttonVariant: 'secondary',
headerButtonsClasses: classes.backToEditorBtn,
handleClick: () =>
(window.location.href = `${editorPath(org, app)}${subUrl}${window.localStorage.getItem(
instanceId,
)}`),
handleClick: () => packagesRouter.navigateToPackage('editorUiEditor', queryParams),
},
];
return action;
Expand Down
3 changes: 0 additions & 3 deletions frontend/app-preview/src/enums/RoutePaths.ts

This file was deleted.

4 changes: 0 additions & 4 deletions frontend/packages/shared/src/api/paths.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,9 @@ export const datamodelMetadataPath = (org, app) => `${basePath}/${org}/${app}/mo
export const orgsListPath = () => `${basePath}/orgs`; // Get

// Preview
export const previewPath = (org, app) => `/preview/${org}/${app}`;
export const instanceIdForPreviewPath = (org, app) => `${basePath}/${org}/${app}/mock-instance-id`; // Get
export const previewPage = (org, app, selectedLayoutSet) => `/designer/html/preview.html?${s({ org, app, selectedLayoutSet })}`;

//Editor
export const editorPath = (org, app) => `/editor/${org}/${app}`;

// Preview - SignalR Hub
export const previewSignalRHubSubPath = () => `/previewHub`;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ export type AltinnHeaderVariant = 'regular' | 'preview';
export interface AltinnButtonActionItem {
title: string;
menuKey: string;
path?: (org: string, app: string) => string;
buttonVariant: ButtonProps['variant'];
buttonColor?: ButtonProps['color'];
headerButtonsClasses: any;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { PackagesRouter } from './PackagesRouter';

const mockOrg: string = 'org';
const mockApp: string = 'app';

describe('PackagesRouter', () => {
describe('constructor', () => {
it('should default to empty strings if app and org are not provided', () => {
const routerWithoutParams = new PackagesRouter();
expect(routerWithoutParams['app']).toEqual('');
expect(routerWithoutParams['org']).toEqual('');
});
});

describe('navigateToPackage', () => {
it('should navigate to the correct "editor/overview page when the location parameter is set to "editorOverview"', () => {
const packagesRouter = new PackagesRouter({ org: mockOrg, app: mockApp });
const expectedUrl = `/editor/${mockOrg}/${mockApp}/overview`;

// Mock the window.location.assign method
const assignMock = jest.fn();
Object.defineProperty(window, 'location', {
value: { assign: assignMock },
writable: true,
});

packagesRouter.navigateToPackage('editorOverview');

expect(assignMock).toHaveBeenCalledWith(expectedUrl);
});

it('should navigate to the correct URL and include queryParams', () => {
const packagesRouter = new PackagesRouter({ org: mockOrg, app: mockApp });

const mockQueryParams = '?layout=123';
const expectedUrl = `/editor/${mockOrg}/${mockApp}/ui-editor${mockQueryParams}`;

const assignMock = jest.fn();
Object.defineProperty(window, 'location', {
value: { assign: assignMock },
writable: true,
});

packagesRouter.navigateToPackage('editorUiEditor', mockQueryParams);

expect(assignMock).toHaveBeenCalledWith(expectedUrl);
});
});

describe('getPackageNavigationUrl', () => {
it('should return the correct URL for a package route with placeholders', () => {
const packagesRouter = new PackagesRouter({ org: mockOrg, app: mockApp });
const expectedUrl = `/editor/${mockOrg}/${mockApp}/deploy`;

const result = packagesRouter.getPackageNavigationUrl('editorPublish');

expect(result).toEqual(expectedUrl);
});

it('should return the correct URL for a package route without placeholders', () => {
const packagesRouter = new PackagesRouter({ org: mockOrg, app: mockApp });
const expectedUrl = '/dashboard';

const result = packagesRouter.getPackageNavigationUrl('dashboard');

expect(result).toEqual(expectedUrl);
});
});

describe('replaceOrgAndApp', () => {
it('should replace {{org}} and {{app}} placeholders in the given URL', () => {
const packagesRouter = new PackagesRouter({ org: mockOrg, app: mockApp });

const mockUrl = '/editor/{{org}}/{{app}}/overview';
const expectedUrl = `/editor/${mockOrg}/${mockApp}/overview`;

const result = packagesRouter['replaceOrgAndApp'](mockUrl);

expect(result).toEqual(expectedUrl);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
type ParamsOptions = {
org?: string;
app?: string;
};

type PackagesRoute =
| 'dashboard'
| 'editorOverview'
| 'editorUiEditor'
| 'preview'
| 'editorPublish';

const packagesRoutes: Record<PackagesRoute, string> = {
dashboard: '/dashboard',
editorOverview: '/editor/{{org}}/{{app}}/overview',
editorUiEditor: '/editor/{{org}}/{{app}}/ui-editor',
editorPublish: '/editor/{{org}}/{{app}}/deploy',
preview: '/preview/{{org}}/{{app}}',
};

export class PackagesRouter {
private app: string;
private org: string;

constructor(private paramsOptions?: ParamsOptions) {
this.app = this.paramsOptions?.app ?? '';
this.org = this.paramsOptions?.org ?? '';
}

public navigateToPackage(packageRoute: PackagesRoute, queryParams?: string): void {
window.location.assign(`${this.getPackageNavigationUrl(packageRoute)}${queryParams ?? ''}`);
}

public getPackageNavigationUrl(packageRoute: PackagesRoute): string {
const selectedPackageRoute = packagesRoutes[packageRoute];

if (selectedPackageRoute.includes('{{org}}') || selectedPackageRoute.includes('{{app}}')) {
return this.replaceOrgAndApp(selectedPackageRoute);
}

return selectedPackageRoute;
}

private replaceOrgAndApp(url: string): string {
return url.replace('{{org}}', this.org).replace('{{app}}', this.app);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { PackagesRouter } from './PackagesRouter';

0 comments on commit 705fb4c

Please sign in to comment.