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

IS-3017: Tydeliggjøre søket #574

Merged
merged 1 commit into from
Jan 29, 2025
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
127 changes: 95 additions & 32 deletions src/sider/sokperson/SokPerson.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import React, { useState } from 'react';
import {
Alert,
BodyShort,
BodyLong,
Box,
Button,
ErrorMessage,
Heading,
HStack,
HelpText,
Label,
TextField,
VStack,
} from '@navikt/ds-react';
Expand All @@ -20,10 +21,39 @@ import * as Amplitude from '@/utils/amplitude';

const texts = {
header: 'Søk etter sykmeldt',
info:
'Her kan du søke opp sykmeldte personer basert på initialer og fødselsdato.',
info: 'Her kan du søke for å finne brukere med aktivt sykefravær.',
label: {
initials: 'Initialer (valgfri)',
birthdate: 'Fødselsdato (obligatorisk)',
},
helpText: {
info: {
title: 'Hvordan søke etter sykmeldt?',
p1:
'Fyll inn fødselsdato for å finne en sykmeldt du har tilgang til, vedkommende må ha et aktivt sykefravær. ',
p2:
'Ønsker man et mer nøyaktig søk kan man legge til initialer til den sykmeldte, men dette er valgfritt. Det er ikke mulig å søke på initialer uten å skrive inn fødselsdato. Dette er for å minimere risiko for feil søkeresultat, og at du finner akkurat den personen du er på leting etter.',
},
initials: {
title: 'Hvordan fyller jeg inn initialer?',
text:
'Her kan du fylle inn initialene til den du vil søke opp. Feltet krever forbokstaven for fornavn og etternavn. Det er mulig å legge til forbokstavene for mellomnavn for mer nøyaktig søkeresultat. ',
},
birthdate: {
title: 'Hvordan fyller jeg inn fødselsdato?',
text: (
<>
Her kan du fylle inn fødselsdato til den du vil søke opp. For å kunne
søke må sifrene fylles inn på formatet:
<strong> dag måned år</strong>, i den rekkefølgen. Ønsker man et mer
nøyaktig søk kan man legge til initialer til den sykmeldte i initial
feltet.
</>
),
},
},
validation: {
initials: 'Vennligst angi gyldige initialer',
initials: 'Vennligst angi to til fire initialer',
birthdate: 'Vennligst angi en gyldig fødselsdato',
},
error: 'Noe gikk galt under søket. Vennligst prøv igjen.',
Expand Down Expand Up @@ -55,6 +85,30 @@ function logSokPersonResults(amount: number, requestDTO: SokDTO) {
});
}

function InitialerLabel() {
return (
<div className="flex gap-2">
{texts.label.initials}
<HelpText title={texts.helpText.initials.title}>
<Label>{texts.helpText.initials.title}</Label>
<BodyLong>{texts.helpText.initials.text}</BodyLong>
</HelpText>
</div>
);
}

function FodselsdatoLabel() {
return (
<div className="flex gap-2">
{texts.label.birthdate}
<HelpText title={texts.helpText.birthdate.title}>
<Label>{texts.helpText.birthdate.title}</Label>
<BodyLong>{texts.helpText.birthdate.text}</BodyLong>
</HelpText>
</div>
);
}

export default function SokPerson() {
const [initials, setInitials] = useState<string>('');
const [birthdate, setBirthdate] = useState<string>('');
Expand All @@ -78,14 +132,15 @@ export default function SokPerson() {
};

const isValidInitials = (initials: string): boolean => {
return initials === '' || (initials.length <= 3 && initials.length > 1);
return initials === '' || (initials.length <= 4 && initials.length > 1);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Er det en juridisk grunn til at vi har begrenset det til ett mellomnavn? Kunne vi evt utvidet til fire initialer?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vet ikke 🤔 Litt usikker på om vi har begrensninger i backend eller om det funker med n antall initialer i backend?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vi har ingen øvre grense i backend, bare at det skal være minst to. Kan ikke se noen grunn til å ikke kunne utvide til fire...

};

const handleSubmit = () => {
const parsedBirthdate = parseBirthdate(birthdate);
const parsedInitials = removePunctuation(initials);
if (isValidInitials(initials) && !!parsedBirthdate) {
const requestDTO: SokDTO = {
initials: initials.toLowerCase(),
initials: parsedInitials.toLowerCase(),
birthdate: parsedBirthdate,
};
mutate(requestDTO, {
Expand All @@ -109,46 +164,54 @@ export default function SokPerson() {
handleSubmit();
}}
>
<Heading level="2" size="medium">
{texts.header}
</Heading>
<div className="flex gap-2 items-center">
<Heading level="2" size="medium">
{texts.header}
</Heading>
<HelpText title={texts.helpText.info.title}>
<Label>{texts.helpText.info.title}</Label>
<BodyLong>{texts.helpText.info.p1}</BodyLong>
<BodyLong className="pt-2">{texts.helpText.info.p2}</BodyLong>
</HelpText>
</div>
<VStack gap="4">
<BodyShort>{texts.info}</BodyShort>
<HStack gap="8" align="end">
<BodyLong>{texts.info}</BodyLong>
<div className="grid grid-cols-[auto,auto,auto] gap-x-8 gap-y-2 align-end max-w-max">
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dette ser kanskje litt voldsomt ut, men det er egt bare for å få error meldingene under det respektive input feltet med grid istedenfor flex.

<TextField
label="Initialer"
description="AB"
label={<FodselsdatoLabel />}
description="ddmmåå"
htmlSize={10}
type="text"
onChange={(e) => setInitials(e.target.value)}
error={isFormError && !isValidInitials(initials)}
onChange={(e) => setBirthdate(e.target.value)}
error={isInvalidBirthdate}
/>
<TextField
label="Fødselsdato"
description="ddmmåå"
htmlSize={14}
label={<InitialerLabel />}
description="Eks: Oline Nordmann blir ON"
htmlSize={6}
type="text"
onChange={(e) => setBirthdate(e.target.value)}
error={isInvalidBirthdate}
onChange={(e) => setInitials(e.target.value)}
error={isFormError && !isValidInitials(initials)}
/>
<Button
loading={isLoading}
icon={<MagnifyingGlassIcon />}
type="submit"
className="self-end max-w-max"
>
Søk
</Button>
</HStack>
{isInvalidInitials && (
<ErrorMessage size="small">
{texts.validation.initials}
</ErrorMessage>
)}
{isInvalidBirthdate && (
<ErrorMessage size="small">
{texts.validation.birthdate}
</ErrorMessage>
)}
{isInvalidBirthdate && (
<ErrorMessage size="small">
{texts.validation.birthdate}
</ErrorMessage>
)}
{isInvalidInitials && (
<ErrorMessage size="small" className="col-start-2 col-end-4">
{texts.validation.initials}
</ErrorMessage>
)}
</div>
{isError && (
<Alert variant="error" size="small">
{texts.error}
Expand Down
39 changes: 27 additions & 12 deletions test/components/SokPersonTest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,21 @@ describe('SokPerson', () => {
.exist;
expect(
screen.getByText(
'Her kan du søke opp sykmeldte personer basert på initialer og fødselsdato.'
'Her kan du søke for å finne brukere med aktivt sykefravær.'
)
).to.exist;
expect(screen.getByRole('textbox', { name: 'Initialer' })).to.exist;
expect(screen.getByRole('textbox', { name: 'Fødselsdato' })).to.exist;
expect(
screen.getByRole('textbox', {
name:
'Initialer (valgfri) Hvordan fyller jeg inn initialer? Hvordan fyller jeg inn initialer?',
})
).to.exist;
expect(
screen.getByRole('textbox', {
name:
'Fødselsdato (obligatorisk) Hvordan fyller jeg inn fødselsdato? Hvordan fyller jeg inn fødselsdato?',
})
).to.exist;
expect(screen.getByRole('button', { name: 'Søk' })).to.exist;
});

Expand All @@ -52,23 +62,26 @@ describe('SokPerson', () => {
await userEvent.click(screen.getByRole('button', { name: 'Søk' }));

expect(screen.getByText('Vennligst angi en gyldig fødselsdato')).to.exist;
expect(screen.queryByText('Vennligst angi gyldige initialer')).to.not.exist;
expect(screen.queryByText('Vennligst angi to til fire initialer')).to.not
.exist;
});
it('should render validation error for initialer when blank and too many characters', async () => {
renderSokPerson();

const initialsInput = screen.getByRole('textbox', { name: 'Initialer' });
const initialsInput = screen.getByRole('textbox', { name: /^Initialer/ });
fireEvent.change(initialsInput, { target: { value: ' ' } });
await userEvent.click(screen.getByRole('button', { name: 'Søk' }));
expect(screen.getByText('Vennligst angi gyldige initialer')).to.exist;
fireEvent.change(initialsInput, { target: { value: 'ABCD' } });
expect(screen.getByText('Vennligst angi gyldige initialer')).to.exist;
expect(screen.getByText('Vennligst angi to til fire initialer')).to.exist;
fireEvent.change(initialsInput, { target: { value: 'ABCDE' } });
expect(screen.getByText('Vennligst angi to til fire initialer')).to.exist;
});
it('should send correct parameters', async () => {
renderSokPerson();

const initialsInput = screen.getByRole('textbox', { name: 'Initialer' });
const birthdateInput = screen.getByRole('textbox', { name: 'Fødselsdato' });
const initialsInput = screen.getByRole('textbox', { name: /^Initialer/ });
const birthdateInput = screen.getByRole('textbox', {
name: /^Fødselsdato/,
});

const initialsValue = 'kk';
const birthdateValue = '101010';
Expand Down Expand Up @@ -104,8 +117,10 @@ describe('SokPerson', () => {
it('should show correct results', async () => {
renderSokPerson();

const initialsInput = screen.getByRole('textbox', { name: 'Initialer' });
const birthdateInput = screen.getByRole('textbox', { name: 'Fødselsdato' });
const initialsInput = screen.getByRole('textbox', { name: /^Initialer/ });
const birthdateInput = screen.getByRole('textbox', {
name: /^Fødselsdato/,
});

const initialsValue = 'kh';
const birthdateValue = '101010';
Expand Down