wip
This commit is contained in:
parent
8add9d459b
commit
45501c30f1
2 changed files with 111 additions and 0 deletions
95
content.js
Normal file
95
content.js
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
"use strict";
|
||||
|
||||
function getApplicationId() {
|
||||
const match = window.location.hash.match(/^#\/job-procedures\/record\/([0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12})/)
|
||||
if (match != null) {
|
||||
return match[1]
|
||||
}
|
||||
throw "Unable to retrieve Application ID";
|
||||
}
|
||||
|
||||
async function getXSRFToken() {
|
||||
// we need to go through the background script to get the XSRF-TOKEN cookie
|
||||
return browser.runtime.sendMessage(
|
||||
{ type: "COOKIE", url: "https://personal.uni-graz.at", key: "XSRF-TOKEN" }
|
||||
).then((cookie) => {
|
||||
return cookie.value;
|
||||
})
|
||||
}
|
||||
|
||||
async function getApplicant(applicant, token) {
|
||||
content.fetch(`https://personal.uni-graz.at/api/erec/job-applications/${applicant.id}`,
|
||||
{
|
||||
headers: { "X-XSRF-TOKEN": token }
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.ok) {
|
||||
return response.json()
|
||||
}
|
||||
throw `Failed to get applicant ${applicant.id}`
|
||||
})
|
||||
.then((jsonData) => {
|
||||
return jsonData
|
||||
})
|
||||
}
|
||||
|
||||
async function getApplicants() {
|
||||
const aid = getApplicationId()
|
||||
const token = await getXSRFToken()
|
||||
content.fetch(`https://personal.uni-graz.at/api/erec/job-applications/procedure/${aid}`,
|
||||
{
|
||||
credentials: "same-origin",
|
||||
headers: { "X-XSRF-TOKEN": token }
|
||||
}
|
||||
)
|
||||
.then((response) => {
|
||||
if (response.ok) {
|
||||
return response.json()
|
||||
}
|
||||
throw "Failed to get list of applications"
|
||||
})
|
||||
.then((jsonData) => {
|
||||
const sliced = jsonData.slice(0, 10);
|
||||
return Promise.allSettled(sliced.map(async (applicant) => getApplicant(applicant, token)))
|
||||
})
|
||||
}
|
||||
|
||||
function rip(event) {
|
||||
const btn = event.target;
|
||||
btn.textContent = "working ..."
|
||||
btn.classList.add("loading")
|
||||
btn.disabled = true;
|
||||
getApplicants().then((applicants) => {
|
||||
btn.textContent = "done"
|
||||
})
|
||||
}
|
||||
|
||||
// injection of rip button
|
||||
function install() {
|
||||
const titleTag = document.querySelector("scrm-module-title")
|
||||
|
||||
if (titleTag != null) {
|
||||
const a = document.createElement("button")
|
||||
a.textContent = "rip"
|
||||
a.classList.add("ripper-btn")
|
||||
a.addEventListener("click", rip, {
|
||||
once: true
|
||||
})
|
||||
titleTag.append(" (", a, ")")
|
||||
} else {
|
||||
console.log("could not install button")
|
||||
}
|
||||
}
|
||||
|
||||
// we need the observer to restore the button after each page load
|
||||
const contentObserver = new MutationObserver((mutations) => {
|
||||
mutations.forEach(mu => {
|
||||
for (const node of mu.removedNodes) {
|
||||
if (node.nodeName == "APP-FULL-PAGE-SPINNER") {
|
||||
install();
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
contentObserver.observe(document.querySelector("app-root"), { subtree: true, childList: true });
|
||||
16
style.css
16
style.css
|
|
@ -0,0 +1,16 @@
|
|||
/* .ripper-link { text-decoration: underline } */
|
||||
|
||||
/* from https://stackoverflow.com/questions/67605723/triple-dot-css-animation-on-a-loading-screen */
|
||||
.loading {
|
||||
font-weight: bold;
|
||||
display: inline-block;
|
||||
font-family: monospace;
|
||||
clip-path: inset(0 3ch 0 0);
|
||||
animation: l 1s steps(4, jump-none) infinite;
|
||||
}
|
||||
|
||||
@keyframes l {
|
||||
to {
|
||||
clip-path: inset(0)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue