Calculate the point total of your grades in Smartschool. This library may only be used by ChromeExtensions.
此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.greasyfork.org/scripts/481384/1307288/Grid%20Smartschool.js
// @license This library may only be used by ChromeExtensions!!! // Grid // License: https://raw.githubusercontent.com/EbbDrop/SmarterSmartchool/main/LICENSE let wideToolbarCallback = function (mutationsList, _) { for (let mutation of mutationsList) { if (mutation.type == 'childList' && mutation.removedNodes.length != 0) { for (const node of mutation.removedNodes) { if (node.id == "show-grid2") { $(".wide-toolbar").append(node); } } } } }; let wideToolbarObserver = new MutationObserver(wideToolbarCallback); let smscMainCallback = function (mutationsList, observer) { for (let mutation of mutationsList) { if (mutation.type == 'childList' && mutation.addedNodes.length == 1 && mutation.addedNodes[0].classList.contains('wide-toolbar')) { observer.disconnect(); wideToolbarObserver.observe($('.wide-toolbar')[0], { attributes: false, childList: true, subtree: false }); onLoad(); addButton(); } } }; let smscMainObserver = new MutationObserver(smscMainCallback); smscMainObserver.observe($('#smscMain')[0], { attributes: false, childList: true, subtree: false }); function totalToStr(total_numerator, total_denominator) { return (Math.round(total_numerator / total_denominator * 1000) / 10).toString() + '%'; } function addButton() { var imageLink = "https://www.smartschool.be/wp/wp-content/uploads/2018/09/smartschool_app_logo_100x100.png" $(".wide-toolbar").append( $("<button/>") .attr("id", "show-grid2") .addClass("wide-toolbar__item") .append( $("<img/>") .addClass("wide-toolbar__item__icon") .attr("src", imageLink) ) .append( $("<span/>").addClass("wide-toolbar__item__name").text("Grid") ) .click(openGrid) ); } function makeGrid() { let loading = $("<h3>Loading!</h3>"); fetch('/results/api/v1/evaluations?itemsOnPage=500').then(r => r.json()).then(results => { let data = {}; let course_to_graphic = {}; let latest_period = null; for (const result of results) { if (result["type"] != "normal") { continue; } let period = result["period"]["name"]; if (latest_period === null) { latest_period = period; } if (!(period in data)) { data[period] = {}; } period = data[period]; for (const course of result["courses"]) { course_to_graphic[course["name"]] = course["graphic"]; const course_name = course["name"]; if (!(course_name in period)) { period[course_name] = []; } period[course_name].push({ "date": result["date"], "name": result["name"], "graphic": result["graphic"] }); } } for (let period_name of Object.keys(data)) { let period = data[period_name]; let grid = $("<div/>").attr("id", "period").append($("<h2/>").text(period_name + ":")); let table = $("<table/>").attr("id", "result-table"); let longest = 0; for (let [_, course] of Object.entries(period)) { course.sort((a, b) => { return a["date"].localeCompare(b["date"]); }); if (course.length > longest) { longest = course.length; } } // Add row for disclamer let disc_row = $("<tr/>"); for (let i = 0; i < longest + 1; i++) { disc_row.append($("<td/>").addClass("hidden-cell")); } disc_row.append($("<td/>").attr("id", "disclamer").text("!")); table.append(disc_row); let overallTotalNumerator = 0; let overallTotalDenominator = 0; for (let [course_name, course] of Object.entries(period)) { let row = $("<tr/>"); if (course_to_graphic[course_name].type == "icon") { row.append($("<th/>").append( $("<span/>") .addClass("icon-label icon-label--24 smsc-svg--" + course_to_graphic[course_name]["value"] + "--24") .text(course_name) )); } else { row.append($("<th/>").text(course_name)); } let total_numerator = 0; let total_denominator = 0; for (const result of course) { const desc = result["graphic"]["description"]; const color = result["graphic"]["color"]; const name = result["name"]; row.append($("<td/>").addClass("c-" + color + "-combo--100").attr({ id: "details", content: name }).text(desc)); let match = desc.match(/^([\d\,\.]+)\/([\d\,\.]+)$/); if (match) { total_numerator += parseFloat(match[1].replace(',', '.')); total_denominator += parseFloat(match[2].replace(',', '.')); } } for (let i = 0; i < longest - course.length; i++) { row.append($("<td/>")); } let last_cell = $("<td/>").addClass("total"); if (total_denominator != 0) { last_cell.text(totalToStr(total_numerator, total_denominator)); if (total_numerator / total_denominator < 0.5) { last_cell.addClass('is-low'); } } row.append(last_cell); overallTotalNumerator += total_numerator; overallTotalDenominator += total_denominator; table.append(row); } let overallTotalRow = $("<tr/>"); overallTotalRow.append($("<th/>").text("Total")); for (let i = 0; i < longest; i++) { overallTotalRow.append($("<td/>")); } let overallTotalCell = $("<td/>").addClass("total"); if (overallTotalDenominator != 0) { overallTotalCell.text(totalToStr(overallTotalNumerator, overallTotalDenominator)); if (overallTotalNumerator / overallTotalDenominator < 0.5) { overallTotalCell.addClass('is-low'); } } overallTotalRow.append(overallTotalCell); table.append(overallTotalRow); grid.append($("<div/>").attr("id", "table-container").append(table)); data[period_name] = grid; } let modal = $("<div/>").attr("id", "content-container"); let period_buttons = $("<div/>"); let main_grid = $("<div/>").attr("id", "period-container"); for (let [period_name, grid] of Object.entries(data).reverse()) { // We are using two lambda's sice otherwice they will all use the same scope. period_buttons.append($("<button/>").addClass("period_button").text(period_name).click(((grid) => { return () => { main_grid.empty(); main_grid.append(grid); }; })(grid))); } if (period_buttons.children().length > 1) { period_buttons.prepend($("<span/>").text("Select period: ")); modal.append(period_buttons); } if (latest_period !== null) { main_grid.append(data[latest_period]); } modal.append(main_grid); loading.replaceWith(modal); }); return loading; } function onLoad() { let style = document.createElement('style'); style.innerHTML = ` #result-table #disclamer { border: none !important; color: red; font-weight: bold; position: relative; } #disclamer:hover::before { visibility: visible; opacity: 1; } #disclamer::before { z-index: 1; content: "Deze totalen kunnen afwijken van uw werkelijke resultaten doordat niet altijd alle gegevens gekend zijn."; position: absolute; left: -20rem; border: 3px solid red; padding: 0.2rem; border-radius: 3px; background-color: white; width: 20rem; visibility: hidden; opacity: 0; transition: visibility 0s, opacity 0.5s linear; } #details { position: relative; } #details:hover::before { visibility: visible; opacity: 0.9; } #details::before { z-index: 2; content: attr(content); color: white; background-color: #1a1a1a; visibility: hidden; position: absolute; text-align: center; padding: 0.313rem 0; border-radius: 0.375rem; opacity: 0; transition: opacity .6s; width: 15rem; top: 100%; left: 50%; margin-left: -7.5rem; } #result-table .hidden-cell { border: none !important; } .period_button { background-color: #ff520e; border-radius: 3px; border-style: none; color: #FFFFFF; margin-right: 0.5rem; padding: 0.4rem; text-align: center; transition: 100ms; } .period_button:hover { background-color: #ef4200; } .period_button:active { background-color: #ff6210; } .total { font-weight: bold; } .is-low { color: red !important; } #table-container { flex: 1 1 auto; overflow: auto; } #period { height: 100%; display: flex; flex-direction: column; } #period-container { flex: 1; min-height: 0; } #content-container { display: flex; flex-direction: column; height: 100%; width: 100%; } #result-table { margin-top: 1rem; border: 0px; } #result-table th { text-align: left; } #result-table td { text-align: center; } #result-table th, #result-table td { border: 1px solid gray !important; padding: 0.5rem; min-width: 5.5rem; } #modal-background { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: white; opacity: .50; -webkit-opacity: .5; -moz-opacity: .5; filter: alpha(opacity=50); z-index: 1000; } #modal-content { background-color: white; border-radius: 10px; -webkit-border-radius: 10px; -moz-border-radius: 10px; box-shadow: 0 0 20px 0 #222; -webkit-box-shadow: 0 0 20px 0 #222; -moz-box-shadow: 0 0 20px 0 #222; display: none; padding: 10px; position: fixed; z-index: 1000; left: 10%; top: 10%; width: 80%; height: 80%; } #modal-background.active, #modal-content.active { display: block; } #modal-close { background-color: #ee0000; border-radius: 3px; border-style: none; color: #FFFFFF; padding: 0.4rem; text-align: center; transition: 100ms; position: absolute; right: 0.5rem; } #modal-close:hover { background-color: #dd0000; } #modal-close:active { background-color: #ff0000; } `; document.head.appendChild(style); $("body").append( $("<div/>").attr("id", "modal-background") ).append( $("<div/>").attr("id", "modal-content").append( $("<button/>").attr("id", "modal-close").text("Close") ).append(makeGrid()) ); $("#modal-background, #modal-close").click(function () { $("#modal-content, #modal-background").toggleClass("active"); }); } function openGrid() { $("#modal-content, #modal-background").toggleClass("active"); }