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

Replace beta info popover in preview button with alert info panel in preview page #11307

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

/// <summary>
/// Get status if app is ready for preview
/// </summary>
[HttpGet]
[Route("preview/preview-status")]
public ActionResult<string> PreviewStatus()
{
return Ok();
}

/// <summary>
/// Action for getting local app-images
/// </summary>
Expand Down

This file was deleted.

1 change: 0 additions & 1 deletion frontend/app-development/layout/PageHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ export const buttonActions = (org: string, app: string): AltinnButtonActionItem[
buttonColor: 'inverted',
headerButtonsClasses: undefined,
handleClick: () => (window.location.href = previewPath(org, app)),
inBeta: true,
},
{
title: 'top_menu.deploy',
Expand Down
5 changes: 5 additions & 0 deletions frontend/app-preview/src/PreviewApp.module.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
:root {
--font-family: 'Inter', sans-serif;
}

.previewContainer {
--toolbar-height: 80px;
--subtoolbar-height: 60px;
Expand All @@ -7,6 +11,7 @@
);
--left-menu-width: 68px;

background-color: #efefef;
min-height: 100vh;
width: 100%;
display: flex;
Expand Down
25 changes: 0 additions & 25 deletions frontend/app-preview/src/PreviewContext.tsx

This file was deleted.

36 changes: 26 additions & 10 deletions frontend/app-preview/src/views/LandingPage.module.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.header {
font-family: Inter, 'San Fransisco', 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-family: var(--font-family);
standeren marked this conversation as resolved.
Show resolved Hide resolved
align-items: center;
height: var(--header-height);
width: 100vw;
Expand All @@ -15,7 +15,13 @@
border: none;
}

.iframeMobileViewContainer {
.previewLimitationsInfo {
max-width: 1000px;
width: 100%;
margin: 10px auto;
}

.iframeContainer {
display: flex;
justify-content: center;
background-color: #efefef;
Expand All @@ -30,12 +36,22 @@
margin: 0;
}

/* Mobile View Overlay to cover devtools in the middle of the screen */
.iframeMobileViewOverlay {
position: absolute;
bottom: 0;
height: 100px;
width: 100%;
background-color: #efefef;
z-index: 1;
.alert {
display: flex;
flex-direction: row;
align-self: center;
align-items: center;
width: fit-content;
font-family: var(--font-family);
}

.row {
display: flex;
flex-direction: row;
gap: 1rem;
}

.gridContainer {
display: grid;
grid-template-rows: max-content max-content;
}
84 changes: 84 additions & 0 deletions frontend/app-preview/src/views/LandingPage.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import React from 'react';
import { act, screen, queryByAttribute, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { LandingPage } from './LandingPage';
import { renderWithMockStore } from '../../../../frontend/packages/ux-editor/src/testing/mocks';
import { textMock } from '../../../testing/mocks/i18nMock';

describe('LandingPage', () => {

it('should render an iframe', () => {
const { renderResult } = renderWithMockStore()(<LandingPage variant={'preview'} />);

const getById = queryByAttribute.bind(null, 'id');

const iframe = getById(renderResult.container, 'app-frontend-react-iframe');
expect(iframe).toBeInTheDocument();
});

it('should render the information alert with preview being limited', () => {
renderWithMockStore()(<LandingPage variant={'preview'} />);

const previewLimitationsAlert = screen.getByText(textMock('preview.limitations_info'));
expect(previewLimitationsAlert).toBeInTheDocument();
});

it('should render a popover with options for remembering closing-choice in session or not when clicking cross-button in alert', async () => {
renderWithMockStore()(<LandingPage variant={'preview'} />);

const user = userEvent.setup();

const previewLimitationsAlert = screen.getByText(textMock('preview.limitations_info'));
const alert = within(previewLimitationsAlert);
const hidePreviewLimitationsAlertButton = alert.getByRole('button');
await act(() => user.click(hidePreviewLimitationsAlertButton));
const hidePreviewLimitationsPopover = screen.getByText(textMock('session.reminder'));
expect(hidePreviewLimitationsPopover).toBeInTheDocument();
const hidePreviewLimitationsTemporaryButton = screen.getByRole('button', { name: textMock('session.do_show_again') });
const hidePreviewLimitationsForSessionButton = screen.getByRole('button', { name: textMock('session.dont_show_again') });
expect(hidePreviewLimitationsTemporaryButton).toBeInTheDocument();
expect(hidePreviewLimitationsForSessionButton).toBeInTheDocument();
});

it('should close popover and not set value in session storage when hidePreviewLimitationsTemporaryButton is clicked', async () => {
renderWithMockStore()(<LandingPage variant={'preview'} />);

const user = userEvent.setup();

// Open popover
const previewLimitationsAlert = screen.getByText(textMock('preview.limitations_info'));
const alert = within(previewLimitationsAlert);
const hidePreviewLimitationsAlertButton = alert.getByRole('button');
await act(() => user.click(hidePreviewLimitationsAlertButton));
const hidePreviewLimitationsPopover = screen.getByText(textMock('session.reminder'));
expect(hidePreviewLimitationsPopover).toBeInTheDocument();
const hidePreviewLimitationsTemporaryButton = screen.getByRole('button', { name: textMock('session.do_show_again') });

// Click hide temporary button
await act(() => user.click(hidePreviewLimitationsTemporaryButton));

expect(hidePreviewLimitationsPopover).not.toBeInTheDocument();
expect(window.sessionStorage.getItem('showPreviewLimitationsInfo')).toBeNull();
});

it('should close popover and set value in session storage when hidePreviewLimitationsForSessionButton is clicked', async () => {
renderWithMockStore()(<LandingPage variant={'preview'} />);

const user = userEvent.setup();

// Open popover
const previewLimitationsAlert = screen.getByText(textMock('preview.limitations_info'));
const alert = within(previewLimitationsAlert);
const hidePreviewLimitationsAlertButton = alert.getByRole('button');
await act(() => user.click(hidePreviewLimitationsAlertButton));
const hidePreviewLimitationsPopover = screen.getByText(textMock('session.reminder'));
expect(hidePreviewLimitationsPopover).toBeInTheDocument();
const hidePreviewLimitationsForSessionButton = screen.getByRole('button', { name: textMock('session.dont_show_again') });

// Click hide forever button
await act(() => user.click(hidePreviewLimitationsForSessionButton));

expect(hidePreviewLimitationsPopover).not.toBeInTheDocument();
expect(window.sessionStorage.getItem('showPreviewLimitationsInfo')).toBe('false');
});
});
93 changes: 62 additions & 31 deletions frontend/app-preview/src/views/LandingPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import React, { useState } from 'react';
import classes from './LandingPage.module.css';
import { PreviewContext } from '../PreviewContext';
import { useTranslation } from 'react-i18next';
import { usePreviewConnection } from 'app-shared/providers/PreviewConnectionContext';
import { useInstanceIdQuery, useRepoMetadataQuery, useUserQuery } from 'app-shared/hooks/queries';
Expand All @@ -14,8 +13,11 @@ import {
} from '../components/AppBarConfig/AppPreviewBarConfig';
import { appPreviewButtonActions } from '../components/AppBarConfig/AppPreviewBarConfig';
import { AppPreviewSubMenu } from '../components/AppPreviewSubMenu';
import { Alert, Button, LegacyPopover } from '@digdir/design-system-react';
import { XMarkIcon } from '@navikt/aksel-icons';
import { useStudioUrlParams } from 'app-shared/hooks/useStudioUrlParams';
import { previewPage } from 'app-shared/api/paths';
import { typedSessionStorage } from 'app-shared/utils/webStorage';

export interface LandingPageProps {
variant?: AltinnHeaderVariant;
Expand All @@ -30,15 +32,19 @@ export const LandingPage = ({ variant = 'preview' }: LandingPageProps) => {
const { data: user } = useUserQuery();
const { data: repository } = useRepoMetadataQuery(org, app);
const { data: instanceId } = useInstanceIdQuery(org, app);
const repoType = getRepositoryType(org, app);
const menu = getTopBarAppPreviewMenu(org, app, repoType, t);
const [openSaveChoiceInSession, setOpenShowSaveChoiceInSession] = useState<boolean>(false);
const showPreviewLimitationsInfoSession: boolean = typedSessionStorage.getItem('showPreviewLimitationsInfo');
const [showPreviewLimitationsInfo, setShowPreviewLimitationsInfo] = useState<boolean>(showPreviewLimitationsInfoSession ?? true);
const [selectedLayoutSetInEditor, setSelectedLayoutSetInEditor] = useLocalStorage<string>(
'layoutSet/' + app,
);
const [previewViewSize, setPreviewViewSize] = useLocalStorage<PreviewAsViewSize>(
'viewSize',
'desktop',
);

const repoType = getRepositoryType(org, app);
const menu = getTopBarAppPreviewMenu(org, app, repoType, t);
const isIFrame = (input: HTMLElement | null): input is HTMLIFrameElement =>
input !== null && input.tagName === 'IFRAME';

Expand All @@ -48,6 +54,16 @@ export const LandingPage = ({ variant = 'preview' }: LandingPageProps) => {
window.location.reload();
};

const handleHidePreviewLimitations = () => {
setShowPreviewLimitationsInfo(false);
setOpenShowSaveChoiceInSession(false);
};

const handleRememberChoiceForSession = () => {
typedSessionStorage.setItem('showPreviewLimitationsInfo', false);
handleHidePreviewLimitations();
};

if (previewConnection) {
previewConnection.on('ReceiveMessage', function (message) {
const frame = document.getElementById('app-frontend-react-iframe');
Expand All @@ -62,39 +78,54 @@ export const LandingPage = ({ variant = 'preview' }: LandingPageProps) => {
}

return (
<PreviewContext>
<>
<div className={classes.header}>
<AltinnHeader
menu={menu}
showSubMenu={true}
activeMenuSelection={TopBarAppPreviewMenu.Preview}
org={org}
app={app}
user={user}
repository={repository}
buttonActions={appPreviewButtonActions(org, app, instanceId)}
variant={variant}
subMenuContent={
<AppPreviewSubMenu
setViewSize={setPreviewViewSize}
viewSize={previewViewSize}
selectedLayoutSet={selectedLayoutSetInEditor}
handleChangeLayoutSet={handleChangeLayoutSet}
/>
}
/>
</div>
<div className={classes.iframeMobileViewContainer}>
<>
<div className={classes.header}>
<AltinnHeader
menu={menu}
showSubMenu={true}
activeMenuSelection={TopBarAppPreviewMenu.Preview}
org={org}
app={app}
user={user}
repository={repository}
buttonActions={appPreviewButtonActions(org, app, instanceId)}
variant={variant}
subMenuContent={
<AppPreviewSubMenu
setViewSize={setPreviewViewSize}
viewSize={previewViewSize}
selectedLayoutSet={selectedLayoutSetInEditor}
handleChangeLayoutSet={handleChangeLayoutSet}
/>
}
/>
</div>
<div className={classes.gridContainer}>
{showPreviewLimitationsInfo &&
<Alert severity='info' className={classes.previewLimitationsInfo}>
<div className={classes.alert}>
{t('preview.limitations_info')}
<LegacyPopover
trigger={<Button onClick={() => setOpenShowSaveChoiceInSession(!openSaveChoiceInSession)} size='small' variant='tertiary' icon={<XMarkIcon />}/>}
open={openSaveChoiceInSession}
>
{t('session.reminder')}
<span className={classes.row}>
<Button onClick={handleHidePreviewLimitations} size='small' variant='secondary'>{t('session.do_show_again')}</Button>
<Button onClick={handleRememberChoiceForSession} size='small' variant='secondary'>{t('session.dont_show_again')}</Button>
</span>
</LegacyPopover>
</div>
</Alert>}
<div className={classes.iframeContainer}>
<iframe
title={t('preview.iframe_title')}
id='app-frontend-react-iframe'
src={previewPage(org, app, selectedLayoutSetInEditor)}
className={previewViewSize === 'desktop' ? classes.iframeDesktop : classes.iframeMobile}
/>
{previewViewSize === 'mobile' && <div className={classes.iframeMobileViewOverlay}></div>}
</div>
</>
</PreviewContext>
</div>
</>
);
};
1 change: 0 additions & 1 deletion frontend/language/src/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,6 @@
"top_menu.policy-editor": "Policy",
"top_menu.preview": "Preview",
"top_menu.preview_back_to_editing": "Back to editing",
"top_menu.preview_is_beta_message": "This functionality is in beta. We are working to improve it.",
"top_menu.process-editor": "Process",
"top_menu.texts": "Texts",
"top_menu.texts_old": "Texts *",
Expand Down
Loading
Loading