diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 414b129..a533f33 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -144,26 +144,26 @@ } } }, - { - "type": "docker-build", - "label": "docker-build", - "platform": "python", - "dockerBuild": { - "tag": "gogo2:latest", - "dockerfile": "${workspaceFolder}/Dockerfile", - "context": "${workspaceFolder}", - "pull": true - } - }, - { - "type": "docker-run", - "label": "docker-run: debug", - "dependsOn": [ - "docker-build" - ], - "python": { - "file": "run_clean_dashboard.py" - } - } + // { + // "type": "docker-build", + // "label": "docker-build", + // "platform": "python", + // "dockerBuild": { + // "tag": "gogo2:latest", + // "dockerfile": "${workspaceFolder}/Dockerfile", + // "context": "${workspaceFolder}", + // "pull": true + // } + // }, + // { + // "type": "docker-run", + // "label": "docker-run: debug", + // "dependsOn": [ + // "docker-build" + // ], + // "python": { + // "file": "run_clean_dashboard.py" + // } + // } ] } \ No newline at end of file diff --git a/ANNOTATE/core/data_loader.py b/ANNOTATE/core/data_loader.py index 8e15c95..a572533 100644 --- a/ANNOTATE/core/data_loader.py +++ b/ANNOTATE/core/data_loader.py @@ -67,6 +67,26 @@ class HistoricalDataLoader: return cached_data try: + # Try to get data from DataProvider's cached data first (most efficient) + if hasattr(self.data_provider, 'cached_data'): + with self.data_provider.data_lock: + cached_df = self.data_provider.cached_data.get(symbol, {}).get(timeframe) + + if cached_df is not None and not cached_df.empty: + # Use cached data if we have enough candles + if len(cached_df) >= min(limit, 100): # Use cached if we have at least 100 candles + logger.debug(f"Using DataProvider cached data for {symbol} {timeframe} ({len(cached_df)} candles)") + + # Filter by time range if specified + if start_time or end_time: + filtered_df = self._filter_by_time_range(cached_df.copy(), start_time, end_time) + else: + filtered_df = cached_df.tail(limit).copy() + + # Cache in memory + self.memory_cache[cache_key] = (filtered_df, datetime.now()) + return filtered_df + # Try unified storage first if available if hasattr(self.data_provider, 'is_unified_storage_enabled') and \ self.data_provider.is_unified_storage_enabled(): diff --git a/ANNOTATE/web/templates/annotation_dashboard.html b/ANNOTATE/web/templates/annotation_dashboard.html index e0dd5ff..9c1689c 100644 --- a/ANNOTATE/web/templates/annotation_dashboard.html +++ b/ANNOTATE/web/templates/annotation_dashboard.html @@ -300,14 +300,33 @@ } function deleteAnnotation(annotationId) { - console.log('deleteAnnotation called with ID:', annotationId); + console.log('=== deleteAnnotation called ==='); + console.log('Annotation ID:', annotationId); + console.log('window.appState:', window.appState); + console.log('window.appState.annotations:', window.appState?.annotations); - if (!window.appState || !window.appState.annotations) { - console.error('appState not initialized'); + if (!annotationId) { + console.error('No annotation ID provided'); + showError('No annotation ID provided'); return; } - console.log('Current annotations:', window.appState.annotations.map(a => a.annotation_id)); + if (!window.appState || !window.appState.annotations) { + console.error('appState not initialized'); + showError('Application state not initialized. Please refresh the page.'); + return; + } + + // Check if annotation exists + const annotation = window.appState.annotations.find(a => a.annotation_id === annotationId); + if (!annotation) { + console.error('Annotation not found in appState:', annotationId); + showError('Annotation not found'); + return; + } + + console.log('Found annotation:', annotation); + console.log('Current annotations count:', window.appState.annotations.length); if (!confirm('Delete this annotation?')) { console.log('Delete cancelled by user'); @@ -322,35 +341,45 @@ }) .then(response => { console.log('Delete response status:', response.status); + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`); + } return response.json(); }) .then(data => { console.log('Delete response data:', data); if (data.success) { + console.log('Delete successful, updating UI...'); + // Remove from app state - if (window.appState && window.appState.annotations) { - window.appState.annotations = window.appState.annotations.filter( - a => a.annotation_id !== annotationId - ); - console.log('Removed from appState, remaining:', window.appState.annotations.length); - } + const originalCount = window.appState.annotations.length; + window.appState.annotations = window.appState.annotations.filter( + a => a.annotation_id !== annotationId + ); + console.log(`Removed from appState: ${originalCount} -> ${window.appState.annotations.length}`); // Update UI if (typeof renderAnnotationsList === 'function') { renderAnnotationsList(window.appState.annotations); - console.log('UI updated'); + console.log('UI updated with renderAnnotationsList'); } else { console.error('renderAnnotationsList function not found'); + // Try to reload the page as fallback + location.reload(); + return; } // Remove from chart if (window.appState && window.appState.chartManager) { window.appState.chartManager.removeAnnotation(annotationId); console.log('Removed from chart'); + } else { + console.warn('Chart manager not available'); } showSuccess('Annotation deleted successfully'); + console.log('=== deleteAnnotation completed successfully ==='); } else { console.error('Delete failed:', data.error); showError('Failed to delete annotation: ' + (data.error ? data.error.message : 'Unknown error')); @@ -372,6 +401,9 @@ console.log('=== setupGlobalFunctions called ==='); console.log('deleteAnnotation function exists:', typeof deleteAnnotation); console.log('highlightAnnotation function exists:', typeof highlightAnnotation); + console.log('renderAnnotationsList function exists:', typeof renderAnnotationsList); + console.log('showError function exists:', typeof showError); + console.log('showSuccess function exists:', typeof showSuccess); // Make functions globally available window.showError = showError; @@ -386,6 +418,7 @@ console.log(' - window.renderAnnotationsList:', typeof window.renderAnnotationsList); console.log(' - window.showError:', typeof window.showError); console.log(' - window.showSuccess:', typeof window.showSuccess); + console.log(' - window.highlightAnnotation:', typeof window.highlightAnnotation); // Test call console.log('Testing window.deleteAnnotation availability...'); @@ -394,6 +427,40 @@ } else { console.error('✗ window.deleteAnnotation is NOT a function!'); } + + // Add a test button to verify functionality (temporary) + console.log('Adding test delete function to window for debugging...'); + window.testDeleteFunction = function() { + console.log('Test delete function called'); + console.log('window.deleteAnnotation type:', typeof window.deleteAnnotation); + if (typeof window.deleteAnnotation === 'function') { + console.log('window.deleteAnnotation is available'); + // Test with a fake ID to see if the function runs + console.log('Testing delete function with fake ID...'); + try { + window.deleteAnnotation('test-fake-id'); + } catch (error) { + console.error('Error in test delete:', error); + } + } else { + console.error('window.deleteAnnotation is NOT available'); + } + }; + + // Add test button to page (temporary debugging) + const testButton = document.createElement('button'); + testButton.textContent = 'Test Delete Function'; + testButton.className = 'btn btn-warning btn-sm'; + testButton.style.position = 'fixed'; + testButton.style.top = '10px'; + testButton.style.right = '10px'; + testButton.style.zIndex = '9999'; + testButton.onclick = function() { + console.log('Test button clicked'); + window.testDeleteFunction(); + }; + document.body.appendChild(testButton); + console.log('Test button added to page'); } function renderAnnotationsList(annotations) { @@ -438,15 +505,23 @@ item.querySelector('.delete-btn').addEventListener('click', function(e) { e.stopPropagation(); - console.log('Delete button clicked for:', annotation.annotation_id); + console.log('=== Delete button clicked ==='); + console.log('Annotation ID:', annotation.annotation_id); console.log('window.deleteAnnotation type:', typeof window.deleteAnnotation); + console.log('window object keys containing delete:', Object.keys(window).filter(k => k.includes('delete'))); if (typeof window.deleteAnnotation === 'function') { console.log('Calling window.deleteAnnotation...'); - window.deleteAnnotation(annotation.annotation_id); + try { + window.deleteAnnotation(annotation.annotation_id); + } catch (error) { + console.error('Error calling deleteAnnotation:', error); + showError('Error calling delete function: ' + error.message); + } } else { console.error('window.deleteAnnotation is not a function:', typeof window.deleteAnnotation); - alert('Delete function not available. Please refresh the page.'); + console.log('Available window functions:', Object.keys(window).filter(k => typeof window[k] === 'function')); + showError('Delete function not available. Please refresh the page.'); } }); diff --git a/ANNOTATE/web/templates/components/annotation_list.html b/ANNOTATE/web/templates/components/annotation_list.html index 3e3fdbf..b2e0e94 100644 --- a/ANNOTATE/web/templates/components/annotation_list.html +++ b/ANNOTATE/web/templates/components/annotation_list.html @@ -165,18 +165,32 @@ item.querySelector('.delete-annotation-btn').addEventListener('click', function(e) { e.stopPropagation(); - console.log('Delete button clicked for:', annotation.annotation_id); + console.log('=== Delete annotation button clicked ==='); + console.log('Annotation ID:', annotation.annotation_id); console.log('window.deleteAnnotation type:', typeof window.deleteAnnotation); - console.log('window object keys:', Object.keys(window).filter(k => k.includes('delete'))); + console.log('window object keys containing delete:', Object.keys(window).filter(k => k.includes('delete'))); // Use window.deleteAnnotation to ensure we get the global function if (typeof window.deleteAnnotation === 'function') { console.log('Calling window.deleteAnnotation...'); - window.deleteAnnotation(annotation.annotation_id); + try { + window.deleteAnnotation(annotation.annotation_id); + } catch (error) { + console.error('Error calling deleteAnnotation:', error); + if (typeof window.showError === 'function') { + window.showError('Error calling delete function: ' + error.message); + } else { + alert('Error calling delete function: ' + error.message); + } + } } else { console.error('window.deleteAnnotation is not a function:', typeof window.deleteAnnotation); console.log('Available functions:', Object.keys(window).filter(k => typeof window[k] === 'function')); - alert('Delete function not available. Please refresh the page.'); + if (typeof window.showError === 'function') { + window.showError('Delete function not available. Please refresh the page.'); + } else { + alert('Delete function not available. Please refresh the page.'); + } } }); diff --git a/core/data_provider.py b/core/data_provider.py index 791e135..baeafbd 100644 --- a/core/data_provider.py +++ b/core/data_provider.py @@ -378,7 +378,7 @@ class DataProvider: bool: True if successful, False otherwise """ if not UNIFIED_STORAGE_AVAILABLE: - logger.error("Unified storage components not available. Install required dependencies.") + logger.debug("Unified storage components not available - skipping (optional feature)") return False if self._unified_storage_enabled: