Skip to content

Commit

Permalink
Merge pull request #364 from KTH/issues/KUI-1390-information-icon
Browse files Browse the repository at this point in the history
KUI-1390: added information modal to prerequisites
  • Loading branch information
axelbjo authored Oct 4, 2024
2 parents 7ffbfd5 + 35fc271 commit c9adee5
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 49 deletions.
5 changes: 4 additions & 1 deletion i18n/messages.en.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ module.exports = {
},
header_dropdown_menu_navigation:
'Choose semester and course offering to see current information and more about the course, such as course syllabus, study period, and application information.',
header_dropdown_menue: 'Information per course offering',
header_dropdown_menu: 'Information per course offering',
header_dropdown_menu_aria_label: 'Information about choosing semester and course offering',
header_course_info: 'Course information',
header_content: 'Content and learning outcomes',
Expand Down Expand Up @@ -161,6 +161,9 @@ module.exports = {
course_department: 'Offered by',
course_contact_name: 'Contact ',
course_prerequisites: 'Recommended prerequisites',
course_prerequisites_description:
'Describes the knowledge and skills (in addition to the eligibility requirements) that you need to be able to take the course.',
course_prerequisites_menu_aria_label: 'Information about recommended prerequisites',
course_suggested_addon_studies: 'Add-on studies',
course_supplemental_information_url: 'Supplementary information link',
course_supplemental_information_url_text: 'Supplementary information link text',
Expand Down
5 changes: 4 additions & 1 deletion i18n/messages.se.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ module.exports = {
},
header_dropdown_menu_navigation:
'Välj termin och kursomgång för att se aktuell information och mer om kursen, såsom kursplan, studieperiod och anmälningsinformation.',
header_dropdown_menue: 'Information per kursomgång',
header_dropdown_menu: 'Information per kursomgång',
header_dropdown_menu_aria_label: 'Information om val av termin och kursomgång',
header_course_info: 'Kursinformation',
header_content: 'Innehåll och lärandemål',
Expand Down Expand Up @@ -163,6 +163,9 @@ module.exports = {
course_department: 'Ges av',
course_contact_name: 'Kontaktperson',
course_prerequisites: 'Rekommenderade förkunskaper',
course_prerequisites_description:
'Beskriver vilka kunskaper och färdigheter (utöver behörighetskraven) som du behöver för att kunna ta till dig kursen.',
course_prerequisites_menu_aria_label: 'Information om rekommenderade förkunskaper',
course_suggested_addon_studies: 'Påbyggnad',
course_supplemental_information_url: 'Övrig information - länk',
course_supplemental_information_url_text: 'Övrig information - länk text',
Expand Down
43 changes: 43 additions & 0 deletions public/js/app/components/CourseSection.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/* eslint-disable react/no-danger */
import React from 'react'
import { FaAsterisk } from 'react-icons/fa'
import InfoModal from './InfoModal'

const syllabusMarker = (data, syllabusMarkerAriaLabel) => (
<h3>
{data.header}
{data.syllabusMarker && (
<sup>
<FaAsterisk className="syllabus-marker-icon" aria-label={syllabusMarkerAriaLabel} />
</sup>
)}
{data.infoModal && (
<InfoModal
title={data.header}
infoText={data.infoModal.description}
type="html"
closeLabel={data.infoModal.closeLabel}
ariaLabel={data.infoModal.ariaLabel}
/>
)}
</h3>
)

// eslint-disable-next-line arrow-body-style
const CourseSection = ({ sectionHeader: header = '', courseData = [], sectionId = '', syllabusMarkerAriaLabel }) => {
return (
<div id={sectionId} aria-labelledby={`${sectionId}-header`}>
{header.length ? <h2 id={`${sectionId}-header`}>{header}</h2> : null}
{courseData.map(data =>
data.text ? (
<React.Fragment key={data.header || data.text}>
{data.header && syllabusMarker(data, syllabusMarkerAriaLabel)}
<div className="course-section-content-wrapper" dangerouslySetInnerHTML={{ __html: data.text }} />
</React.Fragment>
) : null
)}
</div>
)
}

export default CourseSection
30 changes: 20 additions & 10 deletions public/js/app/components/CourseSectionList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react'

import { useLanguage } from '../hooks/useLanguage'
import { useMissingInfo } from '../hooks/useMissingInfo'
import CourseSection from './CourseSections'
import CourseSection from './CourseSection'
import { SyllabusInformation } from './SyllabusInformation'

function CourseSectionList({ courseInfo = {}, partToShow, syllabus = {}, syllabusName }) {
Expand Down Expand Up @@ -59,17 +59,17 @@ function CourseSectionList({ courseInfo = {}, partToShow, syllabus = {}, syllabu

const eligibility = getEligibility()

const recommendedPrerequisitesSection =
courseInfo.course_recommended_prerequisites != ''
? {
header: translation.courseInformation.course_prerequisites,
text: courseInfo.course_recommended_prerequisites,
}
: {}

const during = [
...eligibility,
recommendedPrerequisitesSection,
{
header: translation.courseInformation.course_prerequisites,
text: courseInfo.course_recommended_prerequisites,
infoModal: {
description: translation.courseInformation.course_prerequisites_description,
closeLabel: translation.courseLabels.label_close,
ariaLabel: translation.courseInformation.course_prerequisites_menu_aria_label,
},
},
{ header: translation.courseInformation.course_required_equipment, text: courseRequiredEquipment },
{ header: translation.courseInformation.course_literature, text: literatureText },
]
Expand Down Expand Up @@ -165,6 +165,16 @@ function CourseSectionList({ courseInfo = {}, partToShow, syllabus = {}, syllabu
header: translation.courseInformation.course_supplemental_information,
text: courseInfo.course_supplemental_information,
})
if (!isMissingInfoLabel(courseInfo.course_supplemental_information_url))
prepare.push({
header: translation.courseInformation.course_supplemental_information_url,
text: courseInfo.course_supplemental_information_url,
})
if (!isMissingInfoLabel(courseInfo.course_supplemental_information_url_text))
prepare.push({
header: translation.courseInformation.course_supplemental_information_url_text,
text: courseInfo.course_supplemental_information_url_text,
})

if (!isContractEducation() && syllabus.course_additional_regulations !== '')
prepare.push({
Expand Down
30 changes: 0 additions & 30 deletions public/js/app/components/CourseSections.jsx

This file was deleted.

4 changes: 2 additions & 2 deletions public/js/app/components/RoundSelector/RoundSelector.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ export const RoundSelector = ({ activeSemesters, semesterRoundState }) => {
<div className="roundSelector">
<div>
<h2>
{translation.courseLabels.header_dropdown_menue}
{translation.courseLabels.header_dropdown_menu}
<InfoModal
title={translation.courseLabels.header_dropdown_menue}
title={translation.courseLabels.header_dropdown_menu}
infoText={translation.courseLabels.syllabus_info}
type="html"
closeLabel={translation.courseLabels.label_close}
Expand Down
37 changes: 32 additions & 5 deletions public/js/app/components/__tests__/CourseSections.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ import React from 'react'

import '@testing-library/jest-dom'
import { render, screen } from '@testing-library/react'
import CourseSections from '../CourseSections'
import CourseSection from '../CourseSection'
import i18n from '../../../../../i18n'

const [translationEN] = i18n.messages

describe('Component <CourseSections>', () => {
describe('Component <CourseSection>', () => {
test('render text with a syllabus marker correctly', () => {
const mockData = [{ header: 'First test header', text: 'Text for test from test syllabus', syllabusMarker: true }]
render(
<CourseSections
<CourseSection
sectionHeader={'Section with all test headers and texts'}
headerType="3"
courseData={mockData}
Expand All @@ -33,7 +33,7 @@ describe('Component <CourseSections>', () => {
test('render text without a syllabus marker correctly', () => {
const mockData = [{ header: 'Test header chosen by user', text: 'Text for test not from syllabys' }]
render(
<CourseSections
<CourseSection
sectionHeader={'Section with all test headers and texts'}
headerType="3"
courseData={mockData}
Expand All @@ -49,13 +49,40 @@ describe('Component <CourseSections>', () => {
expect(header.querySelector('sup')).toBeNull()
})

test('render an info button correctly', () => {
const mockData = [
{
header: 'First test header',
text: 'Text for test from test syllabus',
syllabusMarker: true,
infoModal: {
description: translationEN.courseInformation.course_prerequisites_description,
closeLabel: translationEN.courseLabels.label_close,
ariaLabel: translationEN.courseInformation.course_prerequisites_menu_aria_label,
},
},
]
render(
<CourseSection
sectionHeader={'Section with all test headers and texts'}
headerType="3"
courseData={mockData}
sectionId="firstSection"
syllabusMarkerAriaLabel={translationEN.courseLabels.syllabus_marker_aria_label}
/>
)

const modal = screen.getByLabelText(mockData[0].infoModal.ariaLabel)
expect(modal).toBeInTheDocument()
})

test('render array of several headers with text correctly', () => {
const mockData = [
{ header: 'First test header', text: 'Text for test from test syllabus', syllabusMarker: true },
{ header: 'Second test header', text: 'Text for test not from syllabys' },
]
render(
<CourseSections
<CourseSection
sectionHeader={'Section with all test headers and texts'}
headerType="3"
courseData={mockData}
Expand Down

0 comments on commit c9adee5

Please sign in to comment.