mirror of https://github.com/dirtbags/moth.git
141 lines
4.3 KiB
JavaScript
141 lines
4.3 KiB
JavaScript
import * as moth from "../moth.mjs"
|
|
import * as common from "../common.mjs"
|
|
|
|
const server = new moth.Server("../")
|
|
|
|
/**
|
|
* Update "doing" indicators
|
|
*
|
|
* @param {String | null} what Text to display, or null to not update text
|
|
* @param {Number | null} finished Percentage complete to display, or null to not update progress
|
|
*/
|
|
function doing(what, finished = null) {
|
|
for (let e of document.querySelectorAll(".doing")) {
|
|
e.classList.remove("hidden")
|
|
if (what) {
|
|
e.textContent = what
|
|
}
|
|
if (finished) {
|
|
e.value = finished
|
|
} else {
|
|
e.removeAttribute("value")
|
|
}
|
|
}
|
|
}
|
|
function done() {
|
|
for (let e of document.querySelectorAll(".doing")) {
|
|
e.classList.add("hidden")
|
|
}
|
|
}
|
|
|
|
async function GetNice() {
|
|
let NiceElementsByIdentifier = {}
|
|
let resp = await fetch("NICEFramework2017.json")
|
|
let obj = await resp.json()
|
|
for (let e of obj.elements) {
|
|
NiceElementsByIdentifier[e.element_identifier] = e
|
|
}
|
|
return NiceElementsByIdentifier
|
|
}
|
|
|
|
/**
|
|
* Fetch a puzzle, and fill its KSAs and rows.
|
|
*
|
|
* This is done once per puzzle, in an asynchronous function, allowing the
|
|
* application to perform multiple blocking operations simultaneously.
|
|
*/
|
|
async function FetchAndFill(puzzle, KSAs, rows) {
|
|
try {
|
|
await puzzle.Populate()
|
|
}
|
|
catch (error) {
|
|
// Keep on going with whatever Populate was able to fill
|
|
}
|
|
for (let KSA of (puzzle.KSAs || [])) {
|
|
KSAs.add(KSA)
|
|
}
|
|
|
|
for (let row of rows) {
|
|
row.querySelector(".category").textContent = puzzle.Category
|
|
row.querySelector(".points").textContent = puzzle.Points
|
|
row.querySelector(".ksas").textContent = (puzzle.KSAs || []).join(" ")
|
|
row.querySelector(".error").textContent = puzzle.Error.Body
|
|
}
|
|
}
|
|
|
|
async function init() {
|
|
doing("Fetching NICE framework data")
|
|
let nicePromise = GetNice()
|
|
|
|
doing("Retrieving server state")
|
|
let state = await server.GetState()
|
|
|
|
doing("Retrieving all puzzles")
|
|
let KSAsByCategory = {}
|
|
let puzzlerowTemplate = document.querySelector("template#puzzlerow")
|
|
let puzzles = state.Puzzles()
|
|
let promises = []
|
|
for (let category of state.Categories()) {
|
|
KSAsByCategory[category] = new Set()
|
|
}
|
|
let pending = puzzles.length
|
|
for (let puzzle of puzzles) {
|
|
// Make space in the table, so everything fills in sorted order
|
|
let rows = []
|
|
for (let tbody of document.querySelectorAll("tbody")) {
|
|
let row = puzzlerowTemplate.content.cloneNode(true).firstElementChild
|
|
tbody.appendChild(row)
|
|
rows.push(row)
|
|
}
|
|
|
|
// Queue up a fetch, and update progress bar
|
|
let promise = FetchAndFill(puzzle, KSAsByCategory[puzzle.Category], rows)
|
|
promises.push(promise)
|
|
promise.then(() => doing(null, 1 - (--pending / puzzles.length)))
|
|
|
|
if (promises.length > 50) {
|
|
// Chrome runs out of resources if you queue up too many of these at once
|
|
await Promise.all(promises)
|
|
promises = []
|
|
}
|
|
}
|
|
await Promise.all(promises)
|
|
|
|
doing("Retrieving NICE identifiers")
|
|
let NiceElementsByIdentifier = await nicePromise
|
|
|
|
|
|
doing("Filling KSAs By Category")
|
|
let allKSAs = new Set()
|
|
for (let div of document.querySelectorAll(".KSAsByCategory")) {
|
|
for (let category of state.Categories()) {
|
|
doing(`Filling KSAs for category: ${category}`)
|
|
let KSAs = [...KSAsByCategory[category]]
|
|
KSAs.sort()
|
|
|
|
div.appendChild(document.createElement("h3")).textContent = category
|
|
let ul = div.appendChild(document.createElement("ul"))
|
|
for (let k of KSAs) {
|
|
let ksa = k.split(/\s+/)[0]
|
|
let ne = NiceElementsByIdentifier[ksa] || { text: "???" }
|
|
let text = `${ksa}: ${ne.text}`
|
|
ul.appendChild(document.createElement("li")).textContent = text
|
|
allKSAs.add(text)
|
|
}
|
|
}
|
|
}
|
|
|
|
doing("Filling KSAs")
|
|
for (let e of document.querySelectorAll(".allKSAs")) {
|
|
let KSAs = [...allKSAs]
|
|
KSAs.sort()
|
|
for (let text of KSAs) {
|
|
e.appendChild(document.createElement("li")).textContent = text
|
|
}
|
|
}
|
|
|
|
done()
|
|
}
|
|
|
|
common.WhenDOMLoaded(init)
|