SmokeScan / ui /storage.py
KinetoLabs's picture
Fix critical model implementations and add sample scenarios
f3ebc82
"""localStorage integration for Gradio via JavaScript injection.
Provides JavaScript code that syncs session state with browser localStorage.
"""
# localStorage keys
STORAGE_KEY_SESSION = "fdam_current_session"
STORAGE_KEY_HISTORY = "fdam_assessment_history"
STORAGE_KEY_IMAGES = "fdam_image_refs" # References only, not actual bytes
# JavaScript code for localStorage operations
LOCALSTORAGE_JS = """
<script>
(function() {
// FDAM localStorage utilities
window.fdamStorage = {
KEYS: {
SESSION: 'fdam_current_session',
HISTORY: 'fdam_assessment_history',
IMAGE_REFS: 'fdam_image_refs'
},
// Save current session
saveSession: function(sessionJson) {
try {
localStorage.setItem(this.KEYS.SESSION, sessionJson);
console.log('[FDAM] Session saved to localStorage');
return true;
} catch (e) {
console.error('[FDAM] Failed to save session:', e);
return false;
}
},
// Load current session
loadSession: function() {
try {
const data = localStorage.getItem(this.KEYS.SESSION);
if (data) {
console.log('[FDAM] Session loaded from localStorage');
return data;
}
} catch (e) {
console.error('[FDAM] Failed to load session:', e);
}
return null;
},
// Save assessment history
saveHistory: function(historyJson) {
try {
localStorage.setItem(this.KEYS.HISTORY, historyJson);
console.log('[FDAM] History saved to localStorage');
return true;
} catch (e) {
console.error('[FDAM] Failed to save history:', e);
return false;
}
},
// Load assessment history
loadHistory: function() {
try {
const data = localStorage.getItem(this.KEYS.HISTORY);
if (data) {
console.log('[FDAM] History loaded from localStorage');
return data;
}
} catch (e) {
console.error('[FDAM] Failed to load history:', e);
}
return null;
},
// Clear all FDAM data
clearAll: function() {
try {
localStorage.removeItem(this.KEYS.SESSION);
localStorage.removeItem(this.KEYS.HISTORY);
localStorage.removeItem(this.KEYS.IMAGE_REFS);
console.log('[FDAM] All localStorage data cleared');
return true;
} catch (e) {
console.error('[FDAM] Failed to clear storage:', e);
return false;
}
},
// Get storage usage info
getStorageInfo: function() {
try {
let total = 0;
for (let key in localStorage) {
if (key.startsWith('fdam_')) {
total += localStorage.getItem(key).length;
}
}
return {
used_bytes: total,
used_kb: (total / 1024).toFixed(2),
limit_kb: 5120 // ~5MB typical limit
};
} catch (e) {
return { error: e.message };
}
}
};
// Expose to global scope for Gradio callbacks
window.saveSession = window.fdamStorage.saveSession.bind(window.fdamStorage);
window.loadSession = window.fdamStorage.loadSession.bind(window.fdamStorage);
window.saveHistory = window.fdamStorage.saveHistory.bind(window.fdamStorage);
window.loadHistory = window.fdamStorage.loadHistory.bind(window.fdamStorage);
console.log('[FDAM] localStorage utilities loaded');
})();
</script>
"""
# JavaScript functions for Gradio event handlers
JS_SAVE_SESSION = """
async (sessionJson) => {
if (window.fdamStorage) {
window.fdamStorage.saveSession(sessionJson);
}
return sessionJson;
}
"""
JS_LOAD_SESSION = """
async () => {
if (window.fdamStorage) {
return window.fdamStorage.loadSession() || '{}';
}
return '{}';
}
"""
JS_SAVE_HISTORY = """
async (historyJson) => {
if (window.fdamStorage) {
window.fdamStorage.saveHistory(historyJson);
}
return historyJson;
}
"""
JS_LOAD_HISTORY = """
async () => {
if (window.fdamStorage) {
return window.fdamStorage.loadHistory() || '{"assessments":[],"current_session_id":null}';
}
return '{"assessments":[],"current_session_id":null}';
}
"""
# JavaScript to auto-load session on page load
JS_AUTO_LOAD = """
async () => {
// Small delay to ensure Gradio is fully loaded
await new Promise(resolve => setTimeout(resolve, 500));
if (window.fdamStorage) {
const session = window.fdamStorage.loadSession();
const history = window.fdamStorage.loadHistory();
return [session || '{}', history || '{"assessments":[],"current_session_id":null}'];
}
return ['{}', '{"assessments":[],"current_session_id":null}'];
}
"""
def get_head_html(additional_scripts: str = "") -> str:
"""Get HTML to inject into Gradio head for localStorage support.
Args:
additional_scripts: Optional additional HTML/JS to include.
Returns:
Combined HTML string for head injection.
"""
return LOCALSTORAGE_JS + additional_scripts
def create_save_trigger_js(field_updates: dict[str, str]) -> str:
"""Create JavaScript that triggers save after field updates.
Args:
field_updates: Mapping of field name to value expression
Returns:
JavaScript code string
"""
updates = ", ".join(f'"{k}": {v}' for k, v in field_updates.items())
return f"""
async (currentSession, ...values) => {{
try {{
const session = JSON.parse(currentSession || '{{}}');
const updates = {{ {updates} }};
Object.assign(session, updates);
session.updated_at = new Date().toISOString();
const newSession = JSON.stringify(session);
if (window.fdamStorage) {{
window.fdamStorage.saveSession(newSession);
}}
return newSession;
}} catch (e) {{
console.error('[FDAM] Save trigger error:', e);
return currentSession;
}}
}}
"""