diff --git a/services/oodikone2-frontend/src/components/CourseStatistics/ResultTabs/Panes/passRate.jsx b/services/oodikone2-frontend/src/components/CourseStatistics/ResultTabs/Panes/passRate.jsx
index 0a05b5f42f..a4095d3e10 100644
--- a/services/oodikone2-frontend/src/components/CourseStatistics/ResultTabs/Panes/passRate.jsx
+++ b/services/oodikone2-frontend/src/components/CourseStatistics/ResultTabs/Panes/passRate.jsx
@@ -33,7 +33,6 @@ const getPassRateCumSeriesFromStats = (stats) => {
],
relative: [
// eslint-disable-next-line no-unused-vars
- getDataObject(`all`, all.map(_ => 1), 'a'),
getDataObject(`passed`, passed.map(absoluteToRelative(all)), 'b'),
getDataObject(`failed`, failed.map(absoluteToRelative(all)), 'c')
]
@@ -73,7 +72,6 @@ const getPassRateStudSeriesFromStats = (stats) => {
],
relative: [
// eslint-disable-next-line no-unused-vars
- getDataObject(`all`, all.map(_ => 1), 'a'),
getDataObject(` passed on first try`, passedFirst.map(absoluteToRelative(all)), 'b'),
getDataObject(`passed after retry`, passedRetry.map(absoluteToRelative(all)), 'b'),
getDataObject(`failed on first try`, failedFirst.map(absoluteToRelative(all)), 'c'),
@@ -95,8 +93,8 @@ const PassRate = ({ primary, comparison, viewMode, isRelative = false }) => {
const maxPassRateVal = isRelative ? 1 : getMaxValueOfSeries(passGraphSerie.absolute)
const graphOptionsFn = isCumulativeMode ? passRateCumGraphOptions : passRateStudGraphOptions
- const primaryGraphOptions = comparison ? graphOptionsFn(statYears, maxPassRateVal, 'Primary pass rate chart') : graphOptionsFn(statYears, maxPassRateVal, 'Pass rate chart')
- const comparisonGraphOptions = graphOptionsFn(statYears, maxPassRateVal, 'Comparison pass rate chart')
+ const primaryGraphOptions = comparison ? graphOptionsFn(statYears, maxPassRateVal, 'Primary pass rate chart', isRelative) : graphOptionsFn(statYears, maxPassRateVal, 'Pass rate chart', isRelative)
+ const comparisonGraphOptions = graphOptionsFn(statYears, maxPassRateVal, 'Comparison pass rate chart', isRelative)
return (
<>
diff --git a/services/oodikone2-frontend/src/components/CourseStatistics/ResultTabs/index.jsx b/services/oodikone2-frontend/src/components/CourseStatistics/ResultTabs/index.jsx
index 43d49f36ce..ab16318d6f 100644
--- a/services/oodikone2-frontend/src/components/CourseStatistics/ResultTabs/index.jsx
+++ b/services/oodikone2-frontend/src/components/CourseStatistics/ResultTabs/index.jsx
@@ -41,7 +41,7 @@ class ResultTabs extends Component {
comparison={comparison}
primary={primary}
viewMode={viewMode}
- isRelative={isRelative}
+ isRelative={isRelative && comparison}
/>)
},
{
@@ -51,7 +51,7 @@ class ResultTabs extends Component {
comparison={comparison}
primary={primary}
viewMode={viewMode}
- isRelative={isRelative}
+ isRelative={isRelative && comparison}
/>)
}
]
@@ -125,6 +125,7 @@ class ResultTabs extends Component {
this.setState({ isRelative: !this.state.isRelative })}
/>
diff --git a/services/oodikone2-frontend/src/components/PopulationFilters/TagFilter.jsx b/services/oodikone2-frontend/src/components/PopulationFilters/TagFilter.jsx
index 32d67965ba..50fdbeb3c8 100644
--- a/services/oodikone2-frontend/src/components/PopulationFilters/TagFilter.jsx
+++ b/services/oodikone2-frontend/src/components/PopulationFilters/TagFilter.jsx
@@ -12,6 +12,7 @@ import { tagFilter } from '../../populationFilters'
const TagFilter = ({ setPopulationFilterAction, removePopulationFilterAction, filter, samples }) => {
const [options, setOptions] = useState([])
const [selectedTag, setSelectedTag] = useState()
+ const [selectedComp, setSelectedComp] = useState()
const createOptions = () => {
const tags = samples.map(s => s.tags.map(t => ({ tagname: t.tag.tagname, tag_id: t.tag.tag_id })))
@@ -26,13 +27,16 @@ const TagFilter = ({ setPopulationFilterAction, removePopulationFilterAction, fi
}, [])
const handleFilter = () => {
- setPopulationFilterAction(tagFilter({ tag: selectedTag }))
+ setPopulationFilterAction(tagFilter({ tag: selectedTag, comp: selectedComp }))
+ }
+
+ const handleCompChange = (e, { value }) => {
+ setSelectedComp(value)
}
const handleChange = (e, { value }) => {
- // any better solutions?
- const selection = options.filter(tag => tag.value === value)
- setSelectedTag(selection[0])
+ const selection = options.find(tag => tag.value === value)
+ setSelectedTag(selection)
}
const clearFilter = () => {
removePopulationFilterAction(filter.id)
@@ -47,7 +51,17 @@ const TagFilter = ({ setPopulationFilterAction, removePopulationFilterAction, fi
/>
-
+
+
+
+
+
+
+
- Students that have a tag {filter.params.text}
+ Students that {filter.params.comp ? 'have' : 'don\'t have'} a tag {filter.params.text}
diff --git a/services/oodikone2-frontend/src/components/PopulationStudents/index.jsx b/services/oodikone2-frontend/src/components/PopulationStudents/index.jsx
index 8018e13012..8c719dbe56 100644
--- a/services/oodikone2-frontend/src/components/PopulationStudents/index.jsx
+++ b/services/oodikone2-frontend/src/components/PopulationStudents/index.jsx
@@ -360,7 +360,7 @@ class PopulationStudents extends Component {
),
parent: true,
- headerProps: { colSpan: labelToMandatoryCourses[e.label].length, title: e.label }
+ headerProps: { colSpan: labelToMandatoryCourses[e.label].length, title: e.label, ordernumber: e.orderNumber }
}))
)
}
diff --git a/services/oodikone2-frontend/src/components/SortableTable/index.jsx b/services/oodikone2-frontend/src/components/SortableTable/index.jsx
index 20970df0e5..bc5bb5083d 100644
--- a/services/oodikone2-frontend/src/components/SortableTable/index.jsx
+++ b/services/oodikone2-frontend/src/components/SortableTable/index.jsx
@@ -63,20 +63,24 @@ class SortableTable extends Component {
const { collapsed } = this.state
const defaultColumnCount = showNames ? 6 : 3
if (collapsed) {
- const collapsedKeys = collapsed.map(c => c.key)
- return collapsedKeys.reduce((acc, curr) => {
- const previousCols = columns.filter(c => c.key < curr)
+ const collapsedOrderNumbers = collapsed.map(c => c.headerProps.ordernumber)
+ return collapsedOrderNumbers.reduce((acc, curr) => {
+ const previousCols = columns.filter(c => c.headerProps && c.headerProps.ordernumber < curr)
const sumOfPreviousColSpans = previousCols.reduce((a, b) => a + b.headerProps.colSpan, 0)
return [
...acc,
- sumOfPreviousColSpans + columns.find(c => c.key === curr).headerProps.colSpan + defaultColumnCount]
+ sumOfPreviousColSpans + columns.find(c => c.headerProps && c.headerProps.ordernumber === curr).headerProps.colSpan + defaultColumnCount]
}, [])
}
return []
}
const { tableProps, getRowProps, columns, getRowKey, collapsingHeaders } = this.props
const { selected, direction, collapsed } = this.state
- const columnsWithCollapsedHeaders = collapsingHeaders ? [...columns.filter(c => (c.headerProps && (!collapsed.map(cell => cell.headerProps.title).includes(c.headerProps.title) && !c.collapsed))), ...this.state.collapsed].sort((a, b) => a.key - b.key) : columns
+ const columnsWithCollapsedHeaders = collapsingHeaders ? [...columns.filter(c => (
+ c.headerProps && (!collapsed.map(cell => cell.headerProps.title).includes(c.headerProps.title) && !c.collapsed))),
+ ...this.state.collapsed].sort((a, b) => a.headerProps.ordernumber - b.headerProps.ordernumber)
+ :
+ columns
const sortDirection = name => (selected === name ? direction : null)
diff --git a/services/oodikone2-frontend/src/components/TagStudent/index.jsx b/services/oodikone2-frontend/src/components/TagStudent/index.jsx
index 00e78445b0..ec29e06330 100644
--- a/services/oodikone2-frontend/src/components/TagStudent/index.jsx
+++ b/services/oodikone2-frontend/src/components/TagStudent/index.jsx
@@ -26,13 +26,14 @@ const TagStudent = ({
useEffect(() => {
setTags(tags)
- const tagIds = studentstags.map(t => ({ id: t.id, tag_id: t.tag.tag_id }))
- setStudentsTagIds(tagIds)
+ const initialStudentsTagIds = studentstags.map(t => ({ id: t.id, tag_id: t.tag.tag_id }))
+ const tagIds = studentstags.map(t => t.tag.tag_id)
const initialTagOptions = tags.filter(tag => !tagIds.includes(tag.tag_id)).map(tag => ({
key: tag.tag_id,
text: tag.tagname,
value: tag.tag_id
}))
+ setStudentsTagIds(initialStudentsTagIds)
setTagOptions(initialTagOptions)
}, [])
diff --git a/services/oodikone2-frontend/src/constants/index.js b/services/oodikone2-frontend/src/constants/index.js
index 048dbd87d2..b20c212984 100644
--- a/services/oodikone2-frontend/src/constants/index.js
+++ b/services/oodikone2-frontend/src/constants/index.js
@@ -88,11 +88,11 @@ export const API_DATE_FORMAT = 'YYYY.MM.DD'
export const TOKEN_NAME = window.location.pathname.includes('staging') ? 'staging_token' : window.location.pathname.includes('/testing') ? 'testing_token' : 'token' //eslint-disable-line
-export const passRateCumGraphOptions = (categories, max, title) => ({
+export const passRateCumGraphOptions = (categories, max, title, skipFirstColor) => ({
chart: {
type: 'column'
},
- colors: [chartblue, green, red],
+ colors: skipFirstColor ? [green, red] : [chartblue, green, red],
title: {
text: title
@@ -119,11 +119,11 @@ export const passRateCumGraphOptions = (categories, max, title) => ({
}
})
-export const passRateStudGraphOptions = (categories, max, title) => ({
+export const passRateStudGraphOptions = (categories, max, title, skipFirstColor) => ({
chart: {
type: 'column'
},
- colors: [chartblue, chartlgreen, chartdarkg, chartlred, chartdarkred],
+ colors: skipFirstColor ? [chartlgreen, chartdarkg, chartlred, chartdarkred] : [chartblue, chartlgreen, chartdarkg, chartlred, chartdarkred],
title: {
text: title
diff --git a/services/oodikone2-frontend/src/populationFilters/index.js b/services/oodikone2-frontend/src/populationFilters/index.js
index 588befbbc7..c3392c4e6b 100644
--- a/services/oodikone2-frontend/src/populationFilters/index.js
+++ b/services/oodikone2-frontend/src/populationFilters/index.js
@@ -255,16 +255,20 @@ export const gradeMeanFilter = (params) => {
export const tagFilter = (params) => {
const { text, value } = params.tag
+ const { comp } = params
return ({
id: uuidv4(),
type: 'TagFilter',
params: {
text,
- value
+ comp
},
filter: (student) => {
const studentTagIds = student.tags.map(t => t.tag.tag_id)
- return studentTagIds.includes(value)
+ if (comp) {
+ return studentTagIds.includes(value)
+ }
+ return !studentTagIds.includes(value)
}
})
}
diff --git a/services/oodikone2-userservice/src/database/migrations/20190619_populate_faculties.js b/services/oodikone2-userservice/src/database/migrations/20190619_populate_faculties.js
deleted file mode 100644
index 15576fef02..0000000000
--- a/services/oodikone2-userservice/src/database/migrations/20190619_populate_faculties.js
+++ /dev/null
@@ -1,35 +0,0 @@
-const valtiotieteellisen_ohjelmat = [
- 'KH40_001', // Filosofian kandiohjelma
- 'KH70_001', // Politiikan ja viestinnän kandiohjelma
- 'KH70_002', // Yhteiskunnallisen muutoksen kandiohjelma
- 'KH70_003', // Sosiaalitieteiden kandiohjelma
- 'KH70_004', // Taloustieteen kandiohjelma
- 'MH50_001', // Matematiikan ja tilastotieteen maisteriohjelma
- 'MH50_013', // Kaupunkitutkimuksen ja suunnittelun maisteriohjelma
- 'MH57_005', // Ympäristömuutoksen ja globaalin kestävyyden maisteriohjelma
- 'MH70_001', // Filosofian maisteriohjelma
- 'MH70_002', // Politiikan ja viestinnän maisteriohjelma
- 'MH70_003', // Globaalin politiikan ja kommunikaation maisteriohjelma
- 'MH70_004', // Yhteiskunnallisen muutoksen maisteriohjelma
- 'MH70_005', // Nyky-yhteiskunnan tutkimuksen maisteriohjelma
- 'MH70_006', // Euroopan ja pohjoismaiden tutkimuksen maisteriohjelma (European and Nordic Studies)
- 'MH70_007', // Yhteiskuntatieteiden maisteriohjelma
- 'MH70_008', // Sosiaalitieteiden maisteriohjelma
- 'MH70_009', // Taloustieteen maisteriohjelma
- 'MH70_010' // International Masters in Economy, State & Society
-]
-
-module.exports = {
- up: async (queryInterface, Sequelize) => {
- await queryInterface.bulkInsert(
- 'faculty_programmes',
- valtiotieteellisen_ohjelmat.map(code => ({
- faculty_code: 'H70',
- programme_code: code,
- createdAt: new Date(),
- updatedAt: new Date()
- }))
- )
- },
- down: async () => {}
-}
diff --git a/services/oodikone2-userservice/src/database/migrations/20190626_populate_faculty_programmes.js b/services/oodikone2-userservice/src/database/migrations/20190626_populate_faculty_programmes.js
new file mode 100644
index 0000000000..2e4526e132
--- /dev/null
+++ b/services/oodikone2-userservice/src/database/migrations/20190626_populate_faculty_programmes.js
@@ -0,0 +1,153 @@
+// Data from helsinki.fi/rapo -> opiskelijat -> Koulutusohjelmat -> Opiskelijat -> Valitse tiedekunta ja/tai koulutusohjelma
+const faculty_to_programmes = {
+ H10: [
+ 'MH10_001',
+ 'MH40_011',
+ 'KH10_001',
+ ],
+ H20: [
+ 'KH20_001',
+ 'MH20_001',
+ 'MH20_002',
+ ],
+ H30: [
+ 'KH30_001',
+ 'KH30_002',
+ 'MH30_002',
+ 'MH30_003',
+ 'MH30_004',
+ 'MH30_005',
+ 'MH30_001',
+ ],
+ H40: [
+ 'KH40_001',
+ 'KH40_002',
+ 'KH40_003',
+ 'KH40_004',
+ 'KH40_005',
+ 'KH40_006',
+ 'MH40_001',
+ 'MH40_002',
+ 'MH40_003',
+ 'MH40_004',
+ 'MH40_005',
+ 'MH40_006',
+ 'MH40_007',
+ 'MH40_008',
+ 'MH40_009',
+ 'MH40_010',
+ 'MH40_011',
+ 'MH40_012',
+ 'MH40_013',
+ 'MH40_014',
+ 'MH40_015',
+ 'MH70_001',
+ 'MH70_006',
+ ],
+ H50: [
+ 'KH50_001',
+ 'KH50_002',
+ 'KH50_003',
+ 'KH50_004',
+ 'KH50_005',
+ 'KH50_006',
+ 'KH50_007',
+ 'MH50_001',
+ 'MH50_002',
+ 'MH50_003',
+ 'MH50_004',
+ 'MH50_005',
+ 'MH50_006',
+ 'MH50_007',
+ 'MH50_008',
+ 'MH50_009',
+ 'MH50_010',
+ 'MH50_011',
+ 'MH50_012',
+ 'MH50_013',
+ ],
+ H55: [
+ 'KH55_001',
+ 'MH55_001',
+ ],
+ H57: [
+ 'KH57_001',
+ 'KH57_002',
+ 'KH57_003',
+ 'MH50_002',
+ 'MH50_013',
+ 'MH57_001',
+ 'MH57_002',
+ 'MH57_003',
+ 'MH57_004',
+ 'MH57_005',
+ 'MH80_007',
+ ],
+ H60: [
+ 'KH60_001',
+ 'MH60_001',
+ ],
+ H70: [
+ 'KH40_001',
+ 'KH50_001',
+ 'KH70_001',
+ 'KH70_002',
+ 'KH70_003',
+ 'KH70_004',
+ 'MH50_001',
+ 'MH57_005',
+ 'MH70_001',
+ 'MH70_002',
+ 'MH70_003',
+ 'MH70_004',
+ 'MH70_005',
+ 'MH70_006',
+ 'MH70_007',
+ 'MH70_008',
+ 'MH70_009',
+ 'MH70_010',
+ ],
+ H74: [
+ 'KH74_001',
+ ],
+ H80: [
+ 'KH57_002',
+ 'KH80_001',
+ 'KH80_002',
+ 'KH80_003',
+ 'KH80_004',
+ 'MH57_002',
+ 'MH57_003',
+ 'MH57_005',
+ 'MH80_001',
+ 'MH80_002',
+ 'MH80_003',
+ 'MH80_004',
+ 'MH80_005',
+ 'MH80_006',
+ 'MH80_007',
+ ],
+ H90: [
+ 'KH90_001',
+ ],
+}
+
+module.exports = {
+ up: async (queryInterface, Sequelize) => {
+ await queryInterface.bulkDelete(
+ 'faculty_programmes'
+ )
+ for (const faculty of Object.keys(faculty_to_programmes)) {
+ await queryInterface.bulkInsert(
+ 'faculty_programmes',
+ faculty_to_programmes[faculty].map(programme => ({
+ faculty_code: faculty,
+ programme_code: programme,
+ createdAt: new Date(),
+ updatedAt: new Date()
+ }))
+ )
+ }
+ },
+ down: async () => {}
+}