[Evaluation overview] Remove everything

This commit is contained in:
Riku Rauhala
2024-11-27 10:14:29 +02:00
parent 6bf083cc89
commit c2583e5bc9
15 changed files with 2 additions and 1358 deletions
-2
View File
@@ -55,8 +55,6 @@ jobs:
spec: cypress/e2e/Language_center.js
- name: 'Test study guidance groups'
spec: cypress/e2e/Study_guidance_groups.js
- name: 'Test evaluation overview'
spec: cypress/e2e/Evaluation_overview.js
- name: 'Test university'
spec: cypress/e2e/University.js
name: ${{ matrix.name }}
-2
View File
@@ -213,8 +213,6 @@ jobs:
spec: cypress/e2e/Language_center.js
- name: 'Test study guidance groups'
spec: cypress/e2e/Study_guidance_groups.js
- name: 'Test evaluation overview'
spec: cypress/e2e/Evaluation_overview.js
- name: 'Test university'
spec: cypress/e2e/University.js
name: ${{ matrix.name }}
-514
View File
@@ -1,514 +0,0 @@
/// <reference types="cypress" />
const { getEmptyYears } = require('../support/commands')
describe('Evaluation overview', () => {
describe('Programme view', () => {
beforeEach(() => {
cy.init('/evaluationoverview/programme/KH50_001', 'admin')
})
it('Page opens correctly', () => {
cy.contains('Matemaattisten tieteiden kandiohjelma')
cy.contains('KH50_001')
cy.contains("This view is an abridged version of Oodikone's Studyprogramme Overview")
})
it('Progress data is shown correctly with graduated included', () => {
cy.get('[data-cy="Graph-StudyTrackProgress"]').within(() => {
const totalStats = ['12.9%', '6.9%', '9.7%', '9.2%', '3.7%', '6.0%', '51.6%']
for (const stat of totalStats) {
cy.contains(stat)
}
})
const years = getEmptyYears(true)
const tableContents = [
...years.map(year => [year, 0, 0, 0, 0, 0, 0, 0, 0]),
['2023 - 2024', 8, 8, 0, 0, 0, 0, 0, 0],
['2022 - 2023', 26, 9, 9, 4, 3, 0, 1, 0],
['2021 - 2022', 32, 8, 3, 8, 8, 5, 0, 0],
['2020 - 2021', 27, 2, 1, 3, 6, 2, 4, 9],
['2019 - 2020', 33, 1, 0, 2, 1, 0, 3, 26],
['2018 - 2019', 44, 0, 1, 1, 2, 0, 3, 37],
['2017 - 2018', 47, 0, 1, 3, 0, 1, 2, 40],
['Total', 217, 28, 15, 21, 20, 8, 13, 112],
]
cy.checkTableStats(tableContents, 'StudyTrackProgress')
})
it('Progress data is shown correctly with graduated excluded', () => {
cy.get('[data-cy=GraduatedToggle]').click()
cy.get('[data-cy="Graph-StudyTrackProgress"]').within(() => {
const totalStats = ['30.8%', '15.4%', '22.0%', '20.9%', '4.4%', '5.5%']
for (const stat of totalStats) {
cy.contains(stat)
}
})
const years = getEmptyYears(true)
const tableContents = [
...years.map(year => [year, 0, 0, 0, 0, 0, 0, 0, 0]),
['2023 - 2024', 8, 8, 0, 0, 0, 0, 0, 0],
['2022 - 2023', 24, 9, 8, 4, 3, 0, 0, 0],
['2021 - 2022', 31, 8, 3, 8, 8, 4, 0, 0],
['2020 - 2021', 11, 2, 1, 2, 5, 0, 0, 1],
['2019 - 2020', 7, 1, 0, 2, 1, 0, 0, 3],
['2018 - 2019', 5, 0, 1, 1, 2, 0, 0, 1],
['2017 - 2018', 5, 0, 1, 3, 0, 0, 1, 0],
['Total', 91, 28, 14, 20, 19, 4, 1, 5],
]
cy.checkTableStats(tableContents, 'StudyTrackProgress')
})
it('Graduation times breakdown data is shown correctly', () => {
cy.get('[data-cy=graduation-times-graph-breakdown]').within(() => {
cy.contains('Graduation year')
cy.contains('2021')
cy.get('[aria-label="2021, 8. Overtime."]')
cy.get('[aria-label="2021, 24. Max. year overtime."]')
cy.get('[aria-label="2021, 14. On time."]').trigger('mouseover')
cy.contains('Graduated On time: 14 students')
})
cy.get('[data-cy=YearToggle]').click()
cy.get('[data-cy=graduation-times-graph-breakdown]').within(() => {
cy.contains('Graduation year')
cy.contains('2021 - 2022')
cy.get('[aria-label="2021 - 2022, 13. Overtime."]')
cy.get('[aria-label="2021 - 2022, 21. Max. year overtime."]')
cy.get('[aria-label="2021 - 2022, 21. On time."]').trigger('mouseover')
cy.contains('Graduated On time: 21 students')
})
})
it('Graduation times median time data is shown correctly', () => {
cy.get('[data-cy=GraduationTimeToggle]').click()
cy.get('[data-cy=graduation-times-graph]').within(() => {
cy.contains('Graduation year')
cy.contains('2021')
cy.contains('46 graduated').trigger('mouseover')
cy.contains('46 students graduated in year 2021')
cy.contains('median study time: 41 months')
cy.contains('14 graduated on time')
cy.contains('24 graduated max year overtime')
cy.contains('8 graduated over year late')
})
cy.get('[data-cy=YearToggle]').click()
cy.get('[data-cy=graduation-times-graph]').within(() => {
cy.contains('Graduation year')
cy.contains('2021 - 2022')
cy.contains('55 graduated').trigger('mouseover')
cy.contains('55 students graduated in year 2021 - 2022')
cy.contains('median study time: 40 months')
cy.contains('21 graduated on time')
cy.contains('21 graduated max year overtime')
cy.contains('13 graduated over year late')
})
})
it("'Programmes before or after' data is shown correctly", () => {
cy.get('[data-cy=Graph-ProgrammesBeforeOrAfter]').within(() => {
cy.contains('Matematiikan ja tilastotieteen maisteriohjelma')
cy.contains('Tietojenkäsittelytieteen maisteriohjelma')
cy.contains('Datatieteen maisteriohjelma')
cy.contains('2021')
cy.contains('32')
cy.contains('19')
})
let emptyYears = new Array(getEmptyYears(false).length).fill(0)
let tableContents = [
['MH50_001', 'MAST', 'Matematiikan ja tilastotieteen maisteriohjelma', 0, 0, 1, 9, 32, 19, 15, ...emptyYears],
['MH50_002', 'LSI', 'Life Science Informatics -maisteriohjelma', 0, 0, 0, 1, 2, 1, 1, ...emptyYears],
[
'MH50_003',
'TCM',
'Teoreettisten ja laskennallisten menetelmien maisteriohjelma',
0,
0,
0,
0,
1,
2,
1,
...emptyYears,
],
['MH50_009', 'CSM', 'Tietojenkäsittelytieteen maisteriohjelma', 0, 0, 0, 0, 2, 3, 2, ...emptyYears],
['MH50_010', 'DATA', 'Datatieteen maisteriohjelma', 0, 0, 0, 1, 5, 10, 1, ...emptyYears],
['MH70_009', 'ECON', 'Taloustieteen maisteriohjelma', 0, 0, 0, 0, 4, 7, 4, ...emptyYears],
]
cy.checkTableStats(tableContents, 'undefined')
cy.get('[data-cy=YearToggle]').click()
cy.get('[data-cy=Graph-ProgrammesBeforeOrAfter]').within(() => {
cy.contains('Matematiikan ja tilastotieteen maisteriohjelma')
cy.contains('Tietojenkäsittelytieteen maisteriohjelma')
cy.contains('Datatieteen maisteriohjelma')
cy.contains('2021 - 2022')
cy.contains('28')
cy.contains('16')
})
emptyYears = new Array(getEmptyYears(true).length).fill(0)
tableContents = [
['MH50_001', 'MAST', 'Matematiikan ja tilastotieteen maisteriohjelma', 0, 0, 4, 24, 28, 16, 4, ...emptyYears],
['MH50_002', 'LSI', 'Life Science Informatics -maisteriohjelma', 0, 0, 1, 0, 3, 1, 0, ...emptyYears],
[
'MH50_003',
'TCM',
'Teoreettisten ja laskennallisten menetelmien maisteriohjelma',
0,
0,
0,
1,
1,
2,
0,
...emptyYears,
],
['MH50_009', 'CSM', 'Tietojenkäsittelytieteen maisteriohjelma', 0, 0, 0, 0, 4, 3, 0, ...emptyYears],
['MH50_010', 'DATA', 'Datatieteen maisteriohjelma', 0, 0, 1, 0, 12, 4, 0, ...emptyYears],
['MH70_009', 'ECON', 'Taloustieteen maisteriohjelma', 0, 0, 0, 4, 6, 5, 0, ...emptyYears],
]
cy.checkTableStats(tableContents, 'undefined')
})
})
describe('Faculty view', () => {
beforeEach(() => {
cy.init('/evaluationoverview/faculty/H50', 'admin')
})
it('Page opens correctly', () => {
cy.contains('Matemaattis-luonnontieteellinen tiedekunta')
cy.contains('H50')
cy.contains("This view is an abridged version of Oodikone's Faculty Overview")
})
describe('Progress stats', () => {
describe('Bachelor stats', () => {
it('graph with graduated included is shown correctly', () => {
cy.get('[data-cy="Graph-FacultyBachelorsProgress"]').within(() => {
const totalStats = ['12.2%', '5.3%', '7.5%', '8.2%', '5.3%', '6.3%', '55.2%']
for (const stat of totalStats) {
cy.contains(stat)
}
})
})
it('graph with graduated excluded is shown correctly', () => {
cy.get('[data-cy="GraduatedToggle"]').click()
cy.get('[data-cy="Graph-FacultyBachelorsProgress"]').within(() => {
const totalStats = ['30.5%', '12.5%', '18.0%', '19.5%', '7.0%', '3.1%', '9.4%']
for (const stat of totalStats) {
cy.contains(stat)
}
})
})
it('table with graduated included is shown correctly', () => {
cy.get('[data-cy="Table-FacultyBachelorsProgress"]')
const years = getEmptyYears(true)
const tableContents = [
...years.map(year => [year, 0, 0, 0, 0, 0, 0, 0, 0]),
['2023 - 2024', 14, 13, 0, 0, 0, 0, 0, 1],
['2022 - 2023', 32, 11, 10, 6, 4, 0, 1, 0],
['2021 - 2022', 44, 10, 4, 9, 11, 7, 1, 2],
['2020 - 2021', 38, 3, 1, 3, 7, 3, 8, 13],
['2019 - 2020', 50, 2, 0, 2, 1, 4, 5, 36],
['2018 - 2019', 75, 0, 1, 1, 2, 2, 3, 66],
['2017 - 2018', 66, 0, 1, 3, 1, 1, 2, 58],
['Total', 319, 39, 17, 24, 26, 17, 20, 176],
]
cy.checkTableStats(tableContents, 'FacultyBachelorsProgress')
})
it('table with graduated excluded is shown correctly', () => {
cy.get('[data-cy="GraduatedToggle"]').click()
cy.get('[data-cy="Table-FacultyBachelorsProgress"]')
const years = getEmptyYears(true)
const tableContents = [
...years.map(year => [year, 0, 0, 0, 0, 0, 0, 0, 0]),
['2023 - 2024', 14, 13, 0, 0, 0, 0, 0, 1],
['2022 - 2023', 30, 11, 9, 6, 4, 0, 0, 0],
['2021 - 2022', 41, 10, 4, 9, 11, 6, 0, 1],
['2020 - 2021', 14, 3, 1, 2, 6, 0, 1, 1],
['2019 - 2020', 14, 2, 0, 2, 1, 3, 2, 4],
['2018 - 2019', 6, 0, 1, 1, 2, 0, 0, 2],
['2017 - 2018', 9, 0, 1, 3, 1, 0, 1, 3],
['Total', 128, 39, 16, 23, 25, 9, 4, 12],
]
cy.checkTableStats(tableContents, 'FacultyBachelorsProgress')
})
})
describe('Bachelor + master stats', () => {
it('graph with graduated included is shown correctly', () => {
cy.get('[data-cy=Graph-FacultyBachelorMastersProgress]').within(() => {
const totalStats = ['21.3%', '8.4%', '10.1%', '14.0%', '12.4%', '6.7%', '27.0%']
for (const stat of totalStats) {
cy.contains(stat)
}
})
})
it('graph with graduated excluded is shown correctly', () => {
cy.get('[data-cy="GraduatedToggle"]').click()
cy.get('[data-cy=Graph-FacultyBachelorMastersProgress]').within(() => {
const totalStats = ['28.7%', '11.6%', '14.0%', '18.6%', '15.5%', '3.1%', '8.5%']
for (const stat of totalStats) {
cy.contains(stat)
}
})
})
it('table with graduated included is shown correctly', () => {
cy.get('[data-cy="Table-FacultyBachelorMastersProgress"]')
const years = getEmptyYears(true)
const tableContents = [
...years.map(year => [year, 0, 0, 0, 0, 0, 0, 0, 0]),
['2023 - 2024', 0, 0, 0, 0, 0, 0, 0, 0],
['2022 - 2023', 2, 2, 0, 0, 0, 0, 0, 0],
['2021 - 2022', 4, 2, 0, 0, 0, 1, 0, 1],
['2020 - 2021', 23, 13, 2, 4, 0, 4, 0, 0],
['2019 - 2020', 32, 7, 7, 4, 7, 3, 3, 1],
['2018 - 2019', 63, 10, 2, 5, 13, 7, 4, 22],
['2017 - 2018', 54, 4, 4, 5, 5, 7, 5, 24],
['Total', 178, 38, 15, 18, 25, 22, 12, 48],
]
cy.checkTableStats(tableContents, 'FacultyBachelorMastersProgress')
})
it('table with graduated excluded is shown correctly', () => {
cy.get('[data-cy="GraduatedToggle"]').click()
cy.get('[data-cy="Table-FacultyBachelorMastersProgress"]')
const years = getEmptyYears(true)
const tableContents = [
...years.map(year => [year, 0, 0, 0, 0, 0, 0, 0, 0]),
['2023 - 2024', 0, 0, 0, 0, 0, 0, 0, 0],
['2022 - 2023', 2, 2, 0, 0, 0, 0, 0, 0],
['2021 - 2022', 4, 2, 0, 0, 0, 1, 0, 1],
['2020 - 2021', 21, 13, 2, 4, 0, 2, 0, 0],
['2019 - 2020', 31, 7, 7, 4, 7, 3, 2, 1],
['2018 - 2019', 41, 9, 2, 5, 12, 7, 1, 5],
['2017 - 2018', 30, 4, 4, 5, 5, 7, 1, 4],
['Total', 129, 37, 15, 18, 24, 20, 4, 11],
]
cy.checkTableStats(tableContents, 'FacultyBachelorMastersProgress')
})
})
describe('Master stats', () => {
it('graph with graduated included is shown correctly', () => {
cy.get('[data-cy=Graph-FacultyMastersProgress]').within(() => {
const totalStats = ['16.1%', '12.9%', '6.5%', '12.9%', '9.7%', '16.1%', '25.8%']
for (const stat of totalStats) {
cy.contains(stat)
}
})
})
it('graph with graduated excluded is shown correctly', () => {
cy.get('[data-cy="GraduatedToggle"]').click()
cy.get('[data-cy=Graph-FacultyMastersProgress]').within(() => {
const totalStats = ['23.8%', '19.0%', '9.5%', '9.5%', '9.5%', '14.3%', '14.3%']
for (const stat of totalStats) {
cy.contains(stat)
}
})
})
it('table with graduated included is shown correctly', () => {
cy.get('[data-cy="Table-FacultyMastersProgress"]')
const years = getEmptyYears(true)
const tableContents = [
...years.map(year => [year, 0, 0, 0, 0, 0, 0, 0, 0]),
['2023 - 2024', 4, 4, 0, 0, 0, 0, 0, 0],
['2022 - 2023', 5, 0, 1, 1, 2, 0, 0, 1],
['2021 - 2022', 8, 1, 2, 0, 2, 1, 1, 1],
['2020 - 2021', 3, 0, 0, 0, 0, 0, 2, 1],
['2019 - 2020', 7, 0, 0, 1, 0, 1, 1, 4],
['2018 - 2019', 2, 0, 0, 0, 0, 1, 0, 1],
['2017 - 2018', 2, 0, 1, 0, 0, 0, 1, 0],
['Total', 31, 5, 4, 2, 4, 3, 5, 8],
]
cy.checkTableStats(tableContents, 'FacultyMastersProgress')
})
it('table with graduated excluded is shown correctly', () => {
cy.get('[data-cy="GraduatedToggle"]').click()
cy.get('[data-cy="Table-FacultyMastersProgress"]')
const years = getEmptyYears(true)
const tableContents = [
...years.map(year => [year, 0, 0, 0, 0, 0, 0, 0, 0]),
['2023 - 2024', 4, 4, 0, 0, 0, 0, 0, 0],
['2022 - 2023', 5, 0, 1, 1, 2, 0, 0, 1],
['2021 - 2022', 5, 1, 2, 0, 0, 0, 1, 1],
['2020 - 2021', 0, 0, 0, 0, 0, 0, 0, 0],
['2019 - 2020', 3, 0, 0, 1, 0, 1, 1, 0],
['2018 - 2019', 2, 0, 0, 0, 0, 1, 0, 1],
['2017 - 2018', 2, 0, 1, 0, 0, 0, 1, 0],
['Total', 21, 5, 4, 2, 2, 2, 3, 3],
]
cy.checkTableStats(tableContents, 'FacultyMastersProgress')
})
})
describe('Doctor stats', () => {
it('graph with graduated included is shown correctly', () => {
cy.get('[data-cy=Graph-FacultyDoctoralProgress]').within(() => {
const totalStats = ['6.0%', '18.0%', '16.0%', '14.0%', '46.0%']
for (const stat of totalStats) {
cy.contains(stat)
}
})
})
it('graph with graduated excluded is shown correctly', () => {
cy.get('[data-cy="GraduatedToggle"]').click()
cy.get('[data-cy=Graph-FacultyDoctoralProgress]').within(() => {
const totalStats = ['9.1%', '24.2%', '12.1%', '15.2%', '39.4%']
for (const stat of totalStats) {
cy.contains(stat)
}
})
})
it('table with graduated included is shown correctly', () => {
cy.get('[data-cy="Table-FacultyDoctoralProgress"]')
const years = getEmptyYears(true)
const tableContents = [
...years.map(year => [year, 0, 0, 0, 0, 0, 0]),
['2023 - 2024', 1, 1, 0, 0, 0, 0],
['2022 - 2023', 9, 1, 7, 1, 0, 0],
['2021 - 2022', 3, 1, 1, 0, 0, 1],
['2020 - 2021', 5, 0, 0, 2, 1, 2],
['2019 - 2020', 11, 0, 0, 1, 4, 6],
['2018 - 2019', 14, 0, 1, 4, 2, 7],
['2017 - 2018', 7, 0, 0, 0, 0, 7],
['Total', 50, 3, 9, 8, 7, 23],
]
cy.checkTableStats(tableContents, 'FacultyDoctoralProgress')
})
it('table with graduated excluded is shown correctly', () => {
cy.get('[data-cy="GraduatedToggle"]').click()
cy.get('[data-cy="Table-FacultyDoctoralProgress"]')
const years = getEmptyYears(true)
const tableContents = [
...years.map(year => [year, 0, 0, 0, 0, 0, 0]),
['2023 - 2024', 1, 1, 0, 0, 0, 0],
['2022 - 2023', 9, 1, 7, 1, 0, 0],
['2021 - 2022', 3, 1, 1, 0, 0, 1],
['2020 - 2021', 4, 0, 0, 2, 0, 2],
['2019 - 2020', 9, 0, 0, 1, 4, 4],
['2018 - 2019', 5, 0, 0, 0, 1, 4],
['2017 - 2018', 2, 0, 0, 0, 0, 2],
['Total', 33, 3, 8, 4, 5, 13],
]
cy.checkTableStats(tableContents, 'FacultyDoctoralProgress')
})
})
it('Years in the tables can be clicked to show programme level breakdown', () => {
cy.get('[data-cy="Table-FacultyBachelorsProgress"]').within(() => {
cy.contains('2021 - 2022').click()
cy.contains('31.3%').trigger('mouseover', { force: true })
cy.contains('Matemaattisten tieteiden kandiohjelma')
cy.contains('MAT - KH50_001')
cy.contains('0 Credits: 0')
cy.contains('1 ≤ Credits < 45: 10')
cy.contains('45 ≤ Credits < 90: 9')
cy.contains('90 ≤ Credits < 135: 11')
cy.contains('135 ≤ Credits < 180: 2')
cy.contains('180 ≤ Credits: 0')
})
})
})
describe('Graduation times stats', () => {
it('All the correct sections are displayed', () => {
const checkSections = breakdown => {
const sections = ['bachelor', 'bcMsCombo', 'master', 'doctor']
for (const section of sections) {
cy.get(`[data-cy=Section-${section}]`).within(() => {
cy.get('div.graduations-chart-container').within(() => {
cy.get(`div.faculty-${breakdown ? 'breakdown-' : ''}graph`)
cy.get('div.graduations-message').contains("Click a bar to view that year's programme level breakdown")
})
})
}
}
checkSections(true)
cy.get('[data-cy=GraduationTimeToggle]').click()
checkSections(false)
})
it('Graduation times breakdown data is shown correctly', () => {
cy.get('[data-cy=Section-bachelor]').within(() => {
cy.contains('Graduation year')
cy.contains('2022')
cy.get('[aria-label="2022, 29. On time."]').trigger('mouseover')
cy.contains('On time: 29')
cy.get('[aria-label="2022, 29. On time."]').trigger('click')
cy.contains('Year 2022 by graduation year')
cy.get('[aria-label="MAT, 22. On time."]').trigger('mouseover')
cy.contains('Matemaattisten tieteiden kandiohjelma')
cy.contains('KH50_001')
cy.contains('On time: 22')
cy.get('[aria-label="MFKK, 7. On time."]').trigger('mouseover')
cy.contains('Matematiikan, fysiikan ja kemian opettajan kandiohjelma')
cy.contains('KH50_004')
cy.contains('On time: 7')
})
})
it('Graduation times median time data is shown correctly', () => {
cy.get('[data-cy=GraduationTimeToggle]').click()
cy.get('[data-cy=Section-bachelor]').within(() => {
cy.contains('Graduation year')
cy.contains('2021')
cy.contains('70 graduated').trigger('mouseover')
cy.contains('70 students graduated in year 2021')
cy.contains('median study time: 39.5 months')
cy.contains('28 graduated on time')
cy.contains('32 graduated max year overtime')
cy.contains('10 graduated over year late')
cy.contains('70 graduated').trigger('click')
cy.contains('Year 2021 by graduation year')
cy.get('[aria-label="MAT, 41."]').trigger('mouseover')
cy.contains('Matemaattisten tieteiden kandiohjelma')
cy.contains('KH50_001')
cy.contains('47 students graduated in year 2021')
cy.contains('median study time: 41 months')
cy.contains('14 graduated on time')
cy.contains('25 graduated max year overtime')
cy.contains('8 graduated over year late')
})
})
})
})
})
+2 -2
View File
@@ -23,9 +23,9 @@ The roles `openUniSearch` and `studyGuidanceGroups` simply enable certain views
- Can see statistics of every course and year
### katselemusViewer
### katselmusViewer
- Enables the _Evaluation overview_ view
- Enables the _Evaluation overview_ view (deprecated)
### teachers
@@ -9,7 +9,6 @@ import {
setStudyTrackStats,
} from '../services/analyticsService'
import { getCreditsProduced } from '../services/providerCredits'
import { getProgrammeName } from '../services/studyProgramme'
import { getBasicStatsForStudytrack } from '../services/studyProgramme/studyProgrammeBasics'
import {
getStudyProgrammeCoursesForStudyTrack,
@@ -224,73 +223,4 @@ router.get('/:id/update_studytrackview', async (req: GetUpdateViewRequest, res:
}
})
interface GetEvaluationStatsRequest extends Request {
query: {
graduated: Graduated
year_type: YearType
special_groups: SpecialGroups
}
}
router.get('/:id/evaluationstats', async (req: GetEvaluationStatsRequest, res: Response) => {
const code = req.params.id
const { graduated, year_type: yearType, special_groups: specialGroups } = req.query
if (!code) {
return res.status(422).end()
}
// Statistics for Tilannekuvalomake view
const combinedProgramme = ''
let gradData = await getGraduationStats(code, combinedProgramme, yearType, specialGroups)
if (!gradData) {
const updatedStats = await getGraduationStatsForStudyTrack({
studyProgramme: code,
combinedProgramme,
settings: {
isAcademicYear: yearType === 'ACADEMIC_YEAR',
includeAllSpecials: specialGroups === 'SPECIAL_INCLUDED',
},
})
if (updatedStats) {
await setGraduationStats(updatedStats, yearType, specialGroups)
gradData = updatedStats
}
}
let progressData = await getStudyTrackStats(code, combinedProgramme, graduated, specialGroups)
if (!progressData) {
const studyRightsOfProgramme = await getStudyRightsInProgramme(code, false, true)
const updated = await getStudyTrackStatsForStudyProgramme({
studyProgramme: code,
combinedProgramme,
settings: {
graduated: graduated === 'GRADUATED_INCLUDED',
specialGroups: specialGroups === 'SPECIAL_INCLUDED',
},
studyRightsOfProgramme,
})
if (updated) {
await setStudyTrackStats(updated, graduated, specialGroups)
progressData = updated
}
}
const programmeName = await getProgrammeName(code)
delete gradData.tableStats
delete gradData.graphStats
delete gradData.titles
const data = {
id: code,
programmeName,
status: gradData?.status,
lastUpdated: gradData.lastUpdated,
graduations: gradData,
creditCounts: progressData?.creditCounts,
creditCountsCombo: progressData?.creditCountsCombo,
years: progressData?.years,
}
return res.json(data)
})
export default router
@@ -155,11 +155,6 @@ studyProgrammeToolTips.studyTrackOverviewCombinedProgramme = studyProgrammeToolT
'kentän **All** arvon (lukuun ottamatta *Current status* -kategorian **Graduated bachelor** -saraketta).'
)
studyProgrammeToolTips.studyTrackProgressEvaluationOverview = studyProgrammeToolTips.studyTrackProgress.replace(
'Jos sivun yläosassa on valittuna ”All study rights” (oletus), mukana ovat myös ohjelmaan siirtyneet ja ohjelmasta pois siirtyneet opiskelijat.',
''
)
studyProgrammeToolTips.averageGraduationTimesStudyTracksMaster =
studyProgrammeToolTips.averageGraduationTimesStudyTracks.replace(
'on valmistunut.',
@@ -1,58 +0,0 @@
import { GraduationTimes } from '@/components/FacultyStatistics/TimesAndPaths/GraduationTimes'
export const FacultyGraduations = ({ faculty, graduationStats, groupByStartYear, showMedian, universityMode }) => {
const groupBy = groupByStartYear ? 'byStartYear' : 'byGradYear'
const yearLabel = groupByStartYear ? 'Start year' : 'Graduation year'
const data = graduationStats?.data?.[groupBy].medians
const goals = graduationStats?.data?.goals
const goalExceptions = { ...goals?.exceptions, needed: faculty === 'H30' }
const programmeData = graduationStats?.data?.[groupBy].programmes.medians
const programmeNames = graduationStats?.data?.programmeNames
const classSizes = graduationStats?.data?.classSizes
const commonProps = {
yearLabel,
programmeNames,
showMedian,
classSizes,
goalExceptions,
groupBy,
mode: universityMode ? 'faculty' : 'programme',
}
return (
<div>
<GraduationTimes
data={data?.bachelor}
goal={goals?.bachelor}
level="bachelor"
levelProgrammeData={programmeData?.bachelor}
title="Bachelor"
{...commonProps}
/>
<GraduationTimes
data={data?.bcMsCombo}
goal={goals?.bcMsCombo}
level="bcMsCombo"
levelProgrammeData={programmeData?.bcMsCombo}
title="Bachelor + Master"
{...commonProps}
/>
<GraduationTimes
data={data?.master}
goal={goals?.master}
level="master"
levelProgrammeData={programmeData?.master}
title="Master"
{...commonProps}
/>
<GraduationTimes
data={data?.doctor}
goal={goals?.doctor}
level="doctor"
levelProgrammeData={programmeData?.doctor}
title="Doctor"
{...commonProps}
/>
</div>
)
}
@@ -1,138 +0,0 @@
import { Message } from 'semantic-ui-react'
import { calculateStats, sortProgrammeKeys } from '@/components/FacultyStatistics/facultyHelpers'
import { FacultyBarChart } from '@/components/FacultyStatistics/FacultyProgrammeOverview/FacultyBarChart'
import { FacultyProgressTable } from '@/components/FacultyStatistics/FacultyProgrammeOverview/FacultyProgressTable'
export const FacultyProgress = ({ faculty, progressStats, getDivider }) => {
const bachelorStats = calculateStats(progressStats?.data?.creditCounts?.bachelor, 180)
const bachelorMasterStats = calculateStats(
progressStats?.data?.creditCounts?.bachelorMaster,
faculty === 'H90' ? 360 : 300,
180,
7
)
const masterStats = calculateStats(progressStats?.data?.creditCounts?.master, 120)
const doctorStats = calculateStats(progressStats?.data?.creditCounts?.doctor, 40, 0, 5)
return (
<>
{bachelorStats != null && (
<>
{getDivider('Bachelor', 'BachelorStudentsOfTheFacultyByStartingYear', 'no-infobox')}
<FacultyBarChart
cypress="FacultyBachelorsProgress"
data={{
id: faculty,
stats: bachelorStats.chartStats,
years: progressStats?.data.years,
}}
/>
<FacultyProgressTable
cypress="Table-FacultyBachelorsProgress"
data={bachelorStats.tableStats}
programmeNames={progressStats?.data.programmeNames}
programmeStats={progressStats?.data.bachelorsProgStats}
progressTitles={progressStats?.data.yearlyBachelorTitles}
sortedKeys={sortProgrammeKeys(
Object.keys(progressStats?.data.bachelorsProgStats).map(obj => [
obj,
progressStats?.data?.programmeNames[obj].code,
]),
faculty
).map(listObj => listObj[0])}
titles={bachelorStats.tableTitles}
/>
</>
)}
{bachelorMasterStats != null && (
<>
{getDivider('Bachelor + Master', 'ProgressOfBachelorMaster', 'no-infobox')}
<Message data-cy="FacultyProgrammesShownInfo">
The starting year is the studyright start in the bachelor programme. The credits are computed by the start
date of the bachelor programme and at the moment, they do not include any transferred credits. Thus, in
these statistics some students have fewer credits than in reality.
</Message>
<FacultyBarChart
cypress="FacultyBachelorMastersProgress"
data={{
id: faculty,
stats: bachelorMasterStats.chartStats,
years: progressStats?.data.years,
}}
/>
<FacultyProgressTable
cypress="Table-FacultyBachelorMastersProgress"
data={bachelorMasterStats.tableStats}
programmeNames={progressStats?.data.programmeNames}
programmeStats={progressStats?.data.bcMsProgStats}
progressTitles={progressStats?.data.yearlyBcMsTitles}
sortedKeys={sortProgrammeKeys(
Object.keys(progressStats?.data.bcMsProgStats).map(obj => [
obj,
progressStats?.data?.programmeNames[obj].code,
]),
faculty
).map(listObj => listObj[0])}
titles={bachelorMasterStats.tableTitles}
/>
</>
)}
{masterStats != null && faculty !== 'H90' && (
<>
{getDivider('Master', 'MasterStudentsOfTheFacultyByStartingYear', 'no-infobox')}
<FacultyBarChart
cypress="FacultyMastersProgress"
data={{
id: faculty,
stats: masterStats.chartStats,
years: progressStats?.data.years,
}}
/>
<FacultyProgressTable
cypress="Table-FacultyMastersProgress"
data={masterStats.tableStats}
programmeNames={progressStats?.data.programmeNames}
programmeStats={progressStats?.data.mastersProgStats}
progressTitles={progressStats?.data.yearlyMasterTitles}
sortedKeys={sortProgrammeKeys(
Object.keys(progressStats?.data.mastersProgStats).map(obj => [
obj,
progressStats?.data?.programmeNames[obj].code,
]),
faculty
).map(listObj => listObj[0])}
titles={masterStats.tableTitles}
/>
</>
)}
{doctorStats != null && (
<>
{getDivider('Doctor', 'DoctoralStudentsOfTheFacultyByStartingYear', 'no-infobox')}
<FacultyBarChart
cypress="FacultyDoctoralProgress"
data={{
id: faculty,
stats: doctorStats.chartStats,
years: progressStats?.data.years,
}}
/>
<FacultyProgressTable
cypress="Table-FacultyDoctoralProgress"
data={doctorStats.tableStats}
programmeNames={progressStats?.data.programmeNames}
programmeStats={progressStats?.data.doctoralProgStats}
sortedKeys={sortProgrammeKeys(
Object.keys(progressStats?.data.doctoralProgStats).map(obj => [
obj,
progressStats?.data?.programmeNames[obj].code,
]),
faculty
).map(listObj => listObj[0])}
titles={doctorStats.tableTitles}
/>
</>
)}
</>
)
}
@@ -1,155 +0,0 @@
import { useState } from 'react'
import { Divider, Header, Loader, Message } from 'semantic-ui-react'
import { facultyToolTips } from '@/common/InfoToolTips'
import { InfoBox } from '@/components/InfoBox'
import { useLanguage } from '@/components/LanguagePicker/useLanguage'
import { Toggle } from '@/components/StudyProgramme/Toggle'
import {
useGetFacultiesQuery,
useGetFacultyGraduationTimesQuery,
useGetFacultyProgressStatsQuery,
} from '@/redux/facultyStats'
import { FacultyGraduations } from './FacultyGraduations'
import { FacultyProgress } from './FacultyProgress'
import '@/components/FacultyStatistics/faculty.css'
export const FacultyView = ({ faculty }) => {
const [graduatedGroup, setGraduatedGroup] = useState(false)
const [showMedian, setShowMedian] = useState(false)
const studyProgrammeFilter = 'NEW_STUDY_PROGRAMMES'
const specials = 'SPECIAL_EXCLUDED'
const graduated = graduatedGroup ? 'GRADUATED_EXCLUDED' : 'GRADUATED_INCLUDED'
const { getTextIn } = useLanguage()
const allFaculties = useGetFacultiesQuery()
const faculties = allFaculties?.data
const facultyDetails = faculties && faculty && faculties.find(f => f.code === faculty)
const facultyName = facultyDetails && getTextIn(facultyDetails.name)
const progressStats = useGetFacultyProgressStatsQuery(
{
id: facultyDetails?.id,
studyProgrammeFilter,
specialGroups: specials,
graduated,
},
{ skip: !facultyDetails }
)
const graduationStats = useGetFacultyGraduationTimesQuery(
{ id: facultyDetails?.id, studyProgrammeFilter },
{ skip: !facultyDetails }
)
const getDivider = (title, toolTipText, content, cypress = undefined) => (
<>
<div className="divider">
<Divider data-cy={`Section-${toolTipText}`} horizontal>
{title}
</Divider>
</div>
{content === 'no-infobox' ? null : <InfoBox content={content} cypress={cypress} />}
</>
)
if (allFaculties.isLoading || allFaculties.isFetching) {
return <Loader active style={{ marginTop: '10em' }} />
}
if (!facultyDetails) {
return (
<h3>
{getTextIn({
en: `Faculty “${faculty}” was not found. Please check the address.`,
fi: `Tiedekuntaa ”${faculty}” ei löytynyt. Ole hyvä ja tarkista osoite.`,
})}
</h3>
)
}
const isFetchingOrLoading =
progressStats.isLoading || progressStats.isFetching || graduationStats.isLoading || graduationStats.isFetching
const isError =
(progressStats.isError && graduationStats.isError) ||
(progressStats.isSuccess && !progressStats.data && graduationStats.isSuccess && !graduationStats.data)
if (isError) return <h3>Something went wrong, please try refreshing the page.</h3>
return (
<>
<div style={{ padding: '30px', textAlign: 'center' }}>
<Header>{facultyName}</Header>
<span>{faculty}</span>
</div>
<Message info>
<Message.Header>This view is an abridged version of Oodikone's Faculty Overview</Message.Header>
<p>
In these statistics, all special study rights have been excluded, eg. exchange students and non-degree
students.
</p>
<p>
<b>You can find more statistics on this and all other faculties of the university in main Faculty view. </b>
The full view includes details such as: how many have graduated or started in each faculty and in its
programmes; credits produced by the faculty; populations backgrounds and enrollment statuses. This view
provides statistics both on the whole faculty level and a breakdown of how they are spread among the faculty's
programmes.
</p>
<p>Access the full Faculty view by clicking 'Faculty' in the top navigation bar.</p>
</Message>
<div className="faculty-overview">
{isFetchingOrLoading ? (
<Loader active style={{ marginTop: '15em' }} />
) : (
<div className="programmes-overview">
{progressStats.isSuccess && progressStats.data && (
<>
{getDivider(
'Progress of students of the faculty ',
'bachelorStudentsOfTheFacultyByStartingYear',
facultyToolTips.studentProgress,
'InfoFacultyProgress'
)}
<div className="toggle-container">
<Toggle
cypress="GraduatedToggle"
firstLabel="Graduated included"
secondLabel="Graduated excluded"
setValue={setGraduatedGroup}
toolTips={facultyToolTips.graduatedToggle}
value={graduatedGroup}
/>
</div>
<FacultyProgress faculty={faculty} getDivider={getDivider} progressStats={progressStats} />
</>
)}
{graduationStats.isSuccess && graduationStats.data && (
<>
{getDivider(
'Average graduation times',
'averageGraduationTimes',
facultyToolTips.averageGraduationTimes
)}
<div className="toggle-container">
<Toggle
cypress="GraduationTimeToggle"
firstLabel="Breakdown"
secondLabel="Median times"
setValue={setShowMedian}
value={showMedian}
/>
</div>
<FacultyGraduations
faculty={faculty}
graduationStats={graduationStats}
groupByStartYear={false}
showMedian={showMedian}
/>
</>
)}
</div>
)}
</div>
</>
)
}
@@ -1,216 +0,0 @@
import { useState } from 'react'
import { Divider, Header, Loader, Message, Segment } from 'semantic-ui-react'
import { getTargetCreditsForProgramme } from '@/common'
import { studyProgrammeToolTips } from '@/common/InfoToolTips'
import { calculateStats } from '@/components/FacultyStatistics/facultyHelpers'
import { InfoBox } from '@/components/InfoBox'
import { useLanguage } from '@/components/LanguagePicker/useLanguage'
import { DataTable } from '@/components/StudyProgramme/BasicOverview/DataTable'
import { StackedBarChart } from '@/components/StudyProgramme/BasicOverview/StackedBarChart'
import { BreakdownBarChart } from '@/components/StudyProgramme/BreakdownBarChart'
import { MedianTimeBarChart } from '@/components/StudyProgramme/MedianTimeBarChart'
import { ProgressOfStudents } from '@/components/StudyProgramme/StudyTrackOverview/ProgressOfStudents'
import { Toggle } from '@/components/StudyProgramme/Toggle'
import '@/components/StudyProgramme/studyprogramme.css'
import { useGetEvaluationStatsQuery } from '@/redux/studyProgramme'
export const ProgrammeView = ({ studyprogramme }) => {
const { getTextIn } = useLanguage()
const [showMedian, setShowMedian] = useState(false)
const [academicYear, setAcademicYear] = useState(false)
const [graduated, setGraduated] = useState(false)
const yearType = academicYear ? 'ACADEMIC_YEAR' : 'CALENDAR_YEAR'
const grad = graduated ? 'GRADUATED_EXCLUDED' : 'GRADUATED_INCLUDED'
const statistics = useGetEvaluationStatsQuery({
id: studyprogramme,
yearType,
specialGroups: 'SPECIAL_EXCLUDED',
graduated: grad,
})
const progressStats = calculateStats(statistics?.data?.creditCounts, getTargetCreditsForProgramme(studyprogramme))
if (progressStats?.chartStats) {
progressStats.chartStats.forEach(creditCategory => {
const [total, ...years] = creditCategory.data
creditCategory.data = [total, ...years.reverse()]
})
}
const progressComboStats =
Object.keys(statistics?.data?.creditCountsCombo || {}).length > 0
? calculateStats(statistics.data.creditCountsCombo, getTargetCreditsForProgramme(studyprogramme) + 180)
: null
if (progressComboStats?.chartStats) {
progressComboStats.chartStats.forEach(creditCategory => {
const [total, ...years] = creditCategory.data
creditCategory.data = [total, ...years.reverse()]
})
}
const programmeName = statistics?.data?.programmeName && getTextIn(statistics?.data?.programmeName)
const graduationData = statistics?.data?.graduations
const doCombo = graduationData?.doCombo
const timesData = graduationData?.graduationTimes
const getDivider = (title, toolTipText) => (
<>
<div className="divider">
<Divider data-cy={`Section-${toolTipText}`} horizontal>
{title}
</Divider>
</div>
<InfoBox content={studyProgrammeToolTips[toolTipText]} />
</>
)
const displayMedian = () => (
<>
{doCombo && (
<MedianTimeBarChart
byStartYear={false}
data={graduationData?.comboTimes?.medians}
goal={graduationData?.comboTimes?.goal}
title="Bachelor + Master study right"
/>
)}
<MedianTimeBarChart
byStartYear={false}
data={graduationData?.graduationTimes?.medians}
goal={graduationData?.graduationTimes?.goal}
title={doCombo ? 'Master study right' : ' '}
/>
</>
)
const displayBreakdown = () => (
<>
{doCombo && (
<BreakdownBarChart data={graduationData?.comboTimes?.medians} title="Bachelor + Master study right" />
)}
<BreakdownBarChart data={timesData?.medians} title={doCombo ? 'Master study right' : ' '} />
</>
)
const isFetchingOrLoading = statistics.isLoading || statistics.isFetching
const isError = statistics.isError || (statistics.isSuccess && !statistics.data)
if (isError) return <h3>Something went wrong, please try refreshing the page.</h3>
return (
<>
<div align="center" style={{ padding: '30px' }}>
<Header textAlign="center">{programmeName}</Header>
<span>{studyprogramme}</span>
</div>
<div className="studyprogramme-overview">
{isFetchingOrLoading ? (
<Loader active style={{ marginTop: '10em' }} />
) : (
<Segment className="contentSegment">
<Message info>
<Message.Header>This view is an abridged version of Oodikone's Studyprogramme Overview</Message.Header>
<p style={{ marginTop: '12px' }}>
In these statistics, the following students are excluded: Students whose studyrights{' '}
<b>have been transferred away from or into the program</b> as well as exchange students and non-degree
students.
</p>
<p>
<b>
You can find more statistics on this and other studyprogrammes of the university in main
Studyprogramme Overview.{' '}
</b>
The full view includes details such as: how many have graduated or started in each programme and in its
studytracks; credits produced by the programme; population backgrounds and enrollment statuses.
</p>
<p>
Access the full Studyprogramme Overview by clicking 'Programmes' in the top navigation bar and then
'Overview'. Alternatively, you can select 'Class statistics' to explore studyprogrammes by starting
class with interactive statistics and visualizations.
</p>
<p>
Note that both views have access restrictions. If you can't access either view and feel you should have
access, please contact <a href="mailto:oodikone@helsinki.fi">oodikone@helsinki.fi</a>.
</p>
</Message>
<div>
{getDivider(
'Progress of students of the study programme by starting year',
'studyTrackProgressEvaluationOverview'
)}
<Toggle
cypress="GraduatedToggle"
firstLabel="Graduated included"
secondLabel="Graduated excluded"
setValue={setGraduated}
toolTips={studyProgrammeToolTips.graduatedToggle}
value={graduated}
/>
<ProgressOfStudents
progressComboStats={progressComboStats}
progressStats={progressStats}
track={studyprogramme}
years={statistics.data.years}
/>
{getDivider('Graduation times', 'averageGraduationTimes')}
<div className="toggle-container">
<Toggle
cypress="GraduationTimeToggle"
firstLabel="Breakdown"
secondLabel="Median time"
setValue={setShowMedian}
value={showMedian}
/>
<Toggle
cypress="YearToggle"
firstLabel="Calendar year"
secondLabel="Academic year"
setValue={setAcademicYear}
toolTips={studyProgrammeToolTips.yearToggle}
value={academicYear}
/>
</div>
<div className={`section-container${doCombo ? '' : '-centered'}`}>
{showMedian ? displayMedian() : displayBreakdown()}
</div>
{graduationData?.programmesBeforeOrAfterGraphStats?.length !== 0 && (
<>
{getDivider(
studyprogramme.includes('KH')
? 'Primary master programme studies after this programme'
: 'Primary bachelor programme studies before this programme',
'programmesBeforeOrAfter'
)}
<div className="section-container">
<StackedBarChart
cypress="ProgrammesBeforeOrAfter"
data={graduationData?.programmesBeforeOrAfterGraphStats.map(programme => ({
...programme,
name: getTextIn(programme.name),
}))}
labels={graduationData?.years}
wideTable
/>
<DataTable
data={graduationData?.programmesBeforeOrAfterTableStats.map(programme =>
programme.with(2, getTextIn(programme[2]))
)}
titles={graduationData?.programmesBeforeOrAfterTitles}
wideTable
/>
</div>
</>
)}
</div>
</Segment>
)}
</div>
</>
)
}
@@ -1,153 +0,0 @@
import { orderBy } from 'lodash'
import { useState } from 'react'
import { Link } from 'react-router-dom'
import { Divider, Header, Loader, Message } from 'semantic-ui-react'
import { useTitle } from '@/common/hooks'
import { facultyToolTips } from '@/common/InfoToolTips'
import '@/components/FacultyStatistics/faculty.css'
import { InfoBox } from '@/components/InfoBox'
import { useLanguage } from '@/components/LanguagePicker/useLanguage'
import { Toggle } from '@/components/StudyProgramme/Toggle'
import { useGetAuthorizedUserQuery } from '@/redux/auth'
import { useGetAllFacultiesGraduationStatsQuery, useGetAllFacultiesProgressStatsQuery } from '@/redux/facultyStats'
import { FacultyGraduations } from './FacultyGraduations'
import { FacultyProgress } from './FacultyProgress'
export const UniversityView = ({ isEvaluationOverview }) => {
useTitle('University')
const [graduatedGroup, setGraduatedGroup] = useState(false)
const [medianMode, setMedianMode] = useState(false)
const [excludeSpecials, setIncludeSpecials] = useState(isEvaluationOverview)
const { fullAccessToStudentData, roles } = useGetAuthorizedUserQuery()
const userHasFacultyRights =
fullAccessToStudentData || roles.includes('facultyStatistics') || roles.includes('katselmusViewer')
const graduated = graduatedGroup ? 'GRADUATED_EXCLUDED' : 'GRADUATED_INCLUDED'
const progressStats = useGetAllFacultiesProgressStatsQuery({
graduated,
includeSpecials: !excludeSpecials,
})
const { getTextIn } = useLanguage()
const graduationStats = useGetAllFacultiesGraduationStatsQuery()
const getDivider = (title, toolTipText, content, cypress = undefined) => (
<>
<div className="divider">
<Divider data-cy={`Section-${toolTipText}`} horizontal>
{title}
</Divider>
</div>
{content === 'no-infobox' ? null : <InfoBox content={content} cypress={cypress} />}
</>
)
if (graduationStats.isLoading || graduationStats.isFetching || progressStats.isFetching || progressStats.isLoading) {
return <Loader active style={{ marginTop: '10em' }} />
}
const getMessage = () => {
if (!isEvaluationOverview) {
return (
<Message info>
<p>Programme MH90_001 (Veterinary medicine bachelor + licentiate) is currently excluded.</p>
</Message>
)
}
return (
<Message info>
<Message.Header>This view is a combined version of Oodikone's Faculty Evaluation Overview</Message.Header>
<p>
In these statistics, <b>all special study rights have been excluded</b>, eg. exchange students and non-degree
students.
</p>
<p>Access the full Faculty view of individual faculties by clicking 'Faculty' in the top navigation bar.</p>
<p>
<b>Veterinary medicine bachelor + licentiate (MH90_001) is disabled</b> and not visible in the progress stats.
It is visible in graduation times, but notice that it is found in "Bachelor + Master" category although it has
a target time of 6 years, whereas the other degrees in that category have a target of 5 years.
</p>
</Message>
)
}
const isError =
progressStats.isError ||
(progressStats.isSuccess && !progressStats.data) ||
graduationStats.isError ||
!graduationStats.data
if (isError) return <h3>Something went wrong, please try refreshing the page.</h3>
const allFaculties = Object.values(progressStats.data.programmeNames)
return (
<>
<div style={{ padding: '30px', textAlign: 'center' }}>
<Header>University-level view</Header>
</div>
{getMessage()}
<div>
{userHasFacultyRights && isEvaluationOverview && (
<div>
<p>
<b>Click here to open the corresponding view for an individual faculty</b>
</p>
<div className="facultyLinkBox">
{orderBy(allFaculties, 'code').map(faculty => (
<span key={faculty.code}>
<Link to={`/evaluationoverview/faculty/${faculty.code}`}>{`${
faculty.code
} ${getTextIn(faculty)}`}</Link>
</span>
))}
</div>
</div>
)}
</div>
<div className="faculty-overview">
<div className="programmes-overview">
{getDivider(
'Progress of students of the university',
'BachelorStudentsOfTheFacultyByStartingYear',
facultyToolTips.studentProgress,
'InfoFacultyProgress'
)}
<div className="toggle-container">
<Toggle
cypress="GraduatedToggle"
firstLabel="Graduated included"
secondLabel="Graduated excluded"
setValue={setGraduatedGroup}
toolTips={facultyToolTips.graduatedToggle}
value={graduatedGroup}
/>
{!isEvaluationOverview && (
<Toggle
cypress="StudentToggle"
firstLabel="All study rights"
secondLabel="Special study rights excluded"
setValue={() => setIncludeSpecials(!excludeSpecials)}
toolTips={facultyToolTips.studentToggle}
value={excludeSpecials}
/>
)}
</div>
<FacultyProgress faculty="ALL" getDivider={getDivider} progressStats={progressStats} />
</div>
{getDivider('Average graduation times', 'AverageGraduationTimes', facultyToolTips.averageGraduationTimes)}
<div className="toggle-container">
<Toggle
cypress="GraduationTimeToggle"
firstLabel="Breakdown"
secondLabel="Median times"
setValue={() => setMedianMode(!medianMode)}
value={medianMode}
/>
</div>
<FacultyGraduations
graduationStats={graduationStats}
groupByStartYear={false}
showMedian={medianMode}
universityMode
/>
</div>
</>
)
}
@@ -1,28 +0,0 @@
import { Redirect, useParams } from 'react-router-dom'
import { Segment } from 'semantic-ui-react'
import { useTitle } from '@/common/hooks'
import { FacultyView } from './FacultyView'
import { ProgrammeView } from './ProgrammeView'
import { UniversityView } from './UniversityView'
export const EvaluationOverview = () => {
const { id, level } = useParams()
useTitle('Evaluation overview')
if (!['programme', 'faculty', 'university'].includes(level) || (level !== 'university' && !id)) {
return <Redirect to="/" />
}
const levelToComponent = {
programme: <ProgrammeView studyprogramme={id} />,
faculty: <FacultyView faculty={id} />,
university: <UniversityView isEvaluationOverview />,
}
return (
<div className="segmentContainer">
<Segment className="contentSegment">{levelToComponent[level]}</Segment>
</div>
)
}
@@ -36,9 +36,6 @@ export const ProtectedRoute = ({
if (path.includes('languagecenterview')) {
return iamGroups.includes('grp-kielikeskus-esihenkilot')
}
if (path.includes('evaluationoverview')) {
return location.pathname.includes('university') ? true : hasRequiredRoles
}
if (path.includes('teachers')) {
return hasRequiredRoles || hasFullAccessToTeacherData(roles, iamGroups)
}
@@ -8,7 +8,6 @@ import { CoursePopulation } from '@/components/CoursePopulation'
import { CourseStatistics } from '@/components/CourseStatistics'
import { CustomOpenUniPopulation } from '@/components/CustomOpenUniPopulation'
import { CustomPopulation } from '@/components/CustomPopulation'
import { EvaluationOverview } from '@/components/EvaluationOverview'
import { FacultyStatistics } from '@/components/FacultyStatistics'
import { LanguageCenterView } from '@/components/LanguageCenterView'
import { PopulationStatistics } from '@/components/PopulationStatistics'
@@ -38,7 +37,6 @@ const routes = {
studyGuidanceGroups: '/studyguidancegroups/:groupid?',
faculties: '/faculties/:facultyId?',
customOpenUniPopulation: '/openunipopulation',
evaluationOverview: '/evaluationoverview/:level?/:id?',
university: '/university',
completedCoursesSearch: '/completedcoursessearch',
languageCenterView: '/languagecenterview',
@@ -121,11 +119,6 @@ export const Routes = () => (
requiredRoles={['admin']}
/>
)}
<ProtectedRoute
component={EvaluationOverview}
path={routes.evaluationOverview}
requiredRoles={['admin', 'fullSisuAccess', 'katselmusViewer']}
/>
<ProtectedRoute component={University} path={routes.university} />
<ProtectedRoute
component={CloseToGraduation}
@@ -18,10 +18,6 @@ const studyProgrammeApi = RTKApi.injectEndpoints({
codes
)}&isAcademicYear=${isAcademicYear}&includeSpecials=${specialGroups}`,
}),
getEvaluationStats: builder.query({
query: ({ id, yearType, specialGroups, graduated }) =>
`/v2/studyprogrammes/${id}/evaluationstats?year_type=${yearType}&special_groups=${specialGroups}&graduated=${graduated}`,
}),
getGraduationStats: builder.query({
query: ({ id, yearType, specialGroups, combinedProgramme }) =>
`/v2/studyprogrammes/${id}/graduationstats?year_type=${yearType}&special_groups=${specialGroups}&combined_programme=${combinedProgramme}`,
@@ -53,7 +49,6 @@ export const {
useGetBasicStatsQuery,
useGetColorizedTableCourseStatsQuery,
useGetCreditStatsQuery,
useGetEvaluationStatsQuery,
useGetGraduationStatsQuery,
useGetStudyTrackStatsQuery,
useGetProgrammeCoursesStatsQuery,