feat: bolt dyi datatab (#1570)

* Update DataTab.tsx

## API Key Import Fix

We identified and fixed an issue with the API key import functionality in the DataTab component. The problem was that API keys were being stored in localStorage instead of cookies, and the key format was being incorrectly processed.

### Changes Made:

1. **Updated `handleImportAPIKeys` function**:
   - Changed to store API keys in cookies instead of localStorage
   - Modified to use provider names directly as keys (e.g., "OpenAI", "Google")
   - Added logic to skip comment fields (keys starting with "_")
   - Added page reload after successful import to apply changes immediately

2. **Updated `handleDownloadTemplate` function**:
   - Changed template format to use provider names as keys
   - Added explanatory comment in the template
   - Removed URL-related keys that weren't being used properly

3. **Fixed template format**:
   - Template now uses the correct format with provider names as keys
   - Added support for all available providers including Hyperbolic

These changes ensure that when users download the template, fill it with their API keys, and import it back, the keys are properly stored in cookies with the correct format that the application expects.

* backwards compatible old import template

* Update the export / import settings

Settings Export/Import Improvements
We've completely redesigned the settings export and import functionality to ensure all application settings are properly backed up and restored:
Key Improvements
Comprehensive Export Format: Now captures ALL settings from both localStorage and cookies, organized into logical categories (core, providers, features, UI, connections, debug, updates)
Robust Import System: Automatically detects format version and handles both new and legacy formats with detailed error handling
Complete Settings Coverage: Properly exports and imports settings from ALL tabs including:
Local provider configurations (Ollama, LMStudio, etc.)
Cloud provider API keys (OpenAI, Anthropic, etc.)
Feature toggles and preferences
UI configurations and tab settings
Connection settings (GitHub, Netlify)
Debug configurations and logs
Technical Details
Added version tracking to export files for better compatibility
Implemented fallback mechanisms if primary import methods fail
Added detailed logging for troubleshooting import/export issues
Created helper functions for safer data handling
Maintained backward compatibility with older export formats

Feature Settings:
Feature flags and viewed features
Developer mode settings
Energy saver mode configurations
User Preferences:
User profile information
Theme settings
Tab configurations
Connection Settings:
Netlify connections
Git authentication credentials
Any other service connections
Debug and System Settings:
Debug flags and acknowledged issues
Error logs and event logs
Update settings and preferences

* Update DataTab.tsx

* Update GithubConnection.tsx

revert the code back as asked

* feat: enhance style to match the project

* feat:small improvements

* feat: add major improvements

* Update Dialog.tsx

* Delete DataTab.tsx.bak

* feat: small updates

* Update DataVisualization.tsx

* feat: dark mode fix
This commit is contained in:
Stijnus
2025-03-29 20:43:07 +01:00
committed by GitHub
parent 47444970e8
commit b86fd63700
15 changed files with 6698 additions and 3940 deletions

View File

@@ -342,24 +342,86 @@ export default function DebugTab() {
try {
setLoading((prev) => ({ ...prev, systemInfo: true }));
// Get browser info
const ua = navigator.userAgent;
const browserName = ua.includes('Firefox')
? 'Firefox'
: ua.includes('Chrome')
? 'Chrome'
: ua.includes('Safari')
? 'Safari'
: ua.includes('Edge')
? 'Edge'
: 'Unknown';
const browserVersion = ua.match(/(Firefox|Chrome|Safari|Edge)\/([0-9.]+)/)?.[2] || 'Unknown';
// Get better OS detection
const userAgent = navigator.userAgent;
let detectedOS = 'Unknown';
let detectedArch = 'unknown';
// Improved OS detection
if (userAgent.indexOf('Win') !== -1) {
detectedOS = 'Windows';
} else if (userAgent.indexOf('Mac') !== -1) {
detectedOS = 'macOS';
} else if (userAgent.indexOf('Linux') !== -1) {
detectedOS = 'Linux';
} else if (userAgent.indexOf('Android') !== -1) {
detectedOS = 'Android';
} else if (/iPhone|iPad|iPod/.test(userAgent)) {
detectedOS = 'iOS';
}
// Better architecture detection
if (userAgent.indexOf('x86_64') !== -1 || userAgent.indexOf('x64') !== -1 || userAgent.indexOf('WOW64') !== -1) {
detectedArch = 'x64';
} else if (userAgent.indexOf('x86') !== -1 || userAgent.indexOf('i686') !== -1) {
detectedArch = 'x86';
} else if (userAgent.indexOf('arm64') !== -1 || userAgent.indexOf('aarch64') !== -1) {
detectedArch = 'arm64';
} else if (userAgent.indexOf('arm') !== -1) {
detectedArch = 'arm';
}
// Get browser info with improved detection
const browserName = (() => {
if (userAgent.indexOf('Edge') !== -1 || userAgent.indexOf('Edg/') !== -1) {
return 'Edge';
}
if (userAgent.indexOf('Chrome') !== -1) {
return 'Chrome';
}
if (userAgent.indexOf('Firefox') !== -1) {
return 'Firefox';
}
if (userAgent.indexOf('Safari') !== -1) {
return 'Safari';
}
return 'Unknown';
})();
const browserVersionMatch = userAgent.match(/(Edge|Edg|Chrome|Firefox|Safari)[\s/](\d+(\.\d+)*)/);
const browserVersion = browserVersionMatch ? browserVersionMatch[2] : 'Unknown';
// Get performance metrics
const memory = (performance as any).memory || {};
const timing = performance.timing;
const navigation = performance.navigation;
const connection = (navigator as any).connection;
const connection = (navigator as any).connection || {};
// Try to use Navigation Timing API Level 2 when available
let loadTime = 0;
let domReadyTime = 0;
try {
const navEntries = performance.getEntriesByType('navigation');
if (navEntries.length > 0) {
const navTiming = navEntries[0] as PerformanceNavigationTiming;
loadTime = navTiming.loadEventEnd - navTiming.startTime;
domReadyTime = navTiming.domContentLoadedEventEnd - navTiming.startTime;
} else {
// Fall back to older API
loadTime = timing.loadEventEnd - timing.navigationStart;
domReadyTime = timing.domContentLoadedEventEnd - timing.navigationStart;
}
} catch {
// Fall back to older API if Navigation Timing API Level 2 is not available
loadTime = timing.loadEventEnd - timing.navigationStart;
domReadyTime = timing.domContentLoadedEventEnd - timing.navigationStart;
}
// Get battery info
let batteryInfo;
@@ -405,9 +467,9 @@ export default function DebugTab() {
const memoryPercentage = totalMemory ? (usedMemory / totalMemory) * 100 : 0;
const systemInfo: SystemInfo = {
os: navigator.platform,
arch: navigator.userAgent.includes('x64') ? 'x64' : navigator.userAgent.includes('arm') ? 'arm' : 'unknown',
platform: navigator.platform,
os: detectedOS,
arch: detectedArch,
platform: navigator.platform || 'unknown',
cpus: navigator.hardwareConcurrency + ' cores',
memory: {
total: formatBytes(totalMemory),
@@ -423,7 +485,7 @@ export default function DebugTab() {
userAgent: navigator.userAgent,
cookiesEnabled: navigator.cookieEnabled,
online: navigator.onLine,
platform: navigator.platform,
platform: navigator.platform || 'unknown',
cores: navigator.hardwareConcurrency,
},
screen: {
@@ -445,8 +507,8 @@ export default function DebugTab() {
usagePercentage: memory.totalJSHeapSize ? (memory.usedJSHeapSize / memory.totalJSHeapSize) * 100 : 0,
},
timing: {
loadTime: timing.loadEventEnd - timing.navigationStart,
domReadyTime: timing.domContentLoadedEventEnd - timing.navigationStart,
loadTime,
domReadyTime,
readyStart: timing.fetchStart - timing.navigationStart,
redirectTime: timing.redirectEnd - timing.redirectStart,
appcacheTime: timing.domainLookupStart - timing.fetchStart,
@@ -483,6 +545,23 @@ export default function DebugTab() {
}
};
// Helper function to format bytes to human readable format with better precision
const formatBytes = (bytes: number) => {
if (bytes === 0) {
return '0 B';
}
const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
const i = Math.floor(Math.log(bytes) / Math.log(1024));
// Return with proper precision based on unit size
if (i === 0) {
return `${bytes} ${units[i]}`;
}
return `${(bytes / Math.pow(1024, i)).toFixed(2)} ${units[i]}`;
};
const getWebAppInfo = async () => {
try {
setLoading((prev) => ({ ...prev, webAppInfo: true }));
@@ -520,20 +599,6 @@ export default function DebugTab() {
}
};
// Helper function to format bytes to human readable format
const formatBytes = (bytes: number) => {
const units = ['B', 'KB', 'MB', 'GB'];
let size = bytes;
let unitIndex = 0;
while (size >= 1024 && unitIndex < units.length - 1) {
size /= 1024;
unitIndex++;
}
return `${Math.round(size)} ${units[unitIndex]}`;
};
const handleLogPerformance = () => {
try {
setLoading((prev) => ({ ...prev, performance: true }));
@@ -1353,9 +1418,7 @@ export default function DebugTab() {
</div>
<div className="text-xs text-bolt-elements-textSecondary mt-2 flex items-center gap-1.5">
<div className="i-ph:code w-3.5 h-3.5 text-purple-500" />
DOM Ready: {systemInfo
? (systemInfo.performance.timing.domReadyTime / 1000).toFixed(2)
: '-'}s
DOM Ready: {systemInfo ? (systemInfo.performance.timing.domReadyTime / 1000).toFixed(2) : '-'}s
</div>
</div>