document.addEventListener('DOMContentLoaded', () => { // Initialize CodeMirror editor const editor = CodeMirror.fromTextArea(document.getElementById('scriptInput'), { mode: 'javascript', lineNumbers: true, theme: 'default', indentUnit: 4, tabSize: 4, lineWrapping: true, autoCloseBrackets: true, matchBrackets: true }); // Get DOM elements const runScriptBtn = document.getElementById('runScriptBtn'); const loadExampleBtn = document.getElementById('loadExampleBtn'); const modelSelect = document.getElementById('modelSelect'); const outputArea = document.getElementById('outputArea'); const toastContainer = document.querySelector('.toast-container'); // Function to show toast notifications function showToast(message, type = 'error') { const toastId = 'toast-' + Date.now(); const bgClass = type === 'error' ? 'bg-danger' : (type === 'warning' ? 'bg-warning' : 'bg-info'); const headerText = type === 'error' ? 'Error' : (type === 'warning' ? 'Warning' : 'Info'); // Create the toast element const toastDiv = document.createElement('div'); toastDiv.className = 'toast mb-3'; toastDiv.id = toastId; toastDiv.setAttribute('role', 'alert'); toastDiv.setAttribute('aria-live', 'assertive'); toastDiv.setAttribute('aria-atomic', 'true'); toastDiv.innerHTML = `
${headerText}
${message}
`; // Add to container toastContainer.appendChild(toastDiv); // Initialize and show the toast const toast = new bootstrap.Toast(toastDiv, { autohide: true, delay: 10000 }); toast.show(); // Remove the toast element after it's hidden toastDiv.addEventListener('hidden.bs.toast', () => { toastDiv.remove(); }); } // Function to run the script async function runScript() { const script = editor.getValue(); const modelType = modelSelect.value; if (!script.trim()) { showToast('Please enter a script to run.'); return; } outputArea.textContent = 'Running script...'; try { const response = await fetch('/api/execute', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ script, model_type: modelType }) }); const result = await response.json(); if (result.success) { outputArea.textContent = result.output || 'Script executed successfully with no output.'; } else { outputArea.textContent = result.output || 'Script execution failed.'; showToast(result.error || 'Script execution failed.', 'error'); } } catch (error) { outputArea.textContent = 'Script execution failed. See error details.'; showToast(`Error: ${error.message}`, 'error'); } } // Function to load example script async function loadExample() { const modelType = modelSelect.value; try { const response = await fetch(`/api/example/${modelType}`); if (!response.ok) { throw new Error(`Server returned ${response.status}: ${response.statusText}`); } const exampleScript = await response.text(); editor.setValue(exampleScript); outputArea.textContent = `Loaded ${modelType} example script. Click "Run Script" to execute.`; } catch (error) { // Don't show error in output area, use toast instead showToast(`Failed to load ${modelType} example: ${error.message}`, 'error'); // Clear the editor if it was a new load (not if there was already content) if (!editor.getValue().trim()) { editor.setValue('// Write your Rhai script here'); } } } // Event listeners runScriptBtn.addEventListener('click', runScript); loadExampleBtn.addEventListener('click', loadExample); // Load default example on page load loadExample(); });