Spaces:
Running
Running
Fix JavaScript errors: Add missing showWarning function and improve error handling
Browse filesFIXES:
- Added missing showWarning() function to KnowledgeDistillationApp class
- Added showSuccess() function to class for consistency
- Added proper app initialization with DOMContentLoaded event
- Added null checks for DOM elements before adding event listeners
- Added CSS styling for warning notifications
- Added debugging console logs for troubleshooting
IMPROVEMENTS:
- Better error handling with fallbacks
- More robust DOM element checking
- Consistent notification system across all message types
- Enhanced debugging capabilities
This fixes the 'this.showWarning is not a function' error when clicking 'Add Model' button.
- static/css/style.css +5 -0
- static/js/main.js +104 -28
static/css/style.css
CHANGED
|
@@ -1288,6 +1288,11 @@ body {
|
|
| 1288 |
background: #dc3545;
|
| 1289 |
}
|
| 1290 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1291 |
@keyframes slideIn {
|
| 1292 |
from {
|
| 1293 |
transform: translateX(100%);
|
|
|
|
| 1288 |
background: #dc3545;
|
| 1289 |
}
|
| 1290 |
|
| 1291 |
+
.notification-warning {
|
| 1292 |
+
background: #ffc107;
|
| 1293 |
+
color: #212529;
|
| 1294 |
+
}
|
| 1295 |
+
|
| 1296 |
@keyframes slideIn {
|
| 1297 |
from {
|
| 1298 |
transform: translateX(100%);
|
static/js/main.js
CHANGED
|
@@ -37,48 +37,81 @@ class KnowledgeDistillationApp {
|
|
| 37 |
}
|
| 38 |
|
| 39 |
init() {
|
|
|
|
| 40 |
this.setupEventListeners();
|
| 41 |
this.updateModelCount();
|
|
|
|
| 42 |
}
|
| 43 |
|
| 44 |
setupEventListeners() {
|
| 45 |
// File upload
|
| 46 |
const uploadArea = document.getElementById('upload-area');
|
| 47 |
const fileInput = document.getElementById('file-input');
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
|
|
|
|
|
|
| 55 |
// Hugging Face models
|
| 56 |
-
document.getElementById('add-hf-model')
|
| 57 |
-
document.getElementById('hf-repo')
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
// URL models
|
| 62 |
-
document.getElementById('add-url-model')
|
| 63 |
-
document.getElementById('model-url')
|
| 64 |
-
|
| 65 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
|
| 67 |
// Navigation
|
| 68 |
-
document.getElementById('next-step-1')
|
| 69 |
-
document.getElementById('back-step-2')
|
| 70 |
-
document.getElementById('back-step-3')
|
| 71 |
-
document.getElementById('start-training')
|
| 72 |
-
document.getElementById('start-new-training')
|
| 73 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
// Training controls
|
| 75 |
-
document.getElementById('cancel-training')
|
| 76 |
-
document.getElementById('download-model')
|
| 77 |
-
|
|
|
|
|
|
|
|
|
|
| 78 |
// Modals
|
| 79 |
-
document.getElementById('confirm-start')
|
| 80 |
-
document.getElementById('confirm-cancel')
|
| 81 |
-
document.getElementById('error-ok')
|
|
|
|
|
|
|
|
|
|
|
|
|
| 82 |
|
| 83 |
// Suggested models
|
| 84 |
document.querySelectorAll('.suggestion-btn').forEach(btn => {
|
|
@@ -240,10 +273,17 @@ class KnowledgeDistillationApp {
|
|
| 240 |
}
|
| 241 |
|
| 242 |
async addHuggingFaceModel() {
|
|
|
|
| 243 |
const repoInput = document.getElementById('hf-repo');
|
| 244 |
const tokenInput = document.getElementById('hf-token');
|
| 245 |
const accessTypeSelect = document.getElementById('model-access-type');
|
| 246 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 247 |
const repo = repoInput.value.trim();
|
| 248 |
const manualToken = tokenInput.value.trim();
|
| 249 |
const accessType = accessTypeSelect ? accessTypeSelect.value : 'read';
|
|
@@ -788,6 +828,26 @@ class KnowledgeDistillationApp {
|
|
| 788 |
hideErrorModal() {
|
| 789 |
document.getElementById('error-modal').classList.add('hidden');
|
| 790 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 791 |
|
| 792 |
showLoading(message) {
|
| 793 |
// Create loading overlay if it doesn't exist
|
|
@@ -1623,6 +1683,10 @@ function showError(message) {
|
|
| 1623 |
showNotification(message, 'error');
|
| 1624 |
}
|
| 1625 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1626 |
function showNotification(message, type) {
|
| 1627 |
const notification = document.createElement('div');
|
| 1628 |
notification.className = `notification notification-${type}`;
|
|
@@ -1637,3 +1701,15 @@ function showNotification(message, type) {
|
|
| 1637 |
}
|
| 1638 |
}, 5000);
|
| 1639 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
}
|
| 38 |
|
| 39 |
init() {
|
| 40 |
+
console.log('Initializing Knowledge Distillation App...');
|
| 41 |
this.setupEventListeners();
|
| 42 |
this.updateModelCount();
|
| 43 |
+
console.log('App initialization complete');
|
| 44 |
}
|
| 45 |
|
| 46 |
setupEventListeners() {
|
| 47 |
// File upload
|
| 48 |
const uploadArea = document.getElementById('upload-area');
|
| 49 |
const fileInput = document.getElementById('file-input');
|
| 50 |
+
|
| 51 |
+
if (uploadArea && fileInput) {
|
| 52 |
+
uploadArea.addEventListener('click', () => fileInput.click());
|
| 53 |
+
uploadArea.addEventListener('dragover', this.handleDragOver.bind(this));
|
| 54 |
+
uploadArea.addEventListener('dragleave', this.handleDragLeave.bind(this));
|
| 55 |
+
uploadArea.addEventListener('drop', this.handleDrop.bind(this));
|
| 56 |
+
fileInput.addEventListener('change', this.handleFileSelect.bind(this));
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
// Hugging Face models
|
| 60 |
+
const addHfModelBtn = document.getElementById('add-hf-model');
|
| 61 |
+
const hfRepoInput = document.getElementById('hf-repo');
|
| 62 |
+
|
| 63 |
+
if (addHfModelBtn) {
|
| 64 |
+
addHfModelBtn.addEventListener('click', this.addHuggingFaceModel.bind(this));
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
if (hfRepoInput) {
|
| 68 |
+
hfRepoInput.addEventListener('keypress', (e) => {
|
| 69 |
+
if (e.key === 'Enter') this.addHuggingFaceModel();
|
| 70 |
+
});
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
// URL models
|
| 74 |
+
const addUrlModelBtn = document.getElementById('add-url-model');
|
| 75 |
+
const modelUrlInput = document.getElementById('model-url');
|
| 76 |
+
|
| 77 |
+
if (addUrlModelBtn) {
|
| 78 |
+
addUrlModelBtn.addEventListener('click', this.addUrlModel.bind(this));
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
if (modelUrlInput) {
|
| 82 |
+
modelUrlInput.addEventListener('keypress', (e) => {
|
| 83 |
+
if (e.key === 'Enter') this.addUrlModel();
|
| 84 |
+
});
|
| 85 |
+
}
|
| 86 |
|
| 87 |
// Navigation
|
| 88 |
+
const nextStep1 = document.getElementById('next-step-1');
|
| 89 |
+
const backStep2 = document.getElementById('back-step-2');
|
| 90 |
+
const backStep3 = document.getElementById('back-step-3');
|
| 91 |
+
const startTraining = document.getElementById('start-training');
|
| 92 |
+
const startNewTraining = document.getElementById('start-new-training');
|
| 93 |
+
|
| 94 |
+
if (nextStep1) nextStep1.addEventListener('click', () => this.goToStep(2));
|
| 95 |
+
if (backStep2) backStep2.addEventListener('click', () => this.goToStep(1));
|
| 96 |
+
if (backStep3) backStep3.addEventListener('click', () => this.goToStep(2));
|
| 97 |
+
if (startTraining) startTraining.addEventListener('click', this.showConfirmModal.bind(this));
|
| 98 |
+
if (startNewTraining) startNewTraining.addEventListener('click', () => this.resetAndGoToStep(1));
|
| 99 |
+
|
| 100 |
// Training controls
|
| 101 |
+
const cancelTraining = document.getElementById('cancel-training');
|
| 102 |
+
const downloadModel = document.getElementById('download-model');
|
| 103 |
+
|
| 104 |
+
if (cancelTraining) cancelTraining.addEventListener('click', this.cancelTraining.bind(this));
|
| 105 |
+
if (downloadModel) downloadModel.addEventListener('click', this.downloadModel.bind(this));
|
| 106 |
+
|
| 107 |
// Modals
|
| 108 |
+
const confirmStart = document.getElementById('confirm-start');
|
| 109 |
+
const confirmCancel = document.getElementById('confirm-cancel');
|
| 110 |
+
const errorOk = document.getElementById('error-ok');
|
| 111 |
+
|
| 112 |
+
if (confirmStart) confirmStart.addEventListener('click', this.startTraining.bind(this));
|
| 113 |
+
if (confirmCancel) confirmCancel.addEventListener('click', this.hideConfirmModal.bind(this));
|
| 114 |
+
if (errorOk) errorOk.addEventListener('click', this.hideErrorModal.bind(this));
|
| 115 |
|
| 116 |
// Suggested models
|
| 117 |
document.querySelectorAll('.suggestion-btn').forEach(btn => {
|
|
|
|
| 273 |
}
|
| 274 |
|
| 275 |
async addHuggingFaceModel() {
|
| 276 |
+
console.log('addHuggingFaceModel called');
|
| 277 |
const repoInput = document.getElementById('hf-repo');
|
| 278 |
const tokenInput = document.getElementById('hf-token');
|
| 279 |
const accessTypeSelect = document.getElementById('model-access-type');
|
| 280 |
|
| 281 |
+
console.log('Elements found:', {
|
| 282 |
+
repoInput: !!repoInput,
|
| 283 |
+
tokenInput: !!tokenInput,
|
| 284 |
+
accessTypeSelect: !!accessTypeSelect
|
| 285 |
+
});
|
| 286 |
+
|
| 287 |
const repo = repoInput.value.trim();
|
| 288 |
const manualToken = tokenInput.value.trim();
|
| 289 |
const accessType = accessTypeSelect ? accessTypeSelect.value : 'read';
|
|
|
|
| 828 |
hideErrorModal() {
|
| 829 |
document.getElementById('error-modal').classList.add('hidden');
|
| 830 |
}
|
| 831 |
+
|
| 832 |
+
showWarning(message) {
|
| 833 |
+
try {
|
| 834 |
+
// Use the same notification system as showError but with warning style
|
| 835 |
+
showNotification(message, 'warning');
|
| 836 |
+
} catch (error) {
|
| 837 |
+
console.error('Error showing warning message:', error);
|
| 838 |
+
alert(`Warning: ${message}`);
|
| 839 |
+
}
|
| 840 |
+
}
|
| 841 |
+
|
| 842 |
+
showSuccess(message) {
|
| 843 |
+
try {
|
| 844 |
+
// Use the same notification system as showError but with success style
|
| 845 |
+
showNotification(message, 'success');
|
| 846 |
+
} catch (error) {
|
| 847 |
+
console.error('Error showing success message:', error);
|
| 848 |
+
alert(`Success: ${message}`);
|
| 849 |
+
}
|
| 850 |
+
}
|
| 851 |
|
| 852 |
showLoading(message) {
|
| 853 |
// Create loading overlay if it doesn't exist
|
|
|
|
| 1683 |
showNotification(message, 'error');
|
| 1684 |
}
|
| 1685 |
|
| 1686 |
+
function showWarning(message) {
|
| 1687 |
+
showNotification(message, 'warning');
|
| 1688 |
+
}
|
| 1689 |
+
|
| 1690 |
function showNotification(message, type) {
|
| 1691 |
const notification = document.createElement('div');
|
| 1692 |
notification.className = `notification notification-${type}`;
|
|
|
|
| 1701 |
}
|
| 1702 |
}, 5000);
|
| 1703 |
}
|
| 1704 |
+
|
| 1705 |
+
// Initialize the application when DOM is loaded
|
| 1706 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 1707 |
+
try {
|
| 1708 |
+
// Create global app instance
|
| 1709 |
+
window.app = new KnowledgeDistillationApp();
|
| 1710 |
+
console.log('Knowledge Distillation App initialized successfully');
|
| 1711 |
+
} catch (error) {
|
| 1712 |
+
console.error('Failed to initialize app:', error);
|
| 1713 |
+
alert('Failed to initialize application. Please refresh the page.');
|
| 1714 |
+
}
|
| 1715 |
+
});
|