Files
DarkflameServer/dDashboardServer/static/js/wait-for-jq-dt.js
Aaron Kimbrell e3467465b4 Add dashboard audit log and configuration management
- Implemented dashboard audit logging with InsertAuditLog, GetRecentAuditLogs, GetAuditLogsByIP, and CleanupOldAuditLogs methods.
- Created dashboard configuration management with GetDashboardConfig and SetDashboardConfig methods.
- Added new tables for dashboard_audit_log and dashboard_config in both MySQL and SQLite migrations.
- Updated CMakeLists to include Crow and ASIO for dashboard server functionality.
- Enhanced existing database classes to support new dashboard features, including character, play key, and property management.
- Added new methods for retrieving and managing play keys, properties, and pet names.
- Updated TestSQLDatabase to include stubs for new dashboard-related methods.
- Modified shared and dashboard configuration files for new settings.
2026-04-22 11:01:41 -05:00

76 lines
3.1 KiB
JavaScript

// Helper to wait for jQuery and DataTables (and optionally API) to be available
// Usage:
// safeInit(callback, { timeout: 5000, interval: 100, requireApi: false })
// The callback receives `window.jQuery` as its first argument.
(function(window) {
'use strict';
function waitFor(conditionFn, timeoutMs, intervalMs) {
return new Promise((resolve, reject) => {
const start = Date.now();
const iv = setInterval(() => {
try {
if (conditionFn()) {
clearInterval(iv);
resolve();
return;
}
} catch (e) {
// ignore
}
if (Date.now() - start > timeoutMs) {
clearInterval(iv);
reject(new Error('waitFor: timed out'));
}
}, intervalMs);
});
}
async function safeInit(cb, opts) {
opts = opts || {};
const timeout = typeof opts.timeout === 'number' ? opts.timeout : 5000;
const interval = typeof opts.interval === 'number' ? opts.interval : 100;
const requireApi = !!opts.requireApi;
// Wait for DOM ready first so scripts included at end of body have run
if (document.readyState === 'loading') {
await new Promise(r => document.addEventListener('DOMContentLoaded', r, { once: true }));
}
try {
await waitFor(() => window.jQuery && window.jQuery.fn && window.jQuery.fn.DataTable, timeout, interval);
if (requireApi) {
await waitFor(() => window.API, timeout, interval);
}
// call callback with jQuery
try { cb(window.jQuery); } catch (e) { console.error('safeInit callback error', e); }
} catch (err) {
console.error('safeInit: required libraries failed to load', err);
// If callback provided an onError handler, call it
if (opts.onError && typeof opts.onError === 'function') {
try { opts.onError(err); } catch (e) { console.error(e); }
} else {
// default fallback: show a banner if possible
const tableEls = document.querySelectorAll('table');
if (tableEls && tableEls.length) {
tableEls.forEach(el => {
const wrapper = document.createElement('div');
wrapper.className = 'alert alert-danger';
wrapper.textContent = 'Required JavaScript libraries failed to load (jQuery/DataTables). Please check your network or CDN allowlist.';
el.replaceWith(wrapper);
});
} else {
console.warn('safeInit: libraries missing');
}
}
}
}
// Expose globally
window.safeInit = safeInit;
window.waitForLibraries = function(timeoutMs, intervalMs) {
return waitFor(() => window.jQuery && window.jQuery.fn && window.jQuery.fn.DataTable, timeoutMs || 5000, intervalMs || 100);
};
})(window);