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

react router 7 arrangorflate #4712

Merged
merged 7 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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
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
Loading