Ordner-Zuweisung als klickbare Tabelle statt Checkboxen
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
24
admin.html
24
admin.html
@@ -7,8 +7,6 @@
|
||||
<link rel="stylesheet" href="/assets/css/main.min.css" />
|
||||
<style>
|
||||
.admin-section { background: rgba(0,0,0,0.5); padding: 2em; margin-bottom: 2em; border-radius: 4px; }
|
||||
.folder-check { display: inline-block; margin: 5px 10px; padding: 8px 12px; background: rgba(255,255,255,0.1); border-radius: 4px; }
|
||||
.folder-check label { cursor: pointer; }
|
||||
table { width: 100%; border-collapse: collapse; }
|
||||
th, td { text-align: left; padding: 10px; border-bottom: 1px solid rgba(255,255,255,0.2); }
|
||||
.badge { display: inline-block; padding: 2px 8px; border-radius: 3px; font-size: 0.8em; }
|
||||
@@ -17,6 +15,14 @@
|
||||
.badge-client { background: #4CAF50; }
|
||||
.badge-expired { background: #666; }
|
||||
.btn-small { padding: 4px 10px; font-size: 0.85em; margin: 2px; cursor: pointer; }
|
||||
.folder-row { cursor: pointer; transition: background 0.2s; }
|
||||
.folder-row:hover { background: rgba(255,255,255,0.1); }
|
||||
.folder-row.assigned { background: rgba(76,175,80,0.25); }
|
||||
.folder-row.assigned:hover { background: rgba(76,175,80,0.35); }
|
||||
.folder-status { font-weight: bold; }
|
||||
.folder-status.yes { color: #4CAF50; }
|
||||
.folder-status.no { color: #888; }
|
||||
#folder-table-wrap { display: none; margin-top: 1em; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="is-preload">
|
||||
@@ -65,13 +71,17 @@
|
||||
|
||||
<div class="admin-section">
|
||||
<h2>Ordner-Zuweisung</h2>
|
||||
<p>Weise Unterordner aus dem Websitebilder-Verzeichnis einem Nutzer zu.</p>
|
||||
<select id="user-select" style="margin-bottom: 1em;">
|
||||
<p>Waehle einen Nutzer und klicke auf Ordner um sie zuzuweisen oder zu entfernen.</p>
|
||||
<select id="user-select">
|
||||
<option value="">Nutzer waehlen...</option>
|
||||
</select>
|
||||
<div id="folder-checkboxes" style="display:flex; flex-wrap:wrap; gap:5px; margin-bottom:1em;"></div>
|
||||
<button id="save-assignments">Zuweisung Speichern</button>
|
||||
<span id="assign-status" style="margin-left:10px;"></span>
|
||||
<div id="folder-table-wrap">
|
||||
<table id="folder-table">
|
||||
<thead><tr><th><i class="fa fa-folder"></i> Ordner</th><th style="width:120px; text-align:center;">Status</th></tr></thead>
|
||||
<tbody id="folder-tbody"></tbody>
|
||||
</table>
|
||||
<span id="assign-status" style="display:inline-block; margin-top:10px;"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="admin-section">
|
||||
|
||||
@@ -122,50 +122,70 @@ $(document).ready(function() {
|
||||
|
||||
// ==================== ORDNER-ZUWEISUNG ====================
|
||||
|
||||
var allFolders = [];
|
||||
var assignedFolders = [];
|
||||
|
||||
function loadFolders() {
|
||||
$.get('/api/admin/folders').done(function(folders) {
|
||||
$('#folder-checkboxes').empty();
|
||||
if (folders.length === 0) {
|
||||
$('#folder-checkboxes').html('<p>Keine Unterordner in Websitebilder gefunden. Erstelle Ordner in Nextcloud.</p>');
|
||||
allFolders = folders;
|
||||
});
|
||||
}
|
||||
|
||||
function renderFolderTable() {
|
||||
var $tbody = $('#folder-tbody');
|
||||
$tbody.empty();
|
||||
if (allFolders.length === 0) {
|
||||
$tbody.html('<tr><td colspan="2" style="text-align:center;">Keine Unterordner gefunden. Erstelle Ordner in Nextcloud.</td></tr>');
|
||||
return;
|
||||
}
|
||||
folders.forEach(function(f) {
|
||||
$('#folder-checkboxes').append(
|
||||
'<div class="folder-check"><label>' +
|
||||
'<input type="checkbox" value="' + f + '" class="folder-cb"/> ' +
|
||||
'<i class="fa fa-folder"></i> ' + f +
|
||||
'</label></div>'
|
||||
allFolders.forEach(function(f) {
|
||||
var isAssigned = assignedFolders.indexOf(f) !== -1;
|
||||
var cls = isAssigned ? 'folder-row assigned' : 'folder-row';
|
||||
var statusCls = isAssigned ? 'folder-status yes' : 'folder-status no';
|
||||
var statusText = isAssigned ? 'Zugewiesen' : '—';
|
||||
$tbody.append(
|
||||
'<tr class="' + cls + '" data-folder="' + f + '">' +
|
||||
'<td><i class="fa fa-folder"></i> ' + f + '</td>' +
|
||||
'<td style="text-align:center;"><span class="' + statusCls + '">' + statusText + '</span></td>' +
|
||||
'</tr>'
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Bei User-Auswahl: zugewiesene Ordner laden
|
||||
// Bei User-Auswahl: zugewiesene Ordner laden und Tabelle anzeigen
|
||||
$('#user-select').change(function() {
|
||||
var uid = $(this).val();
|
||||
$('.folder-cb').prop('checked', false);
|
||||
if (!uid) return;
|
||||
$.get('/api/admin/assign?user_id=' + uid).done(function(assignedFolders) {
|
||||
assignedFolders.forEach(function(f) {
|
||||
$('.folder-cb[value="' + f + '"]').prop('checked', true);
|
||||
});
|
||||
if (!uid) {
|
||||
$('#folder-table-wrap').hide();
|
||||
assignedFolders = [];
|
||||
return;
|
||||
}
|
||||
$.get('/api/admin/assign?user_id=' + uid).done(function(folders) {
|
||||
assignedFolders = folders || [];
|
||||
renderFolderTable();
|
||||
$('#folder-table-wrap').show();
|
||||
});
|
||||
});
|
||||
|
||||
// Zuweisung speichern
|
||||
$('#save-assignments').click(function() {
|
||||
// Klick auf Ordner-Zeile: Toggle + sofort speichern
|
||||
$(document).on('click', '.folder-row', function() {
|
||||
var uid = $('#user-select').val();
|
||||
if (!uid) return alert('Bitte Nutzer waehlen');
|
||||
var selected = [];
|
||||
$('.folder-cb:checked').each(function() { selected.push($(this).val()); });
|
||||
|
||||
if (!uid) return;
|
||||
var folder = $(this).data('folder');
|
||||
var idx = assignedFolders.indexOf(folder);
|
||||
if (idx !== -1) {
|
||||
assignedFolders.splice(idx, 1);
|
||||
} else {
|
||||
assignedFolders.push(folder);
|
||||
}
|
||||
renderFolderTable();
|
||||
$.ajax({
|
||||
url: '/api/admin/assign',
|
||||
type: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify({ user_id: uid, folders: selected })
|
||||
data: JSON.stringify({ user_id: uid, folders: assignedFolders })
|
||||
}).done(function() {
|
||||
$('#assign-status').text('Gespeichert!').fadeIn().delay(2000).fadeOut();
|
||||
$('#assign-status').text('Gespeichert!').show().delay(1500).fadeOut();
|
||||
}).fail(function() {
|
||||
alert('Fehler beim Speichern');
|
||||
});
|
||||
|
||||
2
assets/js/admin.min.js
vendored
2
assets/js/admin.min.js
vendored
@@ -1 +1 @@
|
||||
$(document).ready(function(){function e(){$.get("/api/admin/users").done(function(e){$("#users-tbody").empty(),$("#user-select").html('<option value="">Nutzer waehlen...</option>'),e&&0!==e.length?e.forEach(function(e){var n=e.role||"unbekannt",t='<span class="badge badge-'+n+'">'+n+"</span>",a=e.created_at?new Date(e.created_at).toLocaleDateString("de-DE"):"-";if("client"===n&&e.expires_at){var r=new Date(e.expires_at).toLocaleDateString("de-DE");e.expired?(t='<span class="badge badge-expired">abgelaufen</span>',a="Abgelaufen: "+r):a="Bis: "+r}var s='<button class="btn-small" onclick="changePassword('+e.id+", '"+e.username.replace(/'/g,"\\'")+"')\">PW</button>";s+='<button class="btn-small" onclick="deleteUser('+e.id+", '"+e.username.replace(/'/g,"\\'")+"')\">X</button>",$("#users-tbody").append("<tr><td>"+e.id+"</td><td>"+e.username+" "+t+"</td><td>"+n+"</td><td>"+a+"</td><td>"+s+"</td></tr>"),"admin"!==n&&$("#user-select").append('<option value="'+e.id+'">'+e.username+" ("+n+")</option>")}):$("#users-tbody").html('<tr><td colspan="5" style="text-align:center;">Keine Nutzer gefunden</td></tr>')}).fail(function(e){var n="HTTP "+e.status+": "+e.statusText;$("#users-tbody").html('<tr><td colspan="5" style="color:#e44d26;">Fehler beim Laden: '+n+"</td></tr>")})}$.get("/api/auth/me").done(function(n){"admin"!==n.role?(alert("Kein Zugriff!"),window.location.href="/"):(e(),$.get("/api/admin/folders").done(function(e){$("#folder-checkboxes").empty(),0!==e.length?e.forEach(function(e){$("#folder-checkboxes").append('<div class="folder-check"><label><input type="checkbox" value="'+e+'" class="folder-cb"/> <i class="fa fa-folder"></i> '+e+"</label></div>")}):$("#folder-checkboxes").html("<p>Keine Unterordner in Websitebilder gefunden. Erstelle Ordner in Nextcloud.</p>")}),$("body").removeClass("is-preload"))}).fail(function(){window.location.href="/"}),$("#logout-btn").click(function(e){e.preventDefault(),$.post("/api/auth/logout").done(function(){window.location.href="/"})}),$("#create-user-form").submit(function(n){n.preventDefault();var t=$("#new-username").val().trim(),a=$("#new-password").val(),r=$("#new-role").val();t&&a?$.ajax({url:"/api/admin/users",type:"POST",contentType:"application/json",data:JSON.stringify({username:t,password:a,role:r})}).done(function(n){alert('Nutzer "'+t+'" erfolgreich erstellt!'),$("#new-username").val(""),$("#new-password").val(""),e()}).fail(function(e){var n="Unbekannter Fehler";e.responseJSON&&e.responseJSON.error?n=e.responseJSON.error:e.status&&(n="HTTP "+e.status+": "+e.statusText),alert("Fehler beim Erstellen: "+n)}):alert("Bitte Username und Passwort eingeben.")}),window.deleteUser=function(n,t){confirm('Nutzer "'+t+'" wirklich loeschen?')&&$.ajax({url:"/api/admin/users/"+n,type:"DELETE"}).done(e).fail(function(e){alert(e.responseJSON?e.responseJSON.error:"Fehler")})},window.changePassword=function(e,n){var t=prompt('Neues Passwort fuer "'+n+'":');t&&$.ajax({url:"/api/admin/users/"+e+"/password",type:"PUT",contentType:"application/json",data:JSON.stringify({new_password:t})}).done(function(){alert("Passwort geaendert!")}).fail(function(e){alert(e.responseJSON?e.responseJSON.error:"Fehler")})},$("#user-select").change(function(){var e=$(this).val();$(".folder-cb").prop("checked",!1),e&&$.get("/api/admin/assign?user_id="+e).done(function(e){e.forEach(function(e){$('.folder-cb[value="'+e+'"]').prop("checked",!0)})})}),$("#save-assignments").click(function(){var e=$("#user-select").val();if(!e)return alert("Bitte Nutzer waehlen");var n=[];$(".folder-cb:checked").each(function(){n.push($(this).val())}),$.ajax({url:"/api/admin/assign",type:"POST",contentType:"application/json",data:JSON.stringify({user_id:e,folders:n})}).done(function(){$("#assign-status").text("Gespeichert!").fadeIn().delay(2e3).fadeOut()}).fail(function(){alert("Fehler beim Speichern")})}),$("#admin-pw-form").submit(function(e){e.preventDefault(),$.post("/api/auth/change-password",{old_password:$("#admin-pw-old").val(),new_password:$("#admin-pw-new").val()}).done(function(){alert("Passwort geaendert!"),$("#admin-pw-old, #admin-pw-new").val("")}).fail(function(e){alert(e.responseJSON?e.responseJSON.error:"Fehler")})})});
|
||||
$(document).ready(function(){function e(){$.get("/api/admin/users").done(function(e){$("#users-tbody").empty(),$("#user-select").html('<option value="">Nutzer waehlen...</option>'),e&&0!==e.length?e.forEach(function(e){var t=e.role||"unbekannt",n='<span class="badge badge-'+t+'">'+t+"</span>",a=e.created_at?new Date(e.created_at).toLocaleDateString("de-DE"):"-";if("client"===t&&e.expires_at){var r=new Date(e.expires_at).toLocaleDateString("de-DE");e.expired?(n='<span class="badge badge-expired">abgelaufen</span>',a="Abgelaufen: "+r):a="Bis: "+r}var s='<button class="btn-small" onclick="changePassword('+e.id+", '"+e.username.replace(/'/g,"\\'")+"')\">PW</button>";s+='<button class="btn-small" onclick="deleteUser('+e.id+", '"+e.username.replace(/'/g,"\\'")+"')\">X</button>",$("#users-tbody").append("<tr><td>"+e.id+"</td><td>"+e.username+" "+n+"</td><td>"+t+"</td><td>"+a+"</td><td>"+s+"</td></tr>"),"admin"!==t&&$("#user-select").append('<option value="'+e.id+'">'+e.username+" ("+t+")</option>")}):$("#users-tbody").html('<tr><td colspan="5" style="text-align:center;">Keine Nutzer gefunden</td></tr>')}).fail(function(e){var t="HTTP "+e.status+": "+e.statusText;$("#users-tbody").html('<tr><td colspan="5" style="color:#e44d26;">Fehler beim Laden: '+t+"</td></tr>")})}$.get("/api/auth/me").done(function(n){"admin"!==n.role?(alert("Kein Zugriff!"),window.location.href="/"):(e(),$.get("/api/admin/folders").done(function(e){t=e}),$("body").removeClass("is-preload"))}).fail(function(){window.location.href="/"}),$("#logout-btn").click(function(e){e.preventDefault(),$.post("/api/auth/logout").done(function(){window.location.href="/"})}),$("#create-user-form").submit(function(t){t.preventDefault();var n=$("#new-username").val().trim(),a=$("#new-password").val(),r=$("#new-role").val();n&&a?$.ajax({url:"/api/admin/users",type:"POST",contentType:"application/json",data:JSON.stringify({username:n,password:a,role:r})}).done(function(t){alert('Nutzer "'+n+'" erfolgreich erstellt!'),$("#new-username").val(""),$("#new-password").val(""),e()}).fail(function(e){var t="Unbekannter Fehler";e.responseJSON&&e.responseJSON.error?t=e.responseJSON.error:e.status&&(t="HTTP "+e.status+": "+e.statusText),alert("Fehler beim Erstellen: "+t)}):alert("Bitte Username und Passwort eingeben.")}),window.deleteUser=function(t,n){confirm('Nutzer "'+n+'" wirklich loeschen?')&&$.ajax({url:"/api/admin/users/"+t,type:"DELETE"}).done(e).fail(function(e){alert(e.responseJSON?e.responseJSON.error:"Fehler")})},window.changePassword=function(e,t){var n=prompt('Neues Passwort fuer "'+t+'":');n&&$.ajax({url:"/api/admin/users/"+e+"/password",type:"PUT",contentType:"application/json",data:JSON.stringify({new_password:n})}).done(function(){alert("Passwort geaendert!")}).fail(function(e){alert(e.responseJSON?e.responseJSON.error:"Fehler")})};var t=[],n=[];function a(){var e=$("#folder-tbody");e.empty(),0!==t.length?t.forEach(function(t){var a=-1!==n.indexOf(t),r=a?"folder-row assigned":"folder-row",s=a?"folder-status yes":"folder-status no",o=a?"Zugewiesen":"—";e.append('<tr class="'+r+'" data-folder="'+t+'"><td><i class="fa fa-folder"></i> '+t+'</td><td style="text-align:center;"><span class="'+s+'">'+o+"</span></td></tr>")}):e.html('<tr><td colspan="2" style="text-align:center;">Keine Unterordner gefunden. Erstelle Ordner in Nextcloud.</td></tr>')}$("#user-select").change(function(){var e=$(this).val();if(!e)return $("#folder-table-wrap").hide(),void(n=[]);$.get("/api/admin/assign?user_id="+e).done(function(e){n=e||[],a(),$("#folder-table-wrap").show()})}),$(document).on("click",".folder-row",function(){var e=$("#user-select").val();if(e){var t=$(this).data("folder"),r=n.indexOf(t);-1!==r?n.splice(r,1):n.push(t),a(),$.ajax({url:"/api/admin/assign",type:"POST",contentType:"application/json",data:JSON.stringify({user_id:e,folders:n})}).done(function(){$("#assign-status").text("Gespeichert!").show().delay(1500).fadeOut()}).fail(function(){alert("Fehler beim Speichern")})}}),$("#admin-pw-form").submit(function(e){e.preventDefault(),$.post("/api/auth/change-password",{old_password:$("#admin-pw-old").val(),new_password:$("#admin-pw-new").val()}).done(function(){alert("Passwort geaendert!"),$("#admin-pw-old, #admin-pw-new").val("")}).fail(function(e){alert(e.responseJSON?e.responseJSON.error:"Fehler")})})});
|
||||
Reference in New Issue
Block a user