Skip to content

Commit

Permalink
Add task list for merkantil on admin page
Browse files Browse the repository at this point in the history
  • Loading branch information
cskrov committed Nov 8, 2024
1 parent eb54e21 commit e60c920
Show file tree
Hide file tree
Showing 4 changed files with 227 additions and 10 deletions.
2 changes: 1 addition & 1 deletion frontend/src/components/admin/admin-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const AdminButton = ({ children, isLoading, isSuccess, isUninitialized, o
<Button
type="button"
variant="primary"
size="medium"
size="small"
onClick={onClick}
loading={isLoading}
disabled={isLoading}
Expand Down
20 changes: 13 additions & 7 deletions frontend/src/components/admin/admin.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
import { MerkantilTaskList } from '@app/components/admin/merkantil-task-list';
import {
useRecreateElasticAdminMutation,
useRefillElasticAdminMutation,
useResendDvhMutation,
} from '@app/redux-api/internal';
import { HStack, Heading } from '@navikt/ds-react';
import { styled } from 'styled-components';
import { ApiButton } from './api-button';

export const Admin = () => (
<StyledPageContent>
<h1>Administrasjon</h1>
<ApiButton useApi={useRecreateElasticAdminMutation}>KABAL-SEARCH OPENSEARCH RECREATE</ApiButton>
<ApiButton useApi={useRefillElasticAdminMutation}>KABAL-API KAFKA REFILL</ApiButton>
<ApiButton useApi={useResendDvhMutation}>KABAL-API DVH RESEND</ApiButton>
<Heading level="1" size="large">
Administrasjon
</Heading>

<HStack gap="4">
<ApiButton useApi={useRecreateElasticAdminMutation}>KABAL-SEARCH OPENSEARCH RECREATE</ApiButton>
<ApiButton useApi={useRefillElasticAdminMutation}>KABAL-API KAFKA REFILL</ApiButton>
<ApiButton useApi={useResendDvhMutation}>KABAL-API DVH RESEND</ApiButton>
</HStack>

<MerkantilTaskList />
</StyledPageContent>
);

const StyledPageContent = styled.article`
display: flex;
flex-direction: column;
gap: var(--a-spacing-4);
max-width: 400px;
width: 100%;
margin-left: auto;
margin-right: auto;
`;
191 changes: 191 additions & 0 deletions frontend/src/components/admin/merkantil-task-list.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
import { Type } from '@app/components/type/type';
import { isoDateTimeToPretty } from '@app/domain/date';
import { ENVIRONMENT } from '@app/environment';
import { type Task, useGetMerkantilTasksQuery } from '@app/redux-api/internal';
import { SaksTypeEnum } from '@app/types/kodeverk';
import { ArrowsCirclepathIcon, ExternalLinkIcon } from '@navikt/aksel-icons';
import { Alert, Button, CopyButton, HStack, Heading, Skeleton, Table, Tooltip, VStack } from '@navikt/ds-react';
import { Link } from 'react-router-dom';
import { styled } from 'styled-components';

export const MerkantilTaskList = () => {
const { isLoading, isFetching, refetch } = useGetMerkantilTasksQuery();

return (
<section>
<Heading level="1" size="medium" spacing>
<HStack>
<span>Merkantile oppgaver</span>
<Tooltip content="Oppdater">
<Button
onClick={refetch}
loading={isLoading || isFetching}
size="small"
variant="tertiary-neutral"
icon={<ArrowsCirclepathIcon aria-hidden />}
/>
</Tooltip>
</HStack>
</Heading>

<TaskList />
</section>
);
};

const TaskList = () => {
const { data: tasks = [], isLoading, isError, error } = useGetMerkantilTasksQuery();

if (isError) {
return (
<VStack gap="4">
<HStack gap="4">
<Alert variant="error" size="small">
<Heading level="2" size="small" spacing>
Noe gikk galt
</Heading>
<Code>{JSON.stringify(error, null, 2)}</Code>
</Alert>
</HStack>
</VStack>
);
}

if (isLoading) {
return (
<VStack gap="4">
<HStack gap="4">
<Skeleton variant="rounded" height={32} width={120} />
<Skeleton variant="rounded" height={32} width={200} />
</HStack>

<VStack>
<SkeletonRow height={32} />
<SkeletonRow height={48} />
<SkeletonRow height={48} />
<SkeletonRow height={48} />
<SkeletonRow height={48} />
<SkeletonRow height={48} />
<SkeletonRow height={48} />
<SkeletonRow height={48} />
<SkeletonRow height={48} />
<SkeletonRow height={48} />
</VStack>
</VStack>
);
}

return (
<VStack gap="4">
<HStack gap="4">
<CopyButton size="small" copyText={tasks.map(toCopyLine).join('\n')} text="Kopier alle" variant="action" />
<CopyButton
size="small"
copyText={tasks
.filter(({ dateHandled }) => dateHandled === null)
.map(toCopyLine)
.join('\n')}
text="Kopier alle uhåndterte"
variant="action"
/>
</HStack>
<Table zebraStripes size="small">
<Table.Header>
<Table.Row>
<NoWrapTableHeaderCell>Opprettet</NoWrapTableHeaderCell>
<NoWrapTableHeaderCell>Type</NoWrapTableHeaderCell>
<NoWrapTableHeaderCell>Behandling ID</NoWrapTableHeaderCell>
<NoWrapTableHeaderCell>Årsak</NoWrapTableHeaderCell>
<NoWrapTableHeaderCell>Behandlet dato</NoWrapTableHeaderCell>
<NoWrapTableHeaderCell>Behandlet av</NoWrapTableHeaderCell>
<NoWrapTableHeaderCell>Behandlet av navn</NoWrapTableHeaderCell>
<NoWrapTableHeaderCell>Kommentar</NoWrapTableHeaderCell>
<NoWrapTableHeaderCell />
</Table.Row>
</Table.Header>
<Table.Body>
{tasks.map(
({ id, created, typeId, behandlingId, reason, dateHandled, handledBy, handledByName, comment }) => (
<Table.Row key={id}>
<Table.DataCell>{isoDateTimeToPretty(created)}</Table.DataCell>
<Table.DataCell>
<Type type={typeId} />
</Table.DataCell>
<Table.DataCell>
<CopyButton size="small" copyText={behandlingId} text={behandlingId} />
</Table.DataCell>
<Table.DataCell>{reason}</Table.DataCell>
<Table.DataCell>{isoDateTimeToPretty(dateHandled)}</Table.DataCell>
<Table.DataCell>{handledBy}</Table.DataCell>
<Table.DataCell>{handledByName}</Table.DataCell>
<Table.DataCell>{comment}</Table.DataCell>
<Table.DataCell>
<Button
as={Link}
to={getPath(behandlingId, typeId)}
variant="primary"
size="small"
target="_blank"
icon={<ExternalLinkIcon aria-hidden />}
>
Åpne
</Button>
</Table.DataCell>
</Table.Row>
),
)}
</Table.Body>
<StyledTableFooter>
<Table.Row>
<Table.DataCell colSpan={999}>Totalt {tasks.length} oppgaver</Table.DataCell>
</Table.Row>
</StyledTableFooter>
</Table>
</VStack>
);
};

const SkeletonRow = ({ height }: { height: number }) => (
<HStack gap="2" wrap={false}>
<Skeleton variant="text" height={height} width={162} />
<Skeleton variant="text" height={height} width={62} />
<Skeleton variant="text" height={height} width={352} />
<Skeleton variant="text" height={height} width={620} />
<Skeleton variant="text" height={height} width={132} />
<Skeleton variant="text" height={height} width={116} />
<Skeleton variant="text" height={height} width={158} />
<Skeleton variant="text" height={height} width={104} />
<Skeleton variant="text" height={height} width={105} />
</HStack>
);
const DOMAIN = ENVIRONMENT.isProduction ? 'https://kabal.intern.nav.no' : 'https://kabal.intern.dev.nav.no';

const TYPE_TO_PATH: Record<SaksTypeEnum, string> = {
[SaksTypeEnum.KLAGE]: 'klagebehandling',
[SaksTypeEnum.ANKE]: 'ankebehandling',
[SaksTypeEnum.ANKE_I_TRYGDERETTEN]: 'trygderettsankebehandling',
[SaksTypeEnum.BEHANDLING_ETTER_TR_OPPHEVET]: 'behandling-etter-tr-opphevet',
};

const toCopyLine = ({ typeId, behandlingId, reason }: Task) => `${getUrl(behandlingId, typeId)} - ${reason}`;

type UrlFn = (id: string, typeId: SaksTypeEnum) => string;

const getUrl: UrlFn = (...args) => `${DOMAIN}${getPath(...args)}`;
const getPath: UrlFn = (id, typeId) => `/${TYPE_TO_PATH[typeId]}/${id}`;

const NoWrapTableHeaderCell = styled(Table.HeaderCell)`
white-space: nowrap;
`;

const StyledTableFooter = styled.tfoot`
font-style: italic;
`;

const Code = styled.code`
display: block;
white-space: pre-wrap;
padding: var(--a-spacing-4);
border-radius: var(--a-border-radius-medium);
background-color: var(--a-surface-neutral-subtle);
`;
24 changes: 22 additions & 2 deletions frontend/src/redux-api/internal.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
import type { SaksTypeEnum } from '@app/types/kodeverk';
import { createApi } from '@reduxjs/toolkit/query/react';
import { KABAL_INTERNAL_BASE_QUERY } from './common';

export interface Task {
id: string;
created: string;
typeId: SaksTypeEnum;
behandlingId: string;
reason: string;
dateHandled: string | null;
handledBy: string | null;
handledByName: string | null;
comment: string | null;
}

export const kabalInternalApi = createApi({
reducerPath: 'kabalInternalApi',
baseQuery: KABAL_INTERNAL_BASE_QUERY,
Expand All @@ -23,8 +36,15 @@ export const kabalInternalApi = createApi({
method: 'POST',
}),
}),
getMerkantilTasks: builder.query<Task[], void>({
query: () => '/kabal-api/internal/merkantil-tasks',
}),
}),
});

export const { useRefillElasticAdminMutation, useResendDvhMutation, useRecreateElasticAdminMutation } =
kabalInternalApi;
export const {
useRefillElasticAdminMutation,
useResendDvhMutation,
useRecreateElasticAdminMutation,
useGetMerkantilTasksQuery,
} = kabalInternalApi;

0 comments on commit e60c920

Please sign in to comment.