Skip to content
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { FormProvider } from 'src/features/form/FormContext';
import { InstanceProvider } from 'src/features/instance/InstanceContext';
import { PartySelection } from 'src/features/instantiate/containers/PartySelection';
import { InstanceSelectionWrapper } from 'src/features/instantiate/selection/InstanceSelection';
import { PDFWrapper } from 'src/features/pdf/PDFWrapper';
import { PdfWrapper } from 'src/features/pdf/PdfWrapper';
import { FixWrongReceiptType } from 'src/features/receipt/FixWrongReceiptType';
import { DefaultReceipt } from 'src/features/receipt/ReceiptContainer';
import { TaskKeys } from 'src/hooks/useNavigatePage';
Expand Down Expand Up @@ -83,11 +83,11 @@ export const App = () => (
<Route
index
element={
<PDFWrapper>
<PdfWrapper>
<PresentationComponent>
<Form />
</PresentationComponent>
</PDFWrapper>
</PdfWrapper>
}
/>
<Route path=':componentId'>
Expand Down
6 changes: 5 additions & 1 deletion src/components/presentation/Presentation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,5 +121,9 @@ export const useHasPresentation = () => useHasProvider();
* for loaders, this can be used to prevent the loader from creating a presentation.
*/
export function DummyPresentation({ children }: PropsWithChildren) {
return <PresentationProvider value={undefined}>{children}</PresentationProvider>;
return (
<PresentationProvider value={undefined}>
<RenderStart>{children}</RenderStart>
</PresentationProvider>
);
}
16 changes: 14 additions & 2 deletions src/components/wrappers/ProcessWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ import { getProcessNextMutationKey, getTargetTaskFromProcess } from 'src/feature
import { useGetTaskTypeById, useProcessQuery } from 'src/features/instance/useProcessQuery';
import { Lang } from 'src/features/language/Lang';
import { useLanguage } from 'src/features/language/useLanguage';
import { Confirm } from 'src/features/processEnd/confirm/containers/Confirm';
import { Feedback } from 'src/features/processEnd/feedback/Feedback';
import { PdfWrapper } from 'src/features/pdf/PdfWrapper';
import { Confirm } from 'src/features/process/confirm/containers/Confirm';
import { Feedback } from 'src/features/process/feedback/Feedback';
import { ServiceTask } from 'src/features/process/service/ServiceTask';
import { useNavigationParam } from 'src/hooks/navigation';
import { TaskKeys, useIsValidTaskId, useNavigateToTask, useStartUrl } from 'src/hooks/useNavigatePage';
import { useWaitForQueries } from 'src/hooks/useWaitForQueries';
Expand Down Expand Up @@ -143,6 +145,16 @@ export function ProcessWrapper({ children }: PropsWithChildren) {
);
}

if (taskType === ProcessTaskType.Service) {
return (
<PdfWrapper>
<PresentationComponent>
<ServiceTask />
</PresentationComponent>
</PdfWrapper>
);
}

if (taskType === ProcessTaskType.Data) {
return children;
}
Expand Down
1 change: 1 addition & 0 deletions src/core/routing/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ export enum SearchParams {
ExitSubform = 'exitSubform',
Validate = 'validate',
Pdf = 'pdf',
PdfForTask = 'task',
BackToPage = 'backToPage',
}
4 changes: 4 additions & 0 deletions src/features/instance/useProcessQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ export function useGetTaskTypeById() {
return ProcessTaskType.Archived;
}

if (task?.elementType === 'ServiceTask') {
return ProcessTaskType.Service;
}

const altinnTaskType = task?.altinnTaskType;
if (altinnTaskType && isProcessTaskType(altinnTaskType)) {
return altinnTaskType;
Expand Down
9 changes: 9 additions & 0 deletions src/features/pdf/PDFView.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,19 @@
margin-bottom: var(--ds-size-12);
}

.pageBreak {
height: 0;
width: 0;
}

@media print {
.hideInPrint {
display: none;
}

.pageBreak {
page-break-before: always;
}
}

