Skip to content

Commit

Permalink
Merge pull request #644 from Opetushallitus/feature/OPHKIOS-19
Browse files Browse the repository at this point in the history
YKI(Frontend): OPHKIOS-19: Tutkintolistauksen tietojen päivitys
  • Loading branch information
pkoivisto authored Mar 4, 2024
2 parents b70e2b7 + 9f98986 commit 601a3ba
Show file tree
Hide file tree
Showing 11 changed files with 93 additions and 64 deletions.
6 changes: 3 additions & 3 deletions frontend/packages/yki/public/i18n/en-GB/public.json
Original file line number Diff line number Diff line change
Expand Up @@ -451,17 +451,17 @@
},
"filters": {
"buttons": {
"showResults": "Show results ({{count}})"
"search": "Search"
},
"errorDialog": {
"description": "Select first the language and level. Click on the SHOW RESULTS button.",
"description": "Select first the language and level. Click on the SEARCH button.",
"title": "Select the language and level"
},
"errors": {
"required": "Selection is required"
},
"heading": "Search for tests",
"information": "Search for a suitable YKI test by selecting the language and level. Click on the SHOW RESULTS button to see the results.",
"information": "Search for a suitable YKI test by selecting the language and level. Click on the SEARCH button to see the results.",
"selectExamDetails": {
"prompt": "Choose test",
"required": "(required)"
Expand Down
6 changes: 3 additions & 3 deletions frontend/packages/yki/public/i18n/fi-FI/public.json
Original file line number Diff line number Diff line change
Expand Up @@ -451,17 +451,17 @@
},
"filters": {
"buttons": {
"showResults": "Näytä tulokset ({{count}})"
"search": "Hae"
},
"errorDialog": {
"description": "Valitse ensin tutkinnon kieli ja taso. Paina sen jälkeen uudestaan NÄYTÄ TULOKSET -painiketta.",
"description": "Valitse ensin tutkinnon kieli ja taso. Paina sen jälkeen uudestaan HAE -painiketta.",
"title": "Valitse tutkinnon kieli ja taso"
},
"errors": {
"required": "Valinta on pakollinen"
},
"heading": "Etsi yleisiä kielitutkintoja (YKI)",
"information": "Hae tästä sopivaa YKI-testiä. Valitse kieli ja taso. Paina NÄYTÄ TULOKSET -painiketta.",
"information": "Hae tästä sopivaa YKI-testiä. Valitse kieli ja taso. Paina HAE -painiketta.",
"selectExamDetails": {
"prompt": "Valitse tutkinto",
"required": "(pakollinen)"
Expand Down
6 changes: 3 additions & 3 deletions frontend/packages/yki/public/i18n/sv-SE/public.json
Original file line number Diff line number Diff line change
Expand Up @@ -451,17 +451,17 @@
},
"filters": {
"buttons": {
"showResults": "Visa resultat ({{count}})"
"search": "Sök"
},
"errorDialog": {
"description": "Välj först testets språk och nivå. Tryck på VISA RESULTAT-knappen.",
"description": "Välj först testets språk och nivå. Tryck på SÖK-knappen.",
"title": "Välj språk och nivå"
},
"errors": {
"required": "Obligatoriskt att välja"
},
"heading": "Sök allmänna språkexamina (YKI)",
"information": "Sök här för att hitta ett lämpligt YKI-test. Välj språk och nivå. Tryck på VISA RESULTAT-knappen.",
"information": "Sök här för att hitta ett lämpligt YKI-test. Välj språk och nivå. Tryck på SÖK-knappen.",
"selectExamDetails": {
"prompt": "Välj examen",
"required": "(obligatorisk)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,18 +120,17 @@ export const PublicExamSessionListing = ({
keyPrefix: 'yki.pages.registrationPage.examSessionListing',
});
const translateCommon = useCommonTranslation();
const { isPhone } = useWindowProperties();
const { status } = useAppSelector(examSessionsSelector);

const listingHeaderRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (isPhone) {
if (status === APIResponseStatus.Success) {
listingHeaderRef.current?.scrollIntoView({
behavior: 'smooth',
inline: 'nearest',
});
}
}, [isPhone]);
}, [status]);

