mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-05-13 19:05:04 +00:00
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.
This commit is contained in:
75
dDashboardServer/static/js/wait-for-jq-dt.js
Normal file
75
dDashboardServer/static/js/wait-for-jq-dt.js
Normal file
@@ -0,0 +1,75 @@
|
||||
// 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);
|
||||
Reference in New Issue
Block a user