* feat: Add LXC container control functionality to Installed Scripts page - Add reusable ConfirmationModal component with simple and type-to-confirm variants - Add three new tRPC endpoints for container control: - getContainerStatus: Check container running/stopped state via pct status - controlContainer: Start/stop containers via pct start/stop commands - destroyContainer: Destroy containers via pct destroy and delete DB records - Enhance InstalledScriptsTab with container status management and confirmation flows - Update ScriptInstallationCard with Start/Stop and Destroy buttons for SSH scripts - Add container control buttons to desktop table view with proper status handling - Update help documentation with comprehensive container control feature guide - Implement safety features: - Simple OK/Cancel confirmation for start/stop actions - Type-to-confirm modal requiring container ID for destroy actions - SSH connection validation and error handling - Loading states and user feedback for all operations - Only show control buttons for SSH scripts with valid container IDs - Maintain backward compatibility with existing delete functionality for non-SSH scripts All container control operations execute via SSH using existing infrastructure. Real-time container status checking and caching for optimal performance. * fix: Resolve linting errors in LXC control functionality - Remove unused getStatusMutation variable - Fix floating promises by adding void operator - Add missing dependencies to useEffect hooks - Fix unsafe argument types by casting server IDs to Number - Remove unused commandOutput variables - Use useCallback for fetchContainerStatus to fix dependency issues - Move function definition before usage to resolve hoisting errors * fix: Add missing execution_mode property to InstalledScript interface in ScriptInstallationCard - Add execution_mode: local | ssh property to InstalledScript interface - Fixes TypeScript build error when checking script.execution_mode === ssh - Ensures type consistency across all components * fix: Resolve status detection conflicts by using unified bulk fetching - Remove individual fetchContainerStatus function that was conflicting with bulk fetching - Update controlContainerMutation to use fetchContainerStatuses instead of individual calls - Remove unused utils variable to clean up linting warnings - Simplify status detection to use only the bulk getContainerStatuses endpoint - This should resolve the status detection issues by eliminating competing fetch mechanisms * fix: Stop infinite API call loops that were overwhelming the server - Remove fetchContainerStatuses from useEffect dependencies to prevent infinite loops - Use useRef to access current scripts without causing dependency cycles - Reduce multiple useEffect hooks that were all triggering status checks - This should stop the 30+ simultaneous API calls that were redlining the server - Status checks now happen only when needed: on load, after operations, and every 60s * feat: Implement efficient pct list approach for container status checking - Replace individual container status checks with bulk pct list per server - Update getContainerStatuses to run pct list once per server and parse all results - Simplify frontend to just pass server IDs instead of individual container data - Much more efficient: 1 SSH call per server instead of 1 call per container - Parse pct list output format: CTID Status Name - Map pct list status (running/stopped) to our status format - This should resolve the server overload issues while maintaining functionality * fix: Remove duplicate container status display from STATUS column - Remove container runtime status from STATUS column in both desktop and mobile views - Keep container status display next to container ID where it belongs - STATUS column now only shows installation status (SUCCESS/FAILED) - Container runtime status (running/stopped) remains next to container ID - Cleaner UI with no duplicate status information * feat: Trigger status check when switching to installed scripts tab - Add useEffect hook that triggers fetchContainerStatuses when component mounts - This ensures container statuses are refreshed every time user switches to the tab - Improves user experience by always showing current container states - Uses empty dependency array to run only once per tab switch * cleanup: Remove all console.log statements from codebase - Remove console.log statements from InstalledScriptsTab.tsx - Remove console.log statements from installedScripts.ts router - Remove console.log statements from VersionDisplay.tsx - Remove console.log statements from ScriptsGrid.tsx - Keep console.error statements for proper error logging - Cleaner production logs without debug output * feat: Display detailed SSH error messages for container operations - Capture both stdout and stderr from pct start/stop/destroy commands - Show actual SSH error output to users instead of generic error messages - Update controlContainer and destroyContainer to return detailed error messages - Improve frontend error handling to display backend error messages - Users now see specific error details like permission denied, container not found, etc. - Better debugging experience with meaningful error feedback * feat: Auto-stop containers before destroy and improve error UI - Automatically stop running containers before destroying them - Create custom ErrorModal component to replace ugly browser alerts - Support both error and success modal types with appropriate styling - Show detailed SSH error messages in a beautiful modal interface - Update destroy success message to indicate if container was stopped first - Better UX with consistent design language and proper error handling - Auto-close modals after 10 seconds for better user experience * fix: Replace dialog component with custom modal implementation - Remove dependency on non-existent dialog component - Use same modal pattern as ConfirmationModal for consistency - Custom modal with backdrop, proper styling, and responsive design - Maintains all functionality while fixing module resolution error - Consistent with existing codebase patterns * feat: Add instant success feedback for container start/stop operations - Show success modal immediately after start/stop operations - Update container status in UI instantly before background status check - Prevents user confusion by showing expected status change immediately - Add containerId to backend response for proper script identification - Success modals show appropriate messages for start vs stop operations - Background status check still runs to ensure accuracy - Better UX with instant visual feedback * fix: Improve Container Control section styling in help modal - Replace bright red styling with subtle accent colors - Use consistent design language that matches the rest of the interface - Change safety features from red to yellow warning styling - Better visual hierarchy and readability - Maintains warning importance while being less jarring * fix: Make safety features section much more subtle in help modal - Replace bright yellow with muted background colors - Use standard text colors (text-foreground, text-muted-foreground) - Maintains warning icon but with consistent styling - Much less jarring against dark theme - Better integration with overall design language * feat: Replace update script alerts with custom confirmation modal - Replace browser alert() with custom ErrorModal for validation errors - Replace browser confirm() with custom ConfirmationModal for update confirmation - Add type-to-confirm safety feature requiring container ID input - Include data loss warning and backup recommendation in confirmation message - Consistent UI/UX with other confirmation dialogs - Better error messaging with detailed information * fix: Resolve all build errors and warnings - Fix nullish coalescing operator warnings (|| to ??) - Remove unused imports and variables - Fix TypeScript type errors with proper casting - Update ConfirmationModal state type to include missing properties - Fix useEffect dependency warnings - All build errors resolved, only minor unused variable warning remains - Build now passes successfully * feat: Disable update button when container is stopped - Add disabled condition to update button in table view - Add disabled condition to update button in mobile card view - Prevents users from updating stopped containers - Uses containerStatus to determine if button should be disabled - Improves UX by preventing invalid operations on stopped containers * fix: Resolve infinite loop in status updates - Remove containerStatusMutation from fetchContainerStatuses dependencies - Use empty dependency array for fetchContainerStatuses useCallback - Remove fetchContainerStatuses from useEffect dependencies - Only depend on scripts.length to prevent infinite loops - Status updates now run only when scripts change, not on every render * fix: Correct misleading text in update confirmation modal - Change "will re-run the script installation process" to "will update the script" - More accurate description of what the update operation actually does - Maintains warning about potential container impact and backup recommendation - Better user understanding of the actual operation being performed * refactor: Remove all comments from InstalledScriptsTab.tsx - Remove all single-line comments (//) - Remove all multi-line comments (/* */) - Clean up excessive empty lines - Improve code readability and reduce file size - Maintain all functionality while removing documentation comments * refactor: Improve code organization and add comprehensive comments - Add clear section comments for better code organization - Document all major state variables and their purposes - Add detailed comments for complex logic and operations - Improve readability with better spacing and structure - Maintain all existing functionality while improving maintainability - Add comments for container control, mutations, and UI sections
88 lines
2.6 KiB
TypeScript
88 lines
2.6 KiB
TypeScript
'use client';
|
|
|
|
import { useEffect } from 'react';
|
|
import { Button } from './ui/button';
|
|
import { AlertCircle, CheckCircle } from 'lucide-react';
|
|
|
|
interface ErrorModalProps {
|
|
isOpen: boolean;
|
|
onClose: () => void;
|
|
title: string;
|
|
message: string;
|
|
details?: string;
|
|
type?: 'error' | 'success';
|
|
}
|
|
|
|
export function ErrorModal({
|
|
isOpen,
|
|
onClose,
|
|
title,
|
|
message,
|
|
details,
|
|
type = 'error'
|
|
}: ErrorModalProps) {
|
|
// Auto-close after 10 seconds
|
|
useEffect(() => {
|
|
if (isOpen) {
|
|
const timer = setTimeout(() => {
|
|
onClose();
|
|
}, 10000);
|
|
return () => clearTimeout(timer);
|
|
}
|
|
}, [isOpen, onClose]);
|
|
|
|
if (!isOpen) return null;
|
|
|
|
return (
|
|
<div className="fixed inset-0 backdrop-blur-sm bg-black/50 flex items-center justify-center z-50 p-4">
|
|
<div className="bg-card rounded-lg shadow-xl max-w-lg w-full border border-border">
|
|
{/* Header */}
|
|
<div className="flex items-center justify-center p-6 border-b border-border">
|
|
<div className="flex items-center gap-3">
|
|
{type === 'success' ? (
|
|
<CheckCircle className="h-8 w-8 text-green-600 dark:text-green-400" />
|
|
) : (
|
|
<AlertCircle className="h-8 w-8 text-red-600 dark:text-red-400" />
|
|
)}
|
|
<h2 className="text-xl font-semibold text-foreground">{title}</h2>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Content */}
|
|
<div className="p-6">
|
|
<p className="text-sm text-foreground mb-4">{message}</p>
|
|
{details && (
|
|
<div className={`rounded-lg p-3 ${
|
|
type === 'success'
|
|
? 'bg-green-50 dark:bg-green-950/20 border border-green-200 dark:border-green-800'
|
|
: 'bg-red-50 dark:bg-red-950/20 border border-red-200 dark:border-red-800'
|
|
}`}>
|
|
<p className={`text-xs font-medium mb-1 ${
|
|
type === 'success'
|
|
? 'text-green-800 dark:text-green-200'
|
|
: 'text-red-800 dark:text-red-200'
|
|
}`}>
|
|
{type === 'success' ? 'Details:' : 'Error Details:'}
|
|
</p>
|
|
<pre className={`text-xs whitespace-pre-wrap break-words ${
|
|
type === 'success'
|
|
? 'text-green-700 dark:text-green-300'
|
|
: 'text-red-700 dark:text-red-300'
|
|
}`}>
|
|
{details}
|
|
</pre>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{/* Footer */}
|
|
<div className="flex justify-end gap-3 p-6 border-t border-border">
|
|
<Button variant="outline" onClick={onClose}>
|
|
Close
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|