switch (status) {
case APIResponseStatus.NotStarted:
Expand Down Expand Up @@ -162,6 +161,7 @@ export const PublicExamSessionListing = ({
count: examSessions.length,
},
)}
aria-live="assertive"
>
{translateCommon('component.table.header.searchResults', {
count: examSessions.length,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,24 @@ import {
ComboBox,
CustomButton,
LanguageSelect,
LoadingProgressIndicator,
Text,
} from 'shared/components';
import { Color, Severity, TextFieldVariant, Variant } from 'shared/enums';
import {
APIResponseStatus,
Color,
Severity,
TextFieldVariant,
Variant,
} from 'shared/enums';
import { useDialog } from 'shared/hooks';

import { useCommonTranslation, usePublicTranslation } from 'configs/i18n';
import { useAppDispatch, useAppSelector } from 'configs/redux';
import { ExamLanguage, ExamLevel } from 'enums/app';
import { ExamSessionFilters } from 'interfaces/examSessions';
import { setPublicExamSessionFilters } from 'redux/reducers/examSessions';
import {
examSessionsSelector,
selectFilteredPublicExamSessions,
} from 'redux/selectors/examSessions';
import { examSessionsSelector } from 'redux/selectors/examSessions';

const municipalityToComboBoxOption = (m: string) => ({
value: m,
Expand Down Expand Up @@ -200,9 +204,10 @@ export const PublicExamSessionFilters = ({

const { showDialog } = useDialog();

const filteredExamSessions = useAppSelector(selectFilteredPublicExamSessions);
const { language, level, excludeFullSessions, excludeNonOpenSessions } =
useAppSelector(examSessionsSelector).filters;
const { status } = useAppSelector(examSessionsSelector);
const isLoading = status === APIResponseStatus.InProgress;

const dispatch = useAppDispatch();
const onFilterChange = (filter: Partial<ExamSessionFilters>) => {
Expand Down Expand Up @@ -285,18 +290,21 @@ export const PublicExamSessionFilters = ({
</FormControl>
</Box>
<div className="public-exam-session-filters__btn-box">
<CustomButton
disabled={false}
data-testid="public-exam-session-filters__filter__search-btn"
color={Color.Secondary}
variant={Variant.Contained}
onClick={handleSubmitBtnClick}
startIcon={<SearchIcon />}
<LoadingProgressIndicator
isLoading={isLoading}
translateCommon={translateCommon}
>
{`${t('filters.buttons.showResults', {
count: filteredExamSessions.length,
})}`}
</CustomButton>
<CustomButton
disabled={isLoading}
data-testid="public-exam-session-filters__filter__search-btn"
color={Color.Secondary}
variant={Variant.Contained}
onClick={handleSubmitBtnClick}
startIcon={<SearchIcon />}
>
{t('filters.buttons.search')}
</CustomButton>
</LoadingProgressIndicator>
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { TableCell, TableRow, Typography } from '@mui/material';
import dayjs, { Dayjs } from 'dayjs';
import { Dayjs } from 'dayjs';
import { ReactNode } from 'react';
import { CustomButtonLink, Text } from 'shared/components';
import { Color, Variant } from 'shared/enums';
Expand Down Expand Up @@ -61,21 +61,22 @@ const RegistrationUnavailableText = ({
const { t } = usePublicTranslation({
keyPrefix: 'yki.component.registration.registrationUnavailable',
});
const now = dayjs();
const { start, end } =
const { start } =
ExamSessionUtils.getEffectiveRegistrationPeriodDetails(examSession);
if (now.isBefore(start)) {
return (
<>
{t('admissionOpensOn', {
startDate: DateUtils.formatOptionalDate(start),
})}
</>
);
} else if (now.isAfter(end)) {
return <>{t('admissionPeriodIsClosed')}</>;
} else {
if (examSession.open) {
return <>{t('examSessionIsFull')}</>;
} else {
if (examSession.upcoming_admission || examSession.upcoming_post_admission) {
return (
<>
{t('admissionOpensOn', {
startDate: DateUtils.formatOptionalDate(start),
})}
</>
);
} else {
return <>{t('admissionPeriodIsClosed')}</>;
}
}
};

Expand Down
13 changes: 8 additions & 5 deletions frontend/packages/yki/src/pages/RegistrationPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ export const RegistrationPage: FC = () => {
});

const dispatch = useAppDispatch();
const { status, exam_sessions } = useAppSelector(examSessionsSelector);
const { status } = useAppSelector(examSessionsSelector);
const [results, setResults] = useState<Array<ExamSession>>([]);
const [updateResults, setUpdateResults] = useState(false);
const [showResults, setShowResults] = useState(false);
const filteredExamSessions = useAppSelector(selectFilteredPublicExamSessions);
const onApplyFilters = () => {
setResults(filteredExamSessions);
dispatch(loadExamSessions());
setUpdateResults(true);
setShowResults(true);
setPage(0);
};
Expand All @@ -39,10 +41,11 @@ export const RegistrationPage: FC = () => {
useEffect(() => {
if (status === APIResponseStatus.NotStarted) {
dispatch(loadExamSessions());
} else if (status === APIResponseStatus.Success) {
setResults(exam_sessions);
} else if (status === APIResponseStatus.Success && updateResults) {
setResults(filteredExamSessions);
setUpdateResults(false);
}
}, [dispatch, status, exam_sessions]);
}, [dispatch, updateResults, status, filteredExamSessions]);

return (
<Box className="public-registration-page">
Expand Down
4 changes: 0 additions & 4 deletions frontend/packages/yki/src/redux/sagas/examSession.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { call, put, takeLatest } from '@redux-saga/core/effects';
import { PayloadAction } from '@reduxjs/toolkit';
import { AxiosResponse } from 'axios';
import dayjs from 'dayjs';

import axiosInstance from 'configs/axios';
import { translateOutsideComponent } from 'configs/i18n';
Expand All @@ -26,12 +25,9 @@ import { SerializationUtils } from 'utils/serialization';
function* loadExamSessionsSaga() {
const t = translateOutsideComponent();
try {
// TODO Allow passing desired date through redux actions?
const from = dayjs().format('YYYY-MM-DD');
const response: AxiosResponse<ExamSessionsResponse> = yield call(
axiosInstance.get,
APIEndpoints.ExamSessions,
{ params: { from } },
);

yield put(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,22 @@
display: flex;
gap: 2rem;

& > button {
// Allow container for loading progress indicator to grow
> div {
@include phone {
flex-grow: 1;
}
}

& button {
@include phone {
flex-grow: 1;
padding: 0.8rem 3rem;
}

@include not-phone {
min-width: 10vw;
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe('PublicRegistrationPage', () => {

describe('allows filtering exams', () => {
it('but filter criteria must be selected first', () => {
onPublicRegistrationPage.showResults();
onPublicRegistrationPage.search();
const dialogHeading = 'Valitse tutkinnon kieli ja taso';
findDialogByText(dialogHeading).should('be.visible');
findDialogByText(dialogHeading)
Expand All @@ -23,30 +23,32 @@ describe('PublicRegistrationPage', () => {
});

it('all results are available initially', () => {
onPublicRegistrationPage.expectResultsCount(10);
onPublicRegistrationPage.selectExamLanguage('kaikki kielet');
onPublicRegistrationPage.selectExamLevel('kaikki tasot');
onPublicRegistrationPage.search();
onPublicRegistrationPage.expectResultsCount(10);
});

it('can filter by current availability', () => {
onPublicRegistrationPage.selectExamLanguage('kaikki kielet');
onPublicRegistrationPage.selectExamLevel('kaikki tasot');
onPublicRegistrationPage.toggleShowOnlyIfAvailablePlaces();
onPublicRegistrationPage.search();
onPublicRegistrationPage.expectResultsCount(4);
onPublicRegistrationPage.toggleShowOnlyIfOngoingAdmission();
onPublicRegistrationPage.search();
onPublicRegistrationPage.expectResultsCount(3);
});

it('can filter by exam language and level', () => {
onPublicRegistrationPage.selectExamLanguage('suomi');
onPublicRegistrationPage.selectExamLevel('kaikki tasot');
onPublicRegistrationPage.search();
onPublicRegistrationPage.expectResultsCount(9);

onPublicRegistrationPage.selectExamLevel('ylin taso');
onPublicRegistrationPage.search();
onPublicRegistrationPage.expectResultsCount(3);

onPublicRegistrationPage.showResults();
onPublicRegistrationPage.expectResultRowsCount(3);
});
});
Expand All @@ -57,7 +59,7 @@ describe('PublicRegistrationPage', () => {
onPublicRegistrationPage.selectExamLevel('kaikki tasot');
onPublicRegistrationPage.toggleShowOnlyIfAvailablePlaces();
onPublicRegistrationPage.toggleShowOnlyIfOngoingAdmission();
onPublicRegistrationPage.showResults();
onPublicRegistrationPage.search();

onPublicRegistrationPage
.getResultRows()
Expand All @@ -71,7 +73,7 @@ describe('PublicRegistrationPage', () => {
onPublicRegistrationPage.selectExamLanguage('suomi');
onPublicRegistrationPage.selectExamLevel('perustaso');
onPublicRegistrationPage.toggleShowOnlyIfOngoingAdmission();
onPublicRegistrationPage.showResults();
onPublicRegistrationPage.search();

onPublicRegistrationPage
.getResultRows()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,21 @@ class PublicRegistrationPage {
cy.findByLabelText(
'Näytä vain kielitutkinnot, joihin voi ilmoittautua nyt',
),
showResultsButton: () => cy.contains('Näytä tulokset'),
searchButton: () => cy.findByRole('button', { name: /Hae/ }),
title: () => cy.findByTestId('public-registration-page__title-heading'),
};

expectResultsCount(count: number) {
const resultsLabelSuffix =
count === 0
? 'ei tuloksia'
: count === 1
? '1 tulos'
: `${count} tulosta`;
this.elements
.showResultsButton()
.should('have.text', `Näytä tulokset (${count})`);
.resultBox()
.findByRole('heading', { name: `Tulokset (${resultsLabelSuffix})` })
.should('exist');
}

expectResultRowsCount(count: number) {
Expand All @@ -43,8 +50,9 @@ class PublicRegistrationPage {
selectComboBoxOptionByName(this.elements.filterByLevel(), level);
}

showResults() {
this.elements.showResultsButton().click();
search() {
this.elements.searchButton().should('not.be.disabled');
this.elements.searchButton().click();
}

toggleShowOnlyIfAvailablePlaces() {
Expand Down

0 comments on commit 601a3ba

Please sign in to comment.