From ca5dc8a8dfe1e461aa80d840a3af699a4a38d072 Mon Sep 17 00:00:00 2001 From: Pyry Koivisto Date: Thu, 19 Oct 2023 17:58:04 +0300 Subject: [PATCH] YKI(Frontend): Use NativeSelect instead of ComboBox for exam listing filters when on mobile [deploy] --- frontend/packages/yki/package.json | 2 +- .../PublicExamSessionListingFilters.tsx | 334 +++++++++++------- frontend/yarn.lock | 4 +- 3 files changed, 212 insertions(+), 128 deletions(-) diff --git a/frontend/packages/yki/package.json b/frontend/packages/yki/package.json index 0fe93352dc..55687d6196 100644 --- a/frontend/packages/yki/package.json +++ b/frontend/packages/yki/package.json @@ -26,7 +26,7 @@ "yki:tslint": "yarn g:tsc --pretty --noEmit" }, "dependencies": { - "shared": "npm:@opetushallitus/kieli-ja-kaantajatutkinnot.shared@1.9.29" + "shared": "npm:@opetushallitus/kieli-ja-kaantajatutkinnot.shared@1.10.0" }, "devDependencies": { "multer": "^1.4.5-lts.1" diff --git a/frontend/packages/yki/src/components/registration/examSession/PublicExamSessionListingFilters.tsx b/frontend/packages/yki/src/components/registration/examSession/PublicExamSessionListingFilters.tsx index 98310212d3..2b74d0edab 100644 --- a/frontend/packages/yki/src/components/registration/examSession/PublicExamSessionListingFilters.tsx +++ b/frontend/packages/yki/src/components/registration/examSession/PublicExamSessionListingFilters.tsx @@ -7,16 +7,17 @@ import { FormGroup, Typography, } from '@mui/material'; -import { useState } from 'react'; +import { useCallback, useState } from 'react'; import { AutocompleteValue, ComboBox, CustomButton, LanguageSelect, + NativeSelect, Text, } from 'shared/components'; import { Color, Severity, TextFieldVariant, Variant } from 'shared/enums'; -import { useDialog } from 'shared/hooks'; +import { useDialog, useWindowProperties } from 'shared/hooks'; import { useCommonTranslation, usePublicTranslation } from 'configs/i18n'; import { useAppDispatch, useAppSelector } from 'configs/redux'; @@ -28,6 +29,200 @@ import { selectFilteredPublicExamSessions, } from 'redux/selectors/examSessions'; +const municipalityToComboBoxOption = (m: string) => ({ + value: m, + label: m, +}); + +const SelectMunicipality = () => { + const municipalities = useAppSelector(examSessionsSelector).municipalities; + const { municipality } = useAppSelector(examSessionsSelector).filters; + const dispatch = useAppDispatch(); + const onMunicipalityChange = useCallback( + (municipality?: string) => { + dispatch(setPublicExamSessionFilters({ municipality })); + }, + [dispatch] + ); + + const { t } = usePublicTranslation({ + keyPrefix: 'yki.pages.registrationPage', + }); + const { isPhone } = useWindowProperties(); + + return ( +
+ + {t('labels.selectMunicipality')} + + {isPhone ? ( + { + onMunicipalityChange(e.target.value as string); + }} + placeholder={t('labels.selectMunicipality')} + value={ + municipality ? municipalityToComboBoxOption(municipality) : null + } + values={municipalities.map(municipalityToComboBoxOption)} + /> + ) : ( + { + const municipality = v?.value; + onMunicipalityChange(municipality); + }} + label={t('labels.selectMunicipality')} + aria-label={t('labels.selectMunicipality')} + /> + )} +
+ ); +}; + +const SelectExamLanguage = ({ + showError, + onFilterChange, +}: { + showError: boolean; + onFilterChange: (filter: Partial) => void; +}) => { + const { language } = useAppSelector(examSessionsSelector).filters; + + const { t } = usePublicTranslation({ + keyPrefix: 'yki.pages.registrationPage', + }); + const translateCommon = useCommonTranslation(); + const translateLanguage = (language: string) => + translateCommon('languages.' + language); + const languages = Object.values(ExamLanguage); + + return ( + + + {translateCommon('language')}{' '} + + {t('filters.selectExamDetails.required')} + + + { + const language = v as ExamLanguage | undefined; + onFilterChange({ language }); + }} + label={t('labels.selectLanguage')} + aria-label={t('labels.selectLanguage')} + showError={showError && !language} + helperText={showError && !language ? t('filters.errors.required') : ''} + /> + + ); +}; + +const SelectExamLevel = ({ + showError, + onFilterChange, +}: { + showError: boolean; + onFilterChange: (filter: Partial) => void; +}) => { + const { level } = useAppSelector(examSessionsSelector).filters; + + const translateCommon = useCommonTranslation(); + const { t } = usePublicTranslation({ + keyPrefix: 'yki.pages.registrationPage', + }); + + const levelToComboBoxOption = (v: ExamLevel) => ({ + value: v.toString(), + label: translateCommon('languageLevel.' + v.toString()), + }); + const levelValues = Object.values(ExamLevel).map(levelToComboBoxOption); + + const errorStyles = { color: 'error.main' }; + const { isPhone } = useWindowProperties(); + + return ( + + + {translateCommon('level')}{' '} + + {t('filters.selectExamDetails.required')} + + + {isPhone ? ( + { + const level = e.target.value as ExamLevel | undefined; + onFilterChange({ level }); + }} + placeholder={t('labels.selectLevel')} + value={level ? levelToComboBoxOption(level) : null} + values={levelValues} + /> + ) : ( + { + const level = v?.value as ExamLevel | undefined; + onFilterChange({ level }); + }} + label={t('labels.selectLevel')} + aria-label={t('labels.selectLevel')} + showError={showError && !level} + helperText={showError && !level ? t('filters.errors.required') : ''} + /> + )} + + ); +}; + export const PublicExamSessionFilters = ({ onApplyFilters, }: { @@ -41,15 +236,9 @@ export const PublicExamSessionFilters = ({ const { showDialog } = useDialog(); - const { filters, municipalities } = useAppSelector(examSessionsSelector); const filteredExamSessions = useAppSelector(selectFilteredPublicExamSessions); - const { - language, - level, - municipality, - excludeFullSessions, - excludeNonOpenSessions, - } = filters; + const { language, level, excludeFullSessions, excludeNonOpenSessions } = + useAppSelector(examSessionsSelector).filters; const dispatch = useAppDispatch(); const onFilterChange = (filter: Partial) => { @@ -59,7 +248,7 @@ export const PublicExamSessionFilters = ({ const [showError, setShowError] = useState(false); const handleSubmitBtnClick = () => { - if (!filters.language || !filters.level) { + if (!language || !level) { setShowError(true); showDialog({ severity: Severity.Error, @@ -78,22 +267,6 @@ export const PublicExamSessionFilters = ({ } }; - const languages = Object.values(ExamLanguage); - const translateLanguage = (language: string) => - translateCommon('languages.' + language); - - const levelToComboBoxOption = (v: ExamLevel) => ({ - value: v.toString(), - label: translateCommon('languageLevel.' + v.toString()), - }); - const levelValues = Object.values(ExamLevel).map(levelToComboBoxOption); - const municipalityToComboBoxOption = (m: string) => ({ - value: m, - label: m, - }); - - const errorStyles = { color: 'error.main' }; - return (
@@ -104,106 +277,17 @@ export const PublicExamSessionFilters = ({
- - - {translateCommon('language')}{' '} - - {t('filters.selectExamDetails.required')} - - - { - const language = v?.value as ExamLanguage | undefined; - onFilterChange({ language }); - }} - label={t('labels.selectLanguage')} - aria-label={t('labels.selectLanguage')} - showError={showError && !language} - helperText={ - showError && !language ? t('filters.errors.required') : '' - } - /> - - - - {translateCommon('level')}{' '} - - {t('filters.selectExamDetails.required')} - - - { - const level = v?.value as ExamLevel | undefined; - onFilterChange({ level }); - }} - label={t('labels.selectLevel')} - aria-label={t('labels.selectLevel')} - showError={showError && !level} - helperText={ - showError && !level ? t('filters.errors.required') : '' - } - /> - + +
-
- - {t('labels.selectMunicipality')} - - { - const municipality = v?.value; - onFilterChange({ municipality }); - }} - label={t('labels.selectMunicipality')} - aria-label={t('labels.selectMunicipality')} - /> -
+
diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 24fbd256f0..6effa861e7 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2990,7 +2990,7 @@ __metadata: languageName: unknown linkType: soft -"@opetushallitus/kieli-ja-kaantajatutkinnot.shared@workspace:packages/shared, shared@npm:@opetushallitus/kieli-ja-kaantajatutkinnot.shared@1.9.29": +"@opetushallitus/kieli-ja-kaantajatutkinnot.shared@workspace:packages/shared, shared@npm:@opetushallitus/kieli-ja-kaantajatutkinnot.shared@1.10.0": version: 0.0.0-use.local resolution: "@opetushallitus/kieli-ja-kaantajatutkinnot.shared@workspace:packages/shared" languageName: unknown @@ -3010,7 +3010,7 @@ __metadata: resolution: "@opetushallitus/kieli-ja-kaantajatutkinnot.yki@workspace:packages/yki" dependencies: multer: ^1.4.5-lts.1 - shared: "npm:@opetushallitus/kieli-ja-kaantajatutkinnot.shared@1.9.29" + shared: "npm:@opetushallitus/kieli-ja-kaantajatutkinnot.shared@1.10.0" languageName: unknown linkType: soft