Various small fixes (#349)
* Fix script viewer to support vm/ and tools/ scripts - Update ScriptDetailModal to extract scriptName from any path (ct/, vm/, tools/) - Refactor TextViewer to use actual script paths from install_methods - Remove hardcoded path assumptions and use dynamic script paths - Only show Install Script tab for ct/ scripts that have install scripts - Rename CT Script tab to Script for better clarity * Fix downloaded scripts count to include vm/ and tools/ scripts - Update matching logic to use same robust approach as DownloadedScriptsTab - Add normalized slug matching to handle filename-based slugs vs JSON slugs - Add multiple fallback matching strategies for better script detection - Fixes issue where scripts in vm/ and tools/ directories weren't being counted * Filter categories to only show those with scripts - Add filter to exclude categories with count 0 from category sidebar - Only categories with at least one script will be displayed - Reduces UI clutter by hiding empty categories * Fix intermittent page reloads from VersionDisplay reconnect logic - Add guards to prevent reload when not updating - Use refs to track isUpdating and isNetworkError state in interval callbacks - Add hasReloadedRef flag to prevent multiple reloads - Clear reconnect interval when update completes or component unmounts - Only start reconnect attempts when actually updating - Prevents false positive reloads when server responds normally * Fix Next.js HMR WebSocket and static asset handling - Add WebSocket upgrade detection to only intercept /ws/script-execution - Pass all other WebSocket upgrades (including HMR) to Next.js handler - Ensure _next routes and static assets are properly handled by Next.js - Fixes 400 errors for Next.js HMR WebSocket connections - Fixes 403 errors for static assets by ensuring proper routing * Fix WebSocket upgrade handling to properly route Next.js HMR - Create WebSocketServer with noServer: true to avoid auto-attaching - Manually handle upgrade events to route /ws/script-execution to our WebSocketServer - Route all other WebSocket upgrades (including Next.js HMR) to Next.js handler - This ensures Next.js HMR WebSocket connections are properly handled - Fixes 400 errors for /_next/webpack-hmr WebSocket connections * Revert WebSocket handling to simpler approach - Go back to attaching WebSocketServer directly with path option - Remove manual upgrade event handling that was causing errors - The path option should filter to only /ws/script-execution - Next.js should handle its own HMR WebSocket upgrades naturally * Fix WebSocket upgrade handling to preserve Next.js HMR handlers - Save existing upgrade listeners before adding our own - Call existing listeners for non-matching paths to allow Next.js HMR - Only handle /ws/script-execution ourselves - This ensures Next.js can handle its own WebSocket upgrades for HMR * Fix random page reloads during normal app usage - Memoize startReconnectAttempts with useCallback to prevent recreation on every render - Fix useEffect dependency arrays to include memoized function - Add stricter guards checking refs before starting reconnect attempts - Ensure reconnect logic only runs when actually updating (not during normal usage) - Add early return in fallback useEffect to prevent false triggers - Add ref guards in ResyncButton to prevent multiple simultaneous sync operations - Only reload after sync if it was user-initiated * Fix critical bug: prevent reloads from stale updateLogsData.isComplete - Add isUpdating guard before processing updateLogsData.isComplete - Reset shouldSubscribe when update completes or fails - Prevent stale isComplete data from triggering reloads during normal usage * Add update confirmation modal with changelog display - Add UpdateConfirmationModal component that shows changelog before update - Modify getVersionStatus to include release body (changelog) in response - Update VersionDisplay to show confirmation modal instead of starting update directly - Users must review changelog and click 'Proceed with Update' to start update - Ensures users see potential breaking changes before updating
This commit is contained in:
committed by
GitHub
parent
2a9921a4e1
commit
66f8a84260
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { useState, useRef } from 'react';
|
||||
import { api } from '~/trpc/react';
|
||||
import { Button } from './ui/button';
|
||||
import { ContextualHelpIcon } from './ContextualHelpIcon';
|
||||
@@ -9,6 +9,8 @@ export function ResyncButton() {
|
||||
const [isResyncing, setIsResyncing] = useState(false);
|
||||
const [lastSync, setLastSync] = useState<Date | null>(null);
|
||||
const [syncMessage, setSyncMessage] = useState<string | null>(null);
|
||||
const hasReloadedRef = useRef<boolean>(false);
|
||||
const isUserInitiatedRef = useRef<boolean>(false);
|
||||
|
||||
const resyncMutation = api.scripts.resyncScripts.useMutation({
|
||||
onSuccess: (data) => {
|
||||
@@ -16,24 +18,38 @@ export function ResyncButton() {
|
||||
setLastSync(new Date());
|
||||
if (data.success) {
|
||||
setSyncMessage(data.message ?? 'Scripts synced successfully');
|
||||
// Reload the page after successful sync
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 2000); // Wait 2 seconds to show the success message
|
||||
// Only reload if this was triggered by user action
|
||||
if (isUserInitiatedRef.current && !hasReloadedRef.current) {
|
||||
hasReloadedRef.current = true;
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 2000); // Wait 2 seconds to show the success message
|
||||
} else {
|
||||
// Reset flag if reload didn't happen
|
||||
isUserInitiatedRef.current = false;
|
||||
}
|
||||
} else {
|
||||
setSyncMessage(data.error ?? 'Failed to sync scripts');
|
||||
// Clear message after 3 seconds for errors
|
||||
setTimeout(() => setSyncMessage(null), 3000);
|
||||
isUserInitiatedRef.current = false;
|
||||
}
|
||||
},
|
||||
onError: (error) => {
|
||||
setIsResyncing(false);
|
||||
setSyncMessage(`Error: ${error.message}`);
|
||||
setTimeout(() => setSyncMessage(null), 3000);
|
||||
isUserInitiatedRef.current = false;
|
||||
},
|
||||
});
|
||||
|
||||
const handleResync = async () => {
|
||||
// Prevent multiple simultaneous sync operations
|
||||
if (isResyncing) return;
|
||||
|
||||
// Mark as user-initiated before starting
|
||||
isUserInitiatedRef.current = true;
|
||||
hasReloadedRef.current = false;
|
||||
setIsResyncing(true);
|
||||
setSyncMessage(null);
|
||||
resyncMutation.mutate();
|
||||
|
||||
Reference in New Issue
Block a user