Unterstützung für /course/show und Refactoring
- Seitenrouting auf /course/show korrigiert (/course/list leitet um) - Planungsgruppen-Dropdown (planningGroupIds[]) für /course/show ergänzt - Funktionsblöcke je Seite eingeführt (courseList_*, planningGroupList_*) - MutationObserver + Polling für zuverlässiges Timing beim Seitenladen - .gitignore ergänzt
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
// ==UserScript==
|
||||
// @name academyFIVE::AddSelectBox
|
||||
// @namespace dakp/academyfive
|
||||
// @version 2026.03.001
|
||||
// @description Füge Selectbox für Kohorten hinzu
|
||||
// @version 2026.04.007
|
||||
// @description Füge Selectbox für Kohorten/Planungsgruppen hinzu
|
||||
// @author Dims Akpan
|
||||
// @match https://a5.fhdw-hannover.de/*
|
||||
// @match https://a5.fhdw.de/*
|
||||
@@ -14,34 +14,35 @@
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
function addSelectButtons() {
|
||||
// Prüfe ob wir auf der richtigen Seite sind
|
||||
if (!window.location.href.includes('/course/planning-group/list')) {
|
||||
return;
|
||||
|
||||
const LOG = '[A5-SelectBox]';
|
||||
|
||||
// ─── Gemeinsame Hilfsfunktionen ───────────────────────────────────────────
|
||||
|
||||
function insertSelectButtons(selectSelector) {
|
||||
const select = document.querySelector(selectSelector);
|
||||
if (!select) {
|
||||
console.log(LOG, 'select nicht gefunden:', selectSelector);
|
||||
return false;
|
||||
}
|
||||
|
||||
const cohortsDropdown = document.querySelector('select[name="cohort-ids[]"]');
|
||||
|
||||
if (!cohortsDropdown) {
|
||||
console.log('Kohorten-Dropdown nicht gefunden');
|
||||
return;
|
||||
|
||||
const dropdownContainer = select.closest('.btn-group.bootstrap-select');
|
||||
if (!dropdownContainer) {
|
||||
console.log(LOG, 'closest(.btn-group.bootstrap-select) nicht gefunden');
|
||||
return false;
|
||||
}
|
||||
|
||||
const dropdownContainer = cohortsDropdown.closest('.btn-group.bootstrap-select');
|
||||
const searchBox = dropdownContainer?.querySelector('.bs-searchbox');
|
||||
|
||||
|
||||
const searchBox = dropdownContainer.querySelector('.bs-searchbox');
|
||||
if (!searchBox) {
|
||||
console.log('Searchbox nicht gefunden');
|
||||
return;
|
||||
console.log(LOG, '.bs-searchbox nicht gefunden im Container');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Prüfe ob schon vorhanden
|
||||
|
||||
if (searchBox.nextElementSibling?.classList.contains('bs-actionsbox')) {
|
||||
console.log('Select/Deselect Buttons bereits vorhanden');
|
||||
return;
|
||||
console.log(LOG, 'Buttons bereits vorhanden, überspringe');
|
||||
return true;
|
||||
}
|
||||
// Füge die Buttons hinzu
|
||||
|
||||
const actionsBox = document.createElement('div');
|
||||
actionsBox.className = 'bs-actionsbox';
|
||||
actionsBox.innerHTML = `
|
||||
@@ -50,17 +51,80 @@
|
||||
<button type="button" class="actions-btn bs-deselect-all btn btn-default">Nichts auswählen</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
|
||||
searchBox.insertAdjacentElement('afterend', actionsBox);
|
||||
|
||||
console.log('Select/Deselect Buttons erfolgreich eingefügt');
|
||||
console.log(LOG, 'Buttons erfolgreich eingefügt für:', selectSelector);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Versuche es direkt
|
||||
addSelectButtons();
|
||||
|
||||
// Falls das Element noch nicht da ist, warte auf DOMContentLoaded
|
||||
|
||||
function waitAndInsert(tryFn) {
|
||||
console.log(LOG, 'waitAndInsert gestartet | readyState:', document.readyState, '| URL:', window.location.href);
|
||||
|
||||
if (tryFn()) return;
|
||||
|
||||
console.log(LOG, 'Erster Versuch fehlgeschlagen, starte Observer + Polling');
|
||||
|
||||
const observer = new MutationObserver(() => {
|
||||
if (tryFn()) {
|
||||
console.log(LOG, 'Observer: Buttons eingefügt, Observer beendet');
|
||||
observer.disconnect();
|
||||
}
|
||||
});
|
||||
|
||||
observer.observe(document.body, { childList: true, subtree: true });
|
||||
|
||||
let attempts = 0;
|
||||
const poll = setInterval(() => {
|
||||
attempts++;
|
||||
if (tryFn()) {
|
||||
console.log(LOG, 'Polling: Buttons eingefügt nach', attempts, 'Versuchen');
|
||||
clearInterval(poll);
|
||||
} else if (attempts >= 50) {
|
||||
console.log(LOG, 'Polling: Timeout nach 50 Versuchen');
|
||||
clearInterval(poll);
|
||||
observer.disconnect();
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
// ─── /course/list ─────────────────────────────────────────────────────────
|
||||
|
||||
function courseList_tryInsert() {
|
||||
return insertSelectButtons('select[name="planningGroupIds[]"]');
|
||||
}
|
||||
|
||||
function courseList_init() {
|
||||
waitAndInsert(courseList_tryInsert);
|
||||
}
|
||||
|
||||
// ─── /course/planning-group/list ──────────────────────────────────────────
|
||||
|
||||
function planningGroupList_tryInsert() {
|
||||
return insertSelectButtons('select[name="cohort-ids[]"]');
|
||||
}
|
||||
|
||||
function planningGroupList_init() {
|
||||
waitAndInsert(planningGroupList_tryInsert);
|
||||
}
|
||||
|
||||
// ─── Routing ──────────────────────────────────────────────────────────────
|
||||
|
||||
function init() {
|
||||
const url = window.location.href;
|
||||
console.log(LOG, 'init() | URL:', url);
|
||||
|
||||
if (url.includes('/course/planning-group/list')) {
|
||||
planningGroupList_init();
|
||||
} else if (url.includes('/course/show')) {
|
||||
courseList_init();
|
||||
} else {
|
||||
console.log(LOG, 'URL passt zu keiner bekannten Seite, Script inaktiv');
|
||||
}
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', addSelectButtons);
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
})();
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user