Files
WP-LIT-MCP/assets/js/admin.js
T
Jan-Niclas LoosenandClaude Fable 5.1 1b73f0652a fix: Admin-UX aus dem Review – Live-Gruppenfeedback, Protokollfilter, Divi-Hinweis, Rollen-Rückfrage
- Tools: „Ganze Gruppe“ und „Nur lesen“ wirken sofort auf die Zeilen
  (Option „wie Gruppe (…)“, gesperrte Selects mit Hinweis), der Server
  bleibt die Wahrheit; Markup trägt die nötigen data-Attribute.
- Protokoll: Filter in eigenem Block über der Tabelle (Core blendet
  .tablenav .actions auf Telefonen aus); „Protokoll leeren“ nur bei
  Einträgen, rechtsbündig, mit Gesamtzahl über ChangeLog::count().
- Divi: Beschreibung unter „Prüfung starten“, Button primär solange
  ungetestet ohne frischen Bericht.
- Zugriff: Rückfrage vor dem Speichern ohne Rolle oder ohne eigene Rolle.
- Verbindung: HTTPS-Hinweis nicht doppelt neben der Statusliste.
- Mobil: breitere Einstellungs-Spalte im Tools-Reiter.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-08 16:39:44 +02:00

172 lines
5.2 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* Einstellungen → LIT MCP: copy the server URL, live group feedback and collapsible tool
groups, filter paging, and a question before a role save that locks people out. */
( function () {
'use strict';
// "URL kopieren" – like WordPress' "Copy URL to clipboard" in the media library.
function setUpCopyButton() {
var hideTimeout;
if ( ! window.ClipboardJS || ! document.querySelector( '.lit-mcp-copy' ) ) {
return;
}
new window.ClipboardJS( '.lit-mcp-copy' ).on( 'success', function ( event ) {
var success = event.trigger.parentNode.querySelector( '.success' );
event.clearSelection();
event.trigger.focus();
if ( success ) {
clearTimeout( hideTimeout );
success.classList.remove( 'hidden' );
hideTimeout = setTimeout( function () {
success.classList.add( 'hidden' );
}, 3000 );
}
if ( window.wp && window.wp.a11y && window.litMcpAdmin ) {
window.wp.a11y.speak( window.litMcpAdmin.copied );
}
} );
}
// Tool groups: WordPress' own postbox toggles, closed state saved per user.
function setUpGroupToggles() {
if ( window.postboxes && window.pagenow && document.querySelector( '.lit-mcp-groups' ) ) {
window.postboxes.add_postbox_toggles( window.pagenow );
}
}
/*
* Tools: a group's mode and its "nur lesen" switch show on the group's rows at once,
* the same way the page renders them after saving (the server stays the authority).
*/
function setUpLiveGroupFeedback() {
var groups = document.querySelector( '.lit-mcp-groups' );
if ( ! groups ) {
return;
}
groups.querySelectorAll( '.lit-mcp-group' ).forEach( function ( group ) {
var mode = group.querySelector( '.lit-mcp-group-mode' );
var readonly = group.querySelector( '.lit-mcp-group-readonly' );
var tools = group.querySelectorAll( '.lit-mcp-tool-mode' );
if ( mode ) {
mode.addEventListener( 'change', function () {
tools.forEach( function ( select ) {
labelInheritedOption( select, mode, groups.dataset.likeGroup );
} );
} );
}
if ( readonly ) {
readonly.addEventListener( 'change', function () {
tools.forEach( function ( select ) {
if ( select.dataset.writes ) {
lockTool( select, readonly.checked );
}
} );
} );
}
} );
}
// First option: "Standard (…)" without a group mode, "wie Gruppe (…)" with one.
function labelInheritedOption( select, mode, likeGroup ) {
var label;
if ( select.dataset.required ) {
return;
}
if ( ! mode.value ) {
select.options[ 0 ].text = select.dataset.defaultLabel;
return;
}
label = mode.options[ mode.selectedIndex ].text;
if ( select.dataset.directOnly && mode.value === 'indirect' ) {
label = optionText( select, 'direct' ) || label;
}
select.options[ 0 ].text = likeGroup.replace( '%s', label );
}
function optionText( select, value ) {
var option = select.querySelector( 'option[value="' + value + '"]' );
return option ? option.text : '';
}
/*
* "Nur lesen": the select of a writing tool is disabled and its note shown. A disabled
* select is not submitted, so its own setting is kept in a hidden field meanwhile
* (the server does the same when it renders a locked row).
*/
function lockTool( select, locked ) {
var cell = select.parentNode;
var note = cell.querySelector( '.lit-mcp-readonly-note' );
var keep = cell.querySelector( 'input[type="hidden"][name="' + select.name + '"]' );
select.disabled = locked;
if ( locked && select.value && ! keep ) {
keep = document.createElement( 'input' );
keep.type = 'hidden';
keep.name = select.name;
keep.value = select.value;
cell.appendChild( keep );
}
if ( ! locked && keep ) {
keep.remove();
}
if ( note ) {
note.hidden = ! locked;
}
}
// Protokoll: a changed filter starts again on page 1.
function setUpFilterPaging() {
document.querySelectorAll( '.lit-mcp-log-filters select, .lit-mcp-log-filters input' ).forEach(
function ( control ) {
control.addEventListener( 'change', function () {
var paged = control.form && control.form.querySelector( 'input[name="paged"]' );
if ( paged ) {
paged.value = '1';
}
} );
}
);
}
// Zugriff: ask before saving a role set that leaves nobody, or the admin themselves, with access.
function setUpAccessConfirmation() {
var form = document.querySelector( '.lit-mcp-access-form' );
if ( ! form ) {
return;
}
form.addEventListener( 'submit', function ( event ) {
var checked = Array.prototype.map.call(
form.querySelectorAll( 'input[type="checkbox"]:checked' ),
function ( box ) {
return box.value;
}
);
var own = form.dataset.ownRoles ? form.dataset.ownRoles.split( ' ' ) : null;
var question = '';
if ( checked.length === 0 ) {
question = form.dataset.confirmNone;
} else if ( own && ! own.some( function ( role ) { return checked.indexOf( role ) !== -1; } ) ) {
question = form.dataset.confirmOwn;
}
if ( question && ! window.confirm( question ) ) {
event.preventDefault();
}
} );
}
document.addEventListener( 'DOMContentLoaded', function () {
setUpCopyButton();
setUpGroupToggles();
setUpLiveGroupFeedback();
setUpFilterPaging();
setUpAccessConfirmation();
} );
}() );