Files
2meet-data-optimizer/admin/assets/wpdo-settings.js
T
wpdev 6f117f4e9b
Anti-EAV Lint + Quality Gate / anti-eav-lint (pull_request) Successful in 21s
Tests / PHP Lint (pull_request) Successful in 18s
Tests / Unit Tests (pull_request) Successful in 41s
Tests / Integration Tests (pull_request) Successful in 1m25s
Tests / PHPCS (pull_request) Successful in 44s
Tests / PHPStan (pull_request) Successful in 47s
fix(2meet-data-optimizer): 1.4.2 acceptance fixes for archive sweep and uninstall
- Archive sweep waits until idx_original_meta exists (a plugin update does
  not run dbDelta; without the index NOT EXISTS scans the archive per row)
- Duplicate archive cleanup runs from WP-CLI only, never in a web activation
- Uninstall keeps the LatePoint add-on's tmdo_latepoint_db_version
- AJAX save errors stay on screen instead of fading after 2.5 s
- Verify: 2 new integration tests; unit 711, integration 612, phpcs 0, stan OK
- PR: PR-141 (2.4.2 correctness review)
2026-09-28 18:43:50 +08:00

110 lines
2.8 KiB
JavaScript

/**
* WP Data Optimizer — Settings per-section instant save.
*
* Each .wpdo-settings-section card has a "儲存此區塊" button that posts only
* that section's fields via AJAX, updating options without a full page reload.
*
* @since 3.0.2
*/
/* global wpdoSettings */
( function () {
'use strict';
if ( typeof wpdoSettings === 'undefined' ) {
return;
}
const { ajaxUrl, nonce, i18n } = wpdoSettings;
/**
* Collect form fields within a section into a FormData object.
* Unchecked checkboxes are intentionally omitted (server does isset() ? '1' : '0').
*
* @param {HTMLElement} section
* @returns {FormData}
*/
function collectFields( section ) {
const fd = new FormData();
section.querySelectorAll( 'input, select, textarea' ).forEach( ( el ) => {
if ( ! el.name ) {
return;
}
if ( el.type === 'checkbox' ) {
if ( el.checked ) {
fd.append( el.name, el.value );
}
} else if ( el.type === 'radio' ) {
if ( el.checked ) {
fd.append( el.name, el.value );
}
} else {
fd.append( el.name, el.value );
}
} );
return fd;
}
/**
* Show a status message; success fades out after 2.5s, errors stay.
*
* @param {HTMLElement} statusEl
* @param {string} message
* @param {boolean} isError
*/
function showStatus( statusEl, message, isError ) {
statusEl.textContent = message;
statusEl.style.color = isError ? 'var(--color-error, #b03d3d)' : 'var(--color-success, #5a8c5a)';
statusEl.classList.add( 'visible' );
clearTimeout( statusEl._wpdo_timer );
if ( isError ) {
return;
}
statusEl._wpdo_timer = setTimeout( () => {
statusEl.classList.remove( 'visible' );
}, 2500 );
}
document.addEventListener( 'click', function ( e ) {
const btn = e.target.closest( '.wpdo-section-save' );
if ( ! btn ) {
return;
}
const section = btn.closest( '.wpdo-settings-section' );
const statusEl = btn.nextElementSibling;
const sectionKey = section ? section.dataset.section : '';
if ( ! sectionKey ) {
return;
}
const originalLabel = btn.textContent;
btn.disabled = true;
btn.textContent = i18n.saving;
const fd = collectFields( section );
fd.append( 'action', 'wpdo_save_settings_section' );
fd.append( '_ajax_nonce', nonce );
fd.append( 'section', sectionKey );
fetch( ajaxUrl, {
method : 'POST',
credentials : 'same-origin',
body : fd,
} )
.then( ( r ) => r.json() )
.then( ( data ) => {
if ( data.success ) {
showStatus( statusEl, i18n.saved, false );
} else {
showStatus( statusEl, ( data.data && data.data.message ) || i18n.error, true );
}
} )
.catch( () => {
showStatus( statusEl, i18n.error, true );
} )
.finally( () => {
btn.disabled = false;
btn.textContent = originalLabel;
} );
} );
} )();