fixed some major bugs
هذا الالتزام موجود في:
@@ -14,7 +14,7 @@
|
|||||||
========================================================================= */
|
========================================================================= */
|
||||||
|
|
||||||
const CONFIG = {
|
const CONFIG = {
|
||||||
primaryBaseUrl: 'https://gheyma-app-2b88268529f9.hosted.ghaymah.systems',
|
primaryBaseUrl: 'https://ghaymah-app-19cc5d65231a.hosted.ghaymah.systems',
|
||||||
fallbackBaseUrl: 'http://localhost:8080',
|
fallbackBaseUrl: 'http://localhost:8080',
|
||||||
healthPath: '/health',
|
healthPath: '/health',
|
||||||
metricsPath: '/metrics',
|
metricsPath: '/metrics',
|
||||||
@@ -32,6 +32,10 @@ const CONFIG = {
|
|||||||
const CACHE_KEYS = {
|
const CACHE_KEYS = {
|
||||||
CUMULATIVE_TOTAL: 'ghaymah_cumulative_total_requests',
|
CUMULATIVE_TOTAL: 'ghaymah_cumulative_total_requests',
|
||||||
LAST_RAW_COUNT: 'ghaymah_last_raw_server_requests',
|
LAST_RAW_COUNT: 'ghaymah_last_raw_server_requests',
|
||||||
|
HISTORY: 'ghaymah_history',
|
||||||
|
UPTIME_BUCKETS: 'ghaymah_uptime_buckets',
|
||||||
|
EVENTS: 'ghaymah_events',
|
||||||
|
TOTALS: 'ghaymah_totals',
|
||||||
};
|
};
|
||||||
|
|
||||||
function getStoredTotalRequests() {
|
function getStoredTotalRequests() {
|
||||||
@@ -67,6 +71,82 @@ function updateStoredTotalRequests(serverRequests) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* =========================================================================
|
||||||
|
Persistent State Helpers (history, uptime, events, totals)
|
||||||
|
========================================================================= */
|
||||||
|
|
||||||
|
function saveState() {
|
||||||
|
try {
|
||||||
|
// Serialize history: convert Date timestamps to ISO strings
|
||||||
|
const historyToStore = state.history.map(h => ({
|
||||||
|
...h,
|
||||||
|
timestamp: h.timestamp instanceof Date ? h.timestamp.toISOString() : h.timestamp,
|
||||||
|
}));
|
||||||
|
localStorage.setItem(CACHE_KEYS.HISTORY, JSON.stringify(historyToStore));
|
||||||
|
|
||||||
|
localStorage.setItem(CACHE_KEYS.UPTIME_BUCKETS, JSON.stringify(state.uptimeBuckets));
|
||||||
|
|
||||||
|
// Serialize events: convert Date times to ISO strings
|
||||||
|
const eventsToStore = state.events.map(ev => ({
|
||||||
|
...ev,
|
||||||
|
time: ev.time instanceof Date ? ev.time.toISOString() : ev.time,
|
||||||
|
}));
|
||||||
|
localStorage.setItem(CACHE_KEYS.EVENTS, JSON.stringify(eventsToStore));
|
||||||
|
|
||||||
|
localStorage.setItem(CACHE_KEYS.TOTALS, JSON.stringify({
|
||||||
|
success: state.totals.success,
|
||||||
|
failed: state.totals.failed,
|
||||||
|
}));
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadState() {
|
||||||
|
try {
|
||||||
|
const historyRaw = localStorage.getItem(CACHE_KEYS.HISTORY);
|
||||||
|
if (historyRaw) {
|
||||||
|
const parsed = JSON.parse(historyRaw);
|
||||||
|
state.history = parsed.map(h => ({
|
||||||
|
...h,
|
||||||
|
timestamp: new Date(h.timestamp),
|
||||||
|
}));
|
||||||
|
// Trim to max allowed
|
||||||
|
if (state.history.length > CONFIG.maxHistoryPoints) {
|
||||||
|
state.history = state.history.slice(-CONFIG.maxHistoryPoints);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (_) { state.history = []; }
|
||||||
|
|
||||||
|
try {
|
||||||
|
const bucketsRaw = localStorage.getItem(CACHE_KEYS.UPTIME_BUCKETS);
|
||||||
|
if (bucketsRaw) {
|
||||||
|
state.uptimeBuckets = JSON.parse(bucketsRaw);
|
||||||
|
if (state.uptimeBuckets.length > CONFIG.uptimeBuckets) {
|
||||||
|
state.uptimeBuckets = state.uptimeBuckets.slice(-CONFIG.uptimeBuckets);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (_) { state.uptimeBuckets = []; }
|
||||||
|
|
||||||
|
try {
|
||||||
|
const eventsRaw = localStorage.getItem(CACHE_KEYS.EVENTS);
|
||||||
|
if (eventsRaw) {
|
||||||
|
const parsed = JSON.parse(eventsRaw);
|
||||||
|
state.events = parsed.map(ev => ({
|
||||||
|
...ev,
|
||||||
|
time: new Date(ev.time),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
} catch (_) { state.events = []; }
|
||||||
|
|
||||||
|
try {
|
||||||
|
const totalsRaw = localStorage.getItem(CACHE_KEYS.TOTALS);
|
||||||
|
if (totalsRaw) {
|
||||||
|
const t = JSON.parse(totalsRaw);
|
||||||
|
state.totals.success = typeof t.success === 'number' ? t.success : 0;
|
||||||
|
state.totals.failed = typeof t.failed === 'number' ? t.failed : 0;
|
||||||
|
}
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
/* =========================================================================
|
/* =========================================================================
|
||||||
State
|
State
|
||||||
========================================================================= */
|
========================================================================= */
|
||||||
@@ -252,6 +332,9 @@ async function refreshFromSources() {
|
|||||||
}
|
}
|
||||||
state.metricsError = metricsRes.error || 'unavailable';
|
state.metricsError = metricsRes.error || 'unavailable';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Persist all state to localStorage after every refresh
|
||||||
|
saveState();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* =========================================================================
|
/* =========================================================================
|
||||||
@@ -670,7 +753,8 @@ async function doRefresh() {
|
|||||||
========================================================================= */
|
========================================================================= */
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
renderAll(); // Initial empty state paint
|
loadState(); // Restore persisted state before first paint
|
||||||
|
renderAll(); // Paint with restored data
|
||||||
|
|
||||||
document.getElementById('refreshBtn').addEventListener('click', doRefresh);
|
document.getElementById('refreshBtn').addEventListener('click', doRefresh);
|
||||||
window.addEventListener('resize', debounce(renderAll, 150));
|
window.addEventListener('resize', debounce(renderAll, 150));
|
||||||
|
|||||||
المرجع في مشكلة جديدة
حظر مستخدم