NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name Better Bb UBN course list
// @version 2024-02-06
// @description Show all courses in year/semester groupings and ordered by title, for Bb UBN
// @author asameshimae
// @match https://online.manchester.ac.uk/ultra/course
// @icon https://www.google.com/s2/favicons?sz=64&domain=manchester.ac.uk
// @updateURL https://openuserjs.org/meta/asameshimae/Better_Bb_UBN_course_list.meta.js
// @downloadURL https://openuserjs.org/install/asameshimae/Better_Bb_UBN_course_list.user.js
// @grant none
// @license MIT
// ==/UserScript==
/* jshint esversion: 8 */
async function init() {
document.querySelector('#course-columns-current').textContent=''
let sems = ['1SE','2SE','1YR']
let semHuman = sem=>['1st Semester','2nd Semester','Full Year'][sems.indexOf(sem)]
let target = document.querySelector('#course-columns-current')
let r = await fetch('https://online.manchester.ac.uk/learn/api/v1/users/me/memberships?limit=1000&expand=course.effectiveAvailability')
let j = await r.json()
let coursesYears = j.results.filter(e=>e.course.courseId.match(/\-1\d\d1\-(1SE|2SE|1YR)\-/))
let coursesFixed = j.results.filter(e=>!e.course.courseId.match(/\-1\d\d1\-(1SE|2SE|1YR)\-/))
let years = [...new Set(coursesYears.map(e=>e.course.courseId.split('-')[3]))].sort().reverse()
let table = document.createElement('table')
target.append(table)
let tr = document.createElement('tr')
tr.style.verticalAlign='top'
table.append(tr)
let td1 = document.createElement('td')
tr.append(td1)
years.forEach(yearCode=>{
let acYearStart2=(yearCode.substr(1,2))
let yearHuman=`20${acYearStart2}-${(+acYearStart2+1).toString().padStart(2,'0')}`
let h2 = document.createElement('h2')
h2.append(document.createTextNode(yearHuman))
td1.append(h2)
let thisYearCourses = coursesYears.filter(e=>e.course.courseId.split('-')[3]===yearCode)
for(let sem of sems) {
let thisSemCourses = thisYearCourses.filter(e=>e.course.courseId.split('-')[4]===sem)
if(thisSemCourses.length) {
let thisSemCourseNames = thisSemCourses.map(e=>e.course.displayName).sort()
let h3 = document.createElement('h3')
h3.append(document.createTextNode(semHuman(sem)))
td1.append(h3)
let ul = document.createElement('ul')
thisSemCourseNames.forEach(name=>{
let thisCourseUrl = thisSemCourses.find(e=>e.course.displayName===name).course.externalAccessUrl
let li = document.createElement('li')
let a = document.createElement('a')
a.append(document.createTextNode(name))
a.href = thisCourseUrl
li.append(a)
ul.append(li)
})
td1.append(ul)
}
}
})
let td2 = document.createElement('td')
td2.style.paddingLeft='1em'
tr.append(td2)
let h2 = document.createElement('h2')
h2.append(document.createTextNode('Organisations'))
td2.append(h2)
let ul = document.createElement('ul')
let orgCourseNames = coursesFixed.map(e=>e.course.displayName).sort()
orgCourseNames.forEach(name=>{
let thisCourseUrl = coursesFixed.find(e=>e.course.displayName===name).course.externalAccessUrl
let li = document.createElement('li')
let a = document.createElement('a')
a.append(document.createTextNode(name))
a.href = thisCourseUrl
li.append(a)
ul.append(li)
})
td2.append(ul)
}
var i
(function(){
i = setInterval(()=>{
let test = document.querySelector('#course-columns-current')
if(test) {
clearInterval(i)
init()
}
},500)
})()