@media screen {
Expand Down
6 changes: 3 additions & 3 deletions src/features/pdf/PDFWrapper.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { getProcessDataMock } from 'src/__mocks__/getProcessDataMock';
import { PresentationComponent } from 'src/components/presentation/Presentation';
import { FormProvider } from 'src/features/form/FormContext';
import { InstanceProvider } from 'src/features/instance/InstanceContext';
import { PDFWrapper } from 'src/features/pdf/PDFWrapper';
import { PdfWrapper } from 'src/features/pdf/PdfWrapper';
import { fetchApplicationMetadata, fetchInstanceData, fetchProcessState } from 'src/queries/queries';
import { InstanceRouter, renderWithoutInstanceAndLayout } from 'src/test/renderWithProviders';
import type { AppQueries } from 'src/queries/types';
Expand Down Expand Up @@ -52,11 +52,11 @@ const render = async (renderAs: RenderAs, queriesOverride?: Partial<AppQueries>)
renderer: () => (
<InstanceProvider>
<FormProvider>
<PDFWrapper>
<PdfWrapper>
<PresentationComponent>
<Form />
</PresentationComponent>
</PDFWrapper>
</PdfWrapper>
</FormProvider>
</InstanceProvider>
),
Expand Down
105 changes: 87 additions & 18 deletions src/features/pdf/PdfView2.tsx → src/features/pdf/PdfFromLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useMemo } from 'react';
import { useSearchParams } from 'react-router-dom';
import type { PropsWithChildren } from 'react';

import { Heading } from '@digdir/designsystemet-react';
Expand All @@ -7,6 +8,7 @@ import { Flex } from 'src/app-components/Flex/Flex';
import { OrganisationLogo } from 'src/components/presentation/OrganisationLogo/OrganisationLogo';
import { DummyPresentation } from 'src/components/presentation/Presentation';
import { BlockPrint, ReadyForPrint } from 'src/components/ReadyForPrint';
import { SearchParams } from 'src/core/routing/types';
import { useAppName, useAppOwner } from 'src/core/texts/appTexts';
import { useApplicationMetadata } from 'src/features/applicationMetadata/ApplicationMetadataProvider';
import { useLayoutLookups } from 'src/features/form/layout/LayoutsContext';
Expand All @@ -24,30 +26,77 @@ import { AllSubformSummaryComponent2 } from 'src/layout/Subform/Summary/SubformS
import { SummaryComponentFor } from 'src/layout/Summary/SummaryComponent';
import { ComponentSummary } from 'src/layout/Summary2/SummaryComponent2/ComponentSummary';
import { SummaryComponent2 } from 'src/layout/Summary2/SummaryComponent2/SummaryComponent2';
import { TaskSummaryWrapper } from 'src/layout/Summary2/SummaryComponent2/TaskSummaryWrapper';
import { useIsHiddenMulti } from 'src/utils/layout/hidden';
import { useExternalItem } from 'src/utils/layout/hooks';
import { NodesInternal } from 'src/utils/layout/NodesContext';
import { useItemIfType } from 'src/utils/layout/useNodeItem';
import type { IPdfFormat } from 'src/features/pdf/types';

