Skip to content

Commit

Permalink
Merge pull request #4712 from navikt/react-router-7-arrangorflate
Browse files Browse the repository at this point in the history
react router 7 arrangorflate
  • Loading branch information
sndrem authored Dec 3, 2024
2 parents b5ba0c6 + 6f07afb commit 8780fae
Show file tree
Hide file tree
Showing 26 changed files with 209 additions and 1,823 deletions.
29 changes: 15 additions & 14 deletions .github/workflows/cicd-arrangor-flate.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,41 +55,42 @@ jobs:
needs: playwright-version
container:
image: mcr.microsoft.com/playwright:v${{ needs.playwright-version.outputs.version }}-jammy
outputs:
image: ${{ steps.docker-build-push.outputs.image }}
steps:
- uses: actions/checkout@v4
- name: Setup frontend
uses: ./.github/actions/setup-frontend
env:
NODE_AUTH_TOKEN: ${{ secrets.READER_TOKEN }}
- name: Test
run: npx turbo run lint typecheck test playwright --filter=@mr/arrangor-flate
run: npx turbo run lint typecheck playwright --filter=@mr/arrangor-flate

deploy-til-dev:
name: Deploy til dev-gcp
needs: ci
if: github.event_name == 'push' && github.ref_name == 'main' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup frontend
uses: ./.github/actions/setup-frontend
env:
NODE_AUTH_TOKEN: ${{ secrets.READER_TOKEN }}
- name: Bygg applikasjon
run: npx turbo run lint typecheck pack --filter=@mr/arrangor-flate
run: npx turbo run pack --filter=@mr/arrangor-flate
- name: Push docker image to GAR
uses: nais/docker-build-push@v0
id: docker-build-push
if: github.event_name == 'push' && github.ref_name == 'main' || github.event_name == 'workflow_dispatch'
with:
team: team-mulighetsrommet
identity_provider: ${{ secrets.NAIS_WORKLOAD_IDENTITY_PROVIDER }}
project_id: ${{ vars.NAIS_MANAGEMENT_PROJECT_ID }}
docker_context: ./frontend/arrangor-flate
image_suffix: arrangor-flate

deploy-til-dev:
name: Deploy til dev-gcp
needs: ci
if: github.event_name == 'push' && github.ref_name == 'main' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: nais/deploy/actions/deploy@v2
env:
CLUSTER: dev-gcp
RESOURCE: frontend/arrangor-flate/.nais/nais-dev.yaml
VAR: image=${{ needs.ci.outputs.image }}
VAR: image=${{ steps.docker-build-push.outputs.image }}

# TODO Skru på deploy til prod når alt er klart for arrangørflate
# deploy-til-prod:
Expand Down
1 change: 1 addition & 0 deletions frontend/arrangor-flate/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ dist
/playwright-report/
/blob-report/
/playwright/.cache/
.react-router/
2 changes: 1 addition & 1 deletion frontend/arrangor-flate/app/auth/auth.server.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { OpenAPI } from "@mr/api-client";
import { getToken, parseIdportenToken, requestTokenxOboToken, validateToken } from "@navikt/oasis";
import { redirectDocument } from "@remix-run/node";
import { redirectDocument } from "react-router";
import { v4 as uuidv4 } from "uuid";
import { hentMiljø, Miljø } from "../services/miljø";

Expand Down
2 changes: 1 addition & 1 deletion frontend/arrangor-flate/app/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Link } from "@remix-run/react";
import { Link } from "react-router";
import css from "../root.module.css";
import { Arrangorvelger } from "./arrangorvelger/Arrangorvelger";
import { Arrangor } from "@mr/api-client";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Link, LinkProps, useSearchParams } from "@remix-run/react";
import { Link, LinkProps, useSearchParams } from "react-router";
interface Props extends LinkProps {
tabKey?: string;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Select } from "@navikt/ds-react";
import { useNavigate } from "@remix-run/react";
import { useNavigate } from "react-router";
import { useOrgnrFromUrl } from "../../utils";
import { Arrangor } from "@mr/api-client";

