18C / Gradebook

// ==UserScript==
// @name        Gradebook
// @namespace   CCAU
// @description Automate course copies
// @match       https://*.instructure.com/courses/*/gradebook
// @version     0.1.0
// @author      CIDT
// @grant       none
// @license     BSD-3-Clause
// ==/UserScript==
"use strict";
(() => {
  // out/utils.js
  function observeDOM(element, callback) {
    const observer = new MutationObserver(callback);
    observer.observe(element, {
      childList: true
    });
    return observer;
  }
  function sumPoints() {
    return Array.from(document.querySelectorAll(".assignment-points-possible")).map((e) => e.children[0].textContent ?? "0").map((e) => Number(e.match(/(\d+)/)[0])).reduce((acc, num) => {
      return acc + num;
    }, 0);
  }
  function reloadSum() {
    const button = document.querySelector("#ccau_point_total");
    if (button) {
      button.textContent = "Total: " + sumPoints();
    }
  }
  function addButton() {
    const appExists = document.querySelector(".assignment-points-possible");
    const btnExists = document.querySelector("#ccau_point_total");
    if (!appExists || btnExists) {
      return;
    }
    const bar = document.querySelector("#gradebook-actions");
    const btn = document.createElement("a");
    btn.id = "ccau_point_total";
    btn.textContent = "Total: " + sumPoints();
    btn.classList.add("btn");
    btn.setAttribute("tabindex", "0");
    btn.addEventListener("click", reloadSum);
    bar?.insertAdjacentElement("afterbegin", btn);
  }

  // out/index.js
  observeDOM(document.body, () => setTimeout(addButton, 500));
})();