export const PDFView2 = () => {
const order = usePageOrder();
const { data: pdfSettings, isFetching: pdfFormatIsLoading } = usePdfFormatQuery(true);
export function PdfFromLayout() {
const pdfLayoutName = usePdfLayoutName();
if (pdfLayoutName) {
return (
<PdfWrapping>
<PlainPage pageKey={pdfLayoutName} />
</PdfWrapping>
);
}

return <AutoGeneratePdfFromLayout />;
}

function AutoGeneratePdfFromLayout() {
const [params] = useSearchParams();
const taskIds = params.getAll(SearchParams.PdfForTask);
if (taskIds.length > 0) {
throw new Error(
`Unexpected search param ${SearchParams.PdfForTask} provided. This mode does not support passing ` +
`${SearchParams.PdfForTask} as a search param, but will auto-generate a PDF from the ` +
`current layout-set instead. To use the multi-task mode, you cannot have a layout-set ` +
`set up for the current task.`,
);
}

const { data: pdfSettings, isFetching: pdfFormatIsLoading } = usePdfFormatQuery(true);

if (pdfFormatIsLoading) {
return <BlockPrint />;
}

if (pdfLayoutName) {
// Render all components directly if given a separate PDF layout
return (
return (
<DummyPresentation>
<PdfWrapping>
<PlainPage pageKey={pdfLayoutName} />
<div className={classes.instanceInfo}>
<InstanceInformation
elements={{
dateSent: true,
sender: true,
receiver: true,
referenceNumber: true,
}}
/>
</div>
<AllPages pdfSettings={pdfSettings} />
<AllSubformSummaryComponent2 />
</PdfWrapping>
</DummyPresentation>
);
}

export function PdfForServiceTask() {
const [params] = useSearchParams();
const taskIds = params.getAll(SearchParams.PdfForTask);
if (taskIds.length === 0) {
throw new Error(
`No task ids provided (this mode requires passing one or multiple ${SearchParams.PdfForTask} as a search param)`,
);
}

return <AutoGeneratePdfFromTasks taskIds={taskIds} />;
}

function AutoGeneratePdfFromTasks({ taskIds }: { taskIds: string[] }) {
return (
<DummyPresentation>
<PdfWrapping>
Expand All @@ -61,20 +110,22 @@ export const PDFView2 = () => {
}}
/>
</div>
{order
.filter((pageKey) => !pdfSettings?.excludedPages.includes(pageKey))
.map((pageKey) => (
<PdfForPage
key={pageKey}
pageKey={pageKey}
pdfSettings={pdfSettings}
/>
))}
<AllSubformSummaryComponent2 />
{taskIds.map((taskId, idx) => (
<TaskSummaryWrapper
key={taskId}
taskId={taskId}
>
{idx > 0 && <div className={classes.pageBreak} />}
{/* Settings intentionally omitted, as this is new functionality
and PDF settings are deprecated at this point. */}
<AllPages pdfSettings={undefined} />
<AllSubformSummaryComponent2 />
</TaskSummaryWrapper>
))}
</PdfWrapping>
</DummyPresentation>
);
};
}

function PdfWrapping({ children }: PropsWithChildren) {
const orgLogoEnabled = Boolean(useApplicationMetadata().logoOptions);
Expand Down Expand Up @@ -139,6 +190,24 @@ function PlainPage({ pageKey }: { pageKey: string }) {
);
}

function AllPages({ pdfSettings }: { pdfSettings: IPdfFormat | undefined }) {
const order = usePageOrder();

return (
<>
{order
.filter((pageKey) => !pdfSettings?.excludedPages.includes(pageKey))
.map((pageKey) => (
<PdfForPage
key={pageKey}
pageKey={pageKey}
pdfSettings={pdfSettings}
/>
))}
</>
);
}

function PdfForPage({ pageKey, pdfSettings }: { pageKey: string; pdfSettings: IPdfFormat | undefined }) {
const lookups = useLayoutLookups();
const children = useMemo(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,27 @@ import type { PropsWithChildren } from 'react';
import cn from 'classnames';

import { useDevToolsStore } from 'src/features/devtools/data/DevToolsStore';
import { useGetTaskTypeById } from 'src/features/instance/useProcessQuery';
import { PdfForServiceTask, PdfFromLayout } from 'src/features/pdf/PdfFromLayout';
import classes from 'src/features/pdf/PDFView.module.css';
import { PDFView2 } from 'src/features/pdf/PdfView2';
import { useNavigationParam } from 'src/hooks/navigation';
import { useIsPdf } from 'src/hooks/useIsPdf';
import { ProcessTaskType } from 'src/types';

export const usePdfModeActive = (): boolean => {
const previewPDF = useDevToolsStore((state) => state.pdfPreview);
const pdfIsSetInUrl = useIsPdf();
return pdfIsSetInUrl || previewPDF;
};

export function PDFWrapper({ children }: PropsWithChildren) {
export function PdfWrapper({ children }: PropsWithChildren) {
const previewPDF = useDevToolsStore((state) => state.pdfPreview);
const setPdfPreview = useDevToolsStore((state) => state.actions.setPdfPreview);
const renderInstead = useIsPdf();

const taskId = useNavigationParam('taskId');
const taskType = useGetTaskTypeById()(taskId);

useEffect(() => {
if (previewPDF) {
waitForPrint().then((success) => {
Expand All @@ -32,8 +38,10 @@ export function PDFWrapper({ children }: PropsWithChildren) {
}
}, [previewPDF, setPdfPreview]);

const PdfComponent = taskType === ProcessTaskType.Service ? PdfForServiceTask : PdfFromLayout;

if (renderInstead) {
return <PDFView2 />;
return <PdfComponent />;
}

return (
Expand All @@ -42,7 +50,7 @@ export function PDFWrapper({ children }: PropsWithChildren) {

{previewPDF && (
<div className={classes.onlyInPrint}>
<PDFView2 />
<PdfComponent />
</div>
)}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { screen } from '@testing-library/react';

import { getInstanceDataMock } from 'src/__mocks__/getInstanceDataMock';
import { getPartyWithSubunitMock } from 'src/__mocks__/getPartyMock';
import { Confirm } from 'src/features/processEnd/confirm/containers/Confirm';
import { Confirm } from 'src/features/process/confirm/containers/Confirm';
import { fetchInstanceData } from 'src/queries/queries';
import { renderWithInstanceAndLayout } from 'src/test/renderWithProviders';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useAppName } from 'src/core/texts/appTexts';
import { useApplicationMetadata } from 'src/features/applicationMetadata/ApplicationMetadataProvider';
import { useInstanceDataQuery } from 'src/features/instance/InstanceContext';
import { useInstanceOwnerParty, usePartiesAllowedToInstantiate } from 'src/features/party/PartiesProvider';
import { ConfirmPage } from 'src/features/processEnd/confirm/containers/ConfirmPage';
import { ConfirmPage } from 'src/features/process/confirm/containers/ConfirmPage';

export const Confirm = () => {
const instance = useInstanceDataQuery().data;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { AxiosResponse } from 'axios';
import { getApplicationMetadataMock } from 'src/__mocks__/getApplicationMetadataMock';
import { getInstanceDataMock } from 'src/__mocks__/getInstanceDataMock';
import { getPartyMock, getPartyWithSubunitMock } from 'src/__mocks__/getPartyMock';
import { ConfirmPage, type IConfirmPageProps } from 'src/features/processEnd/confirm/containers/ConfirmPage';
import { ConfirmPage, type IConfirmPageProps } from 'src/features/process/confirm/containers/ConfirmPage';
import { doProcessNext } from 'src/queries/queries';
import { renderWithInstanceAndLayout } from 'src/test/renderWithProviders';
import { IProcess } from 'src/types/shared';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { useProcessNext } from 'src/features/instance/useProcessNext';
import { useIsAuthorized } from 'src/features/instance/useProcessQuery';
import { Lang } from 'src/features/language/Lang';
import { useLanguage } from 'src/features/language/useLanguage';
import { returnConfirmSummaryObject } from 'src/features/processEnd/confirm/helpers/returnConfirmSummaryObject';
import { returnConfirmSummaryObject } from 'src/features/process/confirm/helpers/returnConfirmSummaryObject';
import {
filterOutDataModelRefDataAsPdfAndAppOwnedDataTypes,
getAttachmentsWithDataType,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { staticUseLanguageForTests } from 'src/features/language/useLanguage';
import { returnConfirmSummaryObject } from 'src/features/processEnd/confirm/helpers/returnConfirmSummaryObject';
import { returnConfirmSummaryObject } from 'src/features/process/confirm/helpers/returnConfirmSummaryObject';
import type { IParty } from 'src/types/shared';

const langTools = staticUseLanguageForTests({ language: {} });
Expand Down
5 changes: 5 additions & 0 deletions src/features/process/service/ServiceTask.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.buttons {
margin-top: var(--button-margin-top);
display: flex;
gap: 1rem;
}
Loading
Loading