Expand Down
4 changes: 2 additions & 2 deletions frontend/arrangor-flate/app/entry.client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
* For more information, see https://remix.run/docs/en/main/file-conventions/entry.client
*/

import { RemixBrowser } from "@remix-run/react";
import { HydratedRouter } from "react-router/dom";
import { startTransition, StrictMode } from "react";
import { hydrateRoot } from "react-dom/client";

startTransition(() => {
hydrateRoot(
document,
<StrictMode>
<RemixBrowser />
<HydratedRouter />
</StrictMode>,
);
});
26 changes: 13 additions & 13 deletions frontend/arrangor-flate/app/entry.server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
* For more information, see https://remix.run/file-conventions/entry.server
*/
import { PassThrough } from "node:stream";
import type { AppLoadContext, EntryContext } from "@remix-run/node";
import { createReadableStreamFromReadable } from "@remix-run/node";
import { RemixServer } from "@remix-run/react";
import type { AppLoadContext, EntryContext } from "react-router";
import { createReadableStreamFromReadable } from "@react-router/node";
import { ServerRouter } from "react-router";
import { isbot } from "isbot";
import { renderToPipeableStream } from "react-dom/server";
import { initializeMockServer } from "./mocks/node";
import { OpenAPI } from "@mr/api-client";
import { v4 as uuidv4 } from "uuid";

const ABORT_DELAY = 5_000;
export const streamTimeout = 5000;

if (process.env.VITE_MULIGHETSROMMET_API_MOCK === "true") {
// eslint-disable-next-line no-console
Expand Down Expand Up @@ -45,27 +45,27 @@ export default function handleRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
remixContext: EntryContext,
reactRouterContext: EntryContext,
// This is ignored so we can keep it in the template for visibility. Feel
// free to delete this parameter in your app if you're not using it!
// eslint-disable-next-line @typescript-eslint/no-unused-vars
loadContext: AppLoadContext,
) {
return isbot(request.headers.get("user-agent") || "")
? handleBotRequest(request, responseStatusCode, responseHeaders, remixContext)
: handleBrowserRequest(request, responseStatusCode, responseHeaders, remixContext);
? handleBotRequest(request, responseStatusCode, responseHeaders, reactRouterContext)
: handleBrowserRequest(request, responseStatusCode, responseHeaders, reactRouterContext);
}

function handleBotRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
remixContext: EntryContext,
reactRouterContext: EntryContext,
) {
return new Promise((resolve, reject) => {
let shellRendered = false;
const { pipe, abort } = renderToPipeableStream(
<RemixServer context={remixContext} url={request.url} abortDelay={ABORT_DELAY} />,
<ServerRouter context={reactRouterContext} url={request.url} />,
{
onAllReady() {
shellRendered = true;
Expand Down Expand Up @@ -99,20 +99,20 @@ function handleBotRequest(
},
);

setTimeout(abort, ABORT_DELAY);
setTimeout(abort, streamTimeout + 1000);
});
}

function handleBrowserRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
remixContext: EntryContext,
reactRouterContext: EntryContext,
) {
return new Promise((resolve, reject) => {
let shellRendered = false;
const { pipe, abort } = renderToPipeableStream(
<RemixServer context={remixContext} url={request.url} abortDelay={ABORT_DELAY} />,
<ServerRouter context={reactRouterContext} url={request.url} />,
{
onShellReady() {
shellRendered = true;
Expand Down Expand Up @@ -146,6 +146,6 @@ function handleBrowserRequest(
},
);

setTimeout(abort, ABORT_DELAY);
setTimeout(abort, streamTimeout + 1000);
});
}
2 changes: 1 addition & 1 deletion frontend/arrangor-flate/app/hooks/useTabState.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useSearchParams } from "@remix-run/react";
import { useSearchParams } from "react-router";
import { useEffect } from "react";
import { Tabs } from "../routes/$orgnr_.refusjonskrav";

Expand Down
9 changes: 4 additions & 5 deletions frontend/arrangor-flate/app/root.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { Arrangor } from "@mr/api-client";
import { BodyShort, Box, Heading } from "@navikt/ds-react";
import { LoaderFunction } from "@remix-run/node";
import { LoaderFunction } from "react-router";
import {
isRouteErrorResponse,
json,
Links,
Meta,
MetaFunction,
Expand All @@ -12,7 +11,7 @@ import {
ScrollRestoration,
useLoaderData,
useRouteError,
} from "@remix-run/react";
} from "react-router";
import parse from "html-react-parser";
import { ReactNode, useEffect } from "react";
import { hentArrangortilgangerForBruker } from "./auth/arrangortilgang.server";
Expand All @@ -30,10 +29,10 @@ export const loader: LoaderFunction = async ({ request }) => {
await checkValidToken(request);
const arrangortilganger = await hentArrangortilgangerForBruker();

return json({
return {
dekorator: await hentSsrDekoratør(),
arrangortilganger,
});
};
};

export type LoaderData = {
Expand Down
3 changes: 3 additions & 0 deletions frontend/arrangor-flate/app/routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { flatRoutes } from "@react-router/fs-routes";

export default flatRoutes();
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import { ApiError, ArrangorflateService, ArrangorflateTilsagn } from "@mr/api-client";
import { isValidationError } from "@mr/frontend-common/utils/utils";
import { Button, Checkbox, ErrorSummary, Heading, TextField, VStack } from "@navikt/ds-react";
import {
Alert,
Button,
Checkbox,
ErrorSummary,
Heading,
TextField,
VStack,
} from "@navikt/ds-react";
import { ActionFunction, json, LoaderFunction, redirect } from "@remix-run/node";
import { Form, useActionData, useLoaderData } from "@remix-run/react";
ActionFunction,
Form,
LoaderFunction,
redirect,
useActionData,
useLoaderData,
} from "react-router";
import { checkValidToken } from "~/auth/auth.server";
import { Definisjon } from "~/components/Definisjon";
import { PageHeader } from "~/components/PageHeader";
Expand All @@ -28,6 +26,10 @@ type BekreftRefusjonskravData = {
tilsagn: ArrangorflateTilsagn[];
};

interface ActionData {
errors?: FormError[];
}

export const loader: LoaderFunction = async ({
request,
params,
Expand Down Expand Up @@ -68,9 +70,9 @@ export const action: ActionFunction = async ({ request }) => {
const kid = formData.get("kid")?.toString();

if (kontonummerError || bekreftelseError) {
return json({
return {
errors: [kontonummerError, bekreftelseError].filter((error) => error !== undefined),
});
};
}

try {
Expand All @@ -94,15 +96,15 @@ export const action: ActionFunction = async ({ request }) => {
// Remix revaliderer loader data ved actions, så når denne feilmeldingen vises skal allerede kravet
// være oppdatert. Det kan hende vi i fremtiden vil vise _hva_ som har endret seg også, men det
// får vi ta senere.
return json({ errors: apiError.body.errors });
return { errors: [apiError.body.errors] };
}
throw e;
}
};

export default function BekreftRefusjonskrav() {
const { krav, tilsagn } = useLoaderData<BekreftRefusjonskravData>();
const data = useActionData<typeof action>();
const data = useActionData<ActionData>();
const orgnr = useOrgnrFromUrl();
return (
<>
Expand All @@ -124,7 +126,7 @@ export default function BekreftRefusjonskrav() {
label="Kontonummer"
hideLabel
size="small"
error={data?.errors?.kontonummer}
error={data?.errors?.find((error) => error.name === "kontonummer")?.message}
name="kontonummer"
className="border border-[#0214317D] rounded-md"
defaultValue={krav.betalingsinformasjon?.kontonummer}
Expand All @@ -147,20 +149,24 @@ export default function BekreftRefusjonskrav() {
</Definisjon>
</dl>
<VStack gap="2" justify={"start"} align={"start"}>
<Checkbox name="bekreftelse" value="bekreftet" error={data?.errors?.bekreftelse}>
<Checkbox
name="bekreftelse"
value="bekreftet"
error={!!data?.errors?.find((error) => error.name === "bekreftelse")?.message}
>
Det erklæres herved at alle opplysninger er gitt i henhold til de faktiske forhold
</Checkbox>
<input type="hidden" name="refusjonskravId" value={krav.id} />
<input type="hidden" name="refusjonskravDigest" value={krav.beregning.digest} />
<input type="hidden" name="orgnr" value={orgnr} />
{data?.errors?.length > 0 && (
{data?.errors && data.errors.length > 0 && (
<ErrorSummary>
{data.errors.map((error: FormError) => {
return <ErrorSummary.Item key={error.name}>{error.message}</ErrorSummary.Item>;
})}
</ErrorSummary>
)}
{data?.error && <Alert variant="error">{data.error}</Alert>}

<Button type="submit">Bekreft og send refusjonskrav</Button>
</VStack>
</Form>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { RefusjonKravDeltakelse, RefusjonKravDeltakelsePerson } from "@mr/api-client";
import { formaterNOK } from "@mr/frontend-common/utils/utils";
import { Button, GuidePanel, HGrid, SortState, Table, VStack } from "@navikt/ds-react";
import type { LoaderFunction, MetaFunction } from "@remix-run/node";
import { Link, useLoaderData } from "@remix-run/react";
import type { LoaderFunction, MetaFunction } from "react-router";
import { Link, useLoaderData } from "react-router";
import { useState } from "react";
import { checkValidToken } from "~/auth/auth.server";
import { Definisjonsliste } from "~/components/Definisjonsliste";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { LoaderFunction } from "@remix-run/node";
import { LoaderFunction } from "react-router";
import { checkValidToken } from "../auth/auth.server";
import { ArrangorflateService } from "@mr/api-client";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { ArrangorflateService, ArrangorflateTilsagn } from "@mr/api-client";
import { formaterKontoNummer } from "@mr/frontend-common/utils/utils";
import { FilePdfIcon } from "@navikt/aksel-icons";
import { Button, VStack } from "@navikt/ds-react";
import { LoaderFunction } from "@remix-run/node";
import { useLoaderData, useParams } from "@remix-run/react";
import { LoaderFunction } from "react-router";
import { useLoaderData, useParams } from "react-router";
import { checkValidToken } from "~/auth/auth.server";
import { Definisjonsliste } from "~/components/Definisjonsliste";
import { PageHeader } from "~/components/PageHeader";
Expand Down
4 changes: 2 additions & 2 deletions frontend/arrangor-flate/app/routes/$orgnr.tilsagn.$id.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ArrangorflateService, ArrangorflateTilsagn } from "@mr/api-client";
import { LoaderFunction } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
import { LoaderFunction } from "react-router";
import { useLoaderData } from "react-router";
import { Definisjonsliste } from "~/components/Definisjonsliste";
import { TilsagnDetaljer } from "~/components/tilsagn/TilsagnDetaljer";
import { checkValidToken } from "../auth/auth.server";
Expand Down
7 changes: 3 additions & 4 deletions frontend/arrangor-flate/app/routes/$orgnr_.refusjonskrav.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { ArrangorflateService, RefusjonKravKompakt, RefusjonskravStatus } from "@mr/api-client";
import { Tabs } from "@navikt/ds-react";
import type { LoaderFunctionArgs, MetaFunction } from "@remix-run/node";
import { json } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
import type { LoaderFunctionArgs, MetaFunction } from "react-router";
import { useLoaderData } from "react-router";
import { RefusjonskravTable } from "~/components/refusjonskrav/RefusjonskravTable";
import { TilsagnTable } from "~/components/tilsagn/TilsagnTable";
import { checkValidToken, setupOpenApi } from "../auth/auth.server";
Expand All @@ -28,7 +27,7 @@ export async function loader({ request, params }: LoaderFunctionArgs) {
const krav = await ArrangorflateService.getAllRefusjonKrav({ orgnr });
const tilsagn = await ArrangorflateService.getAllArrangorflateTilsagn({ orgnr });

return json({ krav, tilsagn });
return { krav, tilsagn };
}

export default function TilsagnDetaljer() {
Expand Down
Loading

0 comments on commit 8780fae

Please sign in to comment.