Skip to content

Commit

Permalink
VKT(Frontend): Clerk examiner listing
Browse files Browse the repository at this point in the history
  • Loading branch information
pkoivisto committed Nov 7, 2024
1 parent 5ee0bd4 commit bd5db38
Show file tree
Hide file tree
Showing 8 changed files with 217 additions and 31 deletions.
13 changes: 13 additions & 0 deletions frontend/packages/vkt/public/i18n/fi-FI/clerk.json
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,19 @@
"copyToClipboardFailed": "Kopiointi leikepöydälle epäonnistui"
}
},
"clerkExaminerListing": {
"buttons": {
"viewDetails": "Katso tiedot"
},
"header": {
"actions": "Toiminnot",
"examDates": "Tutkintopäivät",
"examLocation": "Tutkintopaikka",
"examiner": "Tutkinnon vastaanottaja",
"language": "Kieli"
},
"title": "Tutkinnon vastaanottajan tiedot"
},
"header": {
"backToOph": "Takaisin Opintopolkuun",
"logOut": "Kirjaudu ulos",
Expand Down
5 changes: 4 additions & 1 deletion frontend/packages/vkt/public/i18n/fi-FI/examiner.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
"personalDetails": {
"heading": "Henkilötiedot",
"information": "Tiedoista vain nimet näkyvät julkisessa listauksessa."
},
"successToast": {
"description": "Tietojen päivittäminen onnistui!"
}
},
"examinerHomepage": {
Expand All @@ -49,7 +52,7 @@
"labels": {
"examiner": "Tutkinnon vastaanottaja",
"examDates": "Tutkintopäivät",
"examPlaces": "Tutkintopaikat",
"examLocations": "Tutkintopaikat",
"full": "Täynnä",
"languages": "Kielet",
"modify": "Muokkaa tietoja",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import {
Divider,
SelectChangeEvent,
TableCell,
TableHead,
TableRow,
} from '@mui/material';
import { Link } from 'react-router-dom';
import { CustomButtonLink, CustomTable, H2, Text } from 'shared/components';
import { Color, Variant } from 'shared/enums';

import { LanguageFilter } from 'components/common/LanguageFilter';
import {
useClerkTranslation,
useCommonTranslation,
useKoodistoMunicipalitiesTranslation,
} from 'configs/i18n';
import { useAppDispatch, useAppSelector } from 'configs/redux';
import { AppRoutes, ExamLanguage } from 'enums/app';
import { ExaminerDetails } from 'interfaces/examinerDetails';
import { setExamEventLanguageFilter } from 'redux/reducers/clerkListExamEvent';
import { clerkListExamEventsSelector } from 'redux/selectors/clerkListExamEvent';
import { clerkListExaminerSelector } from 'redux/selectors/clerkListExaminer';
import { ExaminerUtils } from 'utils/examiner';

export const ClerkExaminerListingHeader = () => {
const { t } = useClerkTranslation({
keyPrefix: 'vkt.component.clerkExaminerListing.header',
});

return (
<TableHead className="heading-text">
<TableRow>
<TableCell>{t('examiner')}</TableCell>
<TableCell>{t('language')}</TableCell>
<TableCell>{t('examLocation')}</TableCell>
<TableCell>{t('examDates')}</TableCell>
<TableCell>{t('actions')}</TableCell>
<TableCell />
</TableRow>
</TableHead>
);
};

const ExaminerListingRow = ({ examiner }: { examiner: ExaminerDetails }) => {
const { t } = useClerkTranslation({
keyPrefix: 'vkt.component.clerkExaminerListing',
});
const translateCommon = useCommonTranslation();
const translateMunicipality = useKoodistoMunicipalitiesTranslation();

const examinerUrl = AppRoutes.ExaminerDetailsPage.replace(
/:oid/,
`${examiner.oid}`,
);

return (
<>
<TableRow
className="clerk-exam-event-listing__row"
data-testid={`clerk-examiners__id-${examiner.id}-row`}
>
<TableCell>
<Link
className="clerk-exam-event-listing__row__link"
to={examinerUrl}
>
<Text>{`${examiner.firstName} ${examiner.lastName}`}</Text>
</Link>
</TableCell>
<TableCell>
<Text>
{ExaminerUtils.renderExamLanguages(examiner, translateCommon)}
</Text>
</TableCell>
<TableCell>
<Text>
{ExaminerUtils.renderExamLocations(examiner, translateMunicipality)}
</Text>
</TableCell>
<TableCell>
<Text>TODO Ei määritelty?</Text>
</TableCell>
<TableCell>
<CustomButtonLink
variant={Variant.Outlined}
color={Color.Secondary}
to={examinerUrl}
>
{t('buttons.viewDetails')}
</CustomButtonLink>
</TableCell>
</TableRow>
</>
);
};

const getRowDetails = (examiner: ExaminerDetails) => {
return <ExaminerListingRow examiner={examiner} />;
};

export const ClerkExaminerListing = () => {
const { t } = useClerkTranslation({
keyPrefix: 'vkt.component.clerkExaminerListing',
});
const dispatch = useAppDispatch();

const { languageFilter } = useAppSelector(clerkListExamEventsSelector);

const handleLanguageFilterChange = (event: SelectChangeEvent) => {
dispatch(setExamEventLanguageFilter(event.target.value as ExamLanguage));
};

const { examiners } = useAppSelector(clerkListExaminerSelector);

return (
<>
<div className="clerk-homepage__grid-container__heading columns grow">
<H2>{t('title')}</H2>
</div>
<Divider />
<LanguageFilter
value={languageFilter}
onChange={handleLanguageFilterChange}
/>
<CustomTable
className="table-layout-auto"
data={examiners}
header={<ClerkExaminerListingHeader />}
getRowDetails={getRowDetails}
stickyHeader
/>
</>
);
};
2 changes: 1 addition & 1 deletion frontend/packages/vkt/src/enums/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export enum AppRoutes {
PublicEnrollmentDone = excellentLevelEnrollmentRoute + '/:examEventId/valmis',
// Routes for good and satisfactory level - TODO
PublicGoodAndSatisfactoryLevelLanding = '/vkt/hyva-ja-tyydyttava-taito',
ClerkRoot = '/vkt/virkailija/',
ClerkRoot = '/vkt/virkailija',
// Routes for clerk user / excellent level
ClerkExcellentLevelPage = clerkExcellentLevelRoutePrefix,
ClerkExamEventCreatePage = clerkExcellentLevelRoutePrefix +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { H1 } from 'shared/components';
import { APIResponseStatus } from 'shared/enums';

import { ClerkExamEventListing } from 'components/clerkExamEvent/listing/ClerkExamEventListing';
import { ClerkExaminerListing } from 'components/clerkExaminer/ClerkExaminerListing';
import { PublicExamEventGridSkeleton } from 'components/skeletons/PublicExamEventGridSkeleton';
import { useClerkTranslation } from 'configs/i18n';
import { useAppDispatch, useAppSelector } from 'configs/redux';
Expand All @@ -20,18 +21,21 @@ export const ClerkGoodAndSatisfactoryLevelPage: FC = () => {
});

const dispatch = useAppDispatch();
const { status } = useAppSelector(clerkListExamEventsSelector);
const { status: examEventsStatus } = useAppSelector(
clerkListExamEventsSelector,
);
const { status: examinerListStatus } = useAppSelector(
clerkListExaminerSelector,
);

const examinersLoading = examinerListStatus === APIResponseStatus.InProgress;
const examEventsLoading = examEventsStatus === APIResponseStatus.InProgress;

useEffect(() => {
if (status === APIResponseStatus.NotStarted) {
if (examEventsStatus === APIResponseStatus.NotStarted) {
dispatch(loadExamEvents());
}
}, [dispatch, status]);
}, [dispatch, examEventsStatus]);
useEffect(() => {
if (examinerListStatus === APIResponseStatus.NotStarted) {
dispatch(loadExaminers());
Expand Down Expand Up @@ -64,6 +68,11 @@ export const ClerkGoodAndSatisfactoryLevelPage: FC = () => {
<Paper elevation={3} className="clerk-homepage__examiners">
{examinersLoading ? (
<PublicExamEventGridSkeleton />
) : (
<ClerkExaminerListing />
)}
{examEventsLoading ? (
<PublicExamEventGridSkeleton />
) : (
<ClerkExamEventListing examEvents={[]} />
)}
Expand Down
25 changes: 16 additions & 9 deletions frontend/packages/vkt/src/pages/examiner/ExaminerDetailsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import {
import { useNavigate } from 'react-router-dom';
import {
CustomButton,
CustomButtonLink,
CustomSwitch,
H1,
H2,
Expand Down Expand Up @@ -278,6 +277,7 @@ const ControlButtons = ({
const dispatch = useAppDispatch();
const { status } = useAppSelector(examinerDetailsUpsertSelector);
const knownExaminerDetails = useExaminerDetails();
const navigate = useNavigate();

const onSave = () => {
if (hasErrors) {
Expand Down Expand Up @@ -309,23 +309,30 @@ const ControlButtons = ({
}
};

const onCancel = () => {
if (window.history.length > 1) {
navigate(-1);
} else if (examinerDetailsInitialized) {
navigate(
AppRoutes.ExaminerHomePage.replace(/:oid/, knownExaminerDetails.oid),
);
}
};

const isLoading = status === APIResponseStatus.InProgress;
const examinerDetailsInitialized =
knownExaminerDetails && isExaminerDetails(knownExaminerDetails);

return (
<div className="columns gapped-xl flex-end">
{examinerDetailsInitialized && (
<CustomButtonLink
<CustomButton
color={Color.Secondary}
disabled={status === APIResponseStatus.InProgress}
to={AppRoutes.ExaminerHomePage.replace(
/:oid/,
knownExaminerDetails.oid,
)}
onClick={onCancel}
>
{translateCommon('cancel')}
</CustomButtonLink>
</CustomButton>
)}
<LoadingProgressIndicator isLoading={isLoading}>
<CustomButton
Expand Down Expand Up @@ -523,12 +530,12 @@ export const ExaminerDetailsPage = () => {
if (oid && examinerDetailsUpsertStatus === APIResponseStatus.Success) {
showToast({
severity: Severity.Success,
description: 'Tietojen päivittäminen onnistui!',
description: t('successToast.description'),
timeOut: Duration.MediumExtra,
});
navigate(AppRoutes.ExaminerHomePage.replace(/:oid/, oid));
}
}, [examinerDetailsUpsertStatus, navigate, oid, showToast]);
}, [examinerDetailsUpsertStatus, navigate, oid, showToast, t]);

// TODO Perhaps navigation protection if dirty fields?
return (
Expand Down
22 changes: 5 additions & 17 deletions frontend/packages/vkt/src/pages/examiner/ExaminerHomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ import {
useKoodistoMunicipalitiesTranslation,
} from 'configs/i18n';
import { useAppDispatch, useAppSelector } from 'configs/redux';
import { AppRoutes, ExamLanguage } from 'enums/app';
import { AppRoutes } from 'enums/app';
import { PublicExaminerExamDate } from 'interfaces/publicExaminer';
import { loadExaminerDetails } from 'redux/reducers/examinerDetails';
import { clerkUserSelector } from 'redux/selectors/clerkUser';
import { examinerDetailsSelector } from 'redux/selectors/examinerDetails';
import { ExaminerUtils } from 'utils/examiner';

const PublicInformation = () => {
const { t } = useExaminerTranslation({
Expand All @@ -29,14 +30,6 @@ const PublicInformation = () => {
return <></>;
}

const examLanguages: Array<ExamLanguage> = examiner.examLanguageFinnish
? examiner.examLanguageSwedish
? [ExamLanguage.FI, ExamLanguage.SV]
: [ExamLanguage.FI]
: examiner.examLanguageSwedish
? [ExamLanguage.SV]
: [];

const examDates: Array<PublicExaminerExamDate> = [
{ examDate: dayjs('2024-10-10'), isFull: false },
{ examDate: dayjs('2024-10-12'), isFull: true },
Expand Down Expand Up @@ -66,17 +59,12 @@ const PublicInformation = () => {
<Text>
<b>{t('labels.languages')}</b>
<br />
{examLanguages
.map((v) => translateCommon(`examLanguage.${v}`))
.join(' & ')}
{ExaminerUtils.renderExamLanguages(examiner, translateCommon)}
</Text>
<Text>
<b>{t('labels.examPlaces')}</b>
<b>{t('labels.examLocations')}</b>
<br />
{examiner.municipalities
.map(({ code }) => translateMunicipality(code))
.sort((a, b) => a.localeCompare(b, 'fi-FI'))
.join(', ')}
{ExaminerUtils.renderExamLocations(examiner, translateMunicipality)}
</Text>
<Text>
<b>{t('labels.examDates')}</b>
Expand Down
31 changes: 31 additions & 0 deletions frontend/packages/vkt/src/utils/examiner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { ExamLanguage } from 'enums/app';
import { ExaminerDetails } from 'interfaces/examinerDetails';

export class ExaminerUtils {
static renderExamLanguages(
examiner: ExaminerDetails,
translateCommon: (k: string) => string,
) {
const examLanguages: Array<ExamLanguage> = examiner.examLanguageFinnish
? examiner.examLanguageSwedish
? [ExamLanguage.FI, ExamLanguage.SV]
: [ExamLanguage.FI]
: examiner.examLanguageSwedish
? [ExamLanguage.SV]
: [];

return examLanguages
.map((v) => translateCommon(`examLanguage.${v}`))
.join(' & ');
}

static renderExamLocations(
examiner: ExaminerDetails,
translateMunicipality: (m: string) => string,
) {
return examiner.municipalities
.map(({ code }) => translateMunicipality(code))
.sort((a, b) => a.localeCompare(b, 'fi-FI'))
.join(', ');
}
}

0 comments on commit bd5db38

Please sign in to comment.