- Create S3DownloadFinished event to cleanup MinIO containers
- Create S3RestoreJobFinished event to cleanup temp files and S3 downloads
- Add formatBytes() helper function for human-readable file sizes
- Update Import component to use full Event class names in callEventOnFinish
- Fix activity monitor visibility issues with proper event dispatching
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The formatBytes function was used in the view but never defined, causing
a runtime error. This function was needed to display S3 file sizes in
human-readable format (e.g., "1.5 MB" instead of "1572864").
Added formatBytes() helper to bootstrap/helpers/shared.php:
- Converts bytes to human-readable format (B, KB, MB, GB, TB, PB)
- Uses base 1024 for proper binary conversion
- Configurable precision (defaults to 2 decimal places)
- Handles zero bytes case
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add debugging to understand why the download message stays visible after completion.
This will help us see if:
1. The event is being dispatched by ActivityMonitor
2. The event is being received by Import component
3. The property is being set to false
4. The entangle is syncing to Alpine properly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Root cause analysis:
- Changed from dispatch to property binding broke the activity monitor completely
- ActivityMonitor component expects activityMonitor event, not property binding
- Original approach was correct: use dispatch + event listeners
Solution:
- Revert to original dispatch('activityMonitor', $activity->id) calls
- Use @if conditionals to render only one monitor at a time (removes from DOM)
- Add unique wire:key to each monitor instance to prevent conflicts
- S3 download monitor: wire:key="s3-download-{{ $resource->uuid }}"
- Database restore monitor: wire:key="database-restore-{{ $resource->uuid }}"
This ensures:
- Activity monitors display correctly when processes start
- Only one monitor is rendered at a time (S3 download OR database restore)
- Each monitor has unique identity via wire:key
- Event listeners work as designed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add updatedActivityId method to watch for changes to activityId property
- When activityId is set/updated, automatically hydrate the activity and enable polling
- This allows the activity monitor to display content when activityId is bound from parent component
- Fixes issue where activity monitor was empty because activity wasn't loaded
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add S3DownloadFinished event listener to Import component
- Add handleS3DownloadFinished method to set s3DownloadInProgress to false
- This ensures the 'Downloading from S3...' message is hidden when download completes
- The success message now properly displays after download finishes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add currentActivityId property to track the active process
- Replace event dispatching with property assignment for cleaner state management
- S3 download monitor only renders during download and is removed when complete
- Database restore monitor only renders during restore operation
- Both monitors now share the same activity-monitor component instance with proper lifecycle management
- When user starts restore after S3 download, S3 monitor is removed from DOM
- Fixes issue where S3 download and database restore showed identical output
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add unique wire keys to activity-monitor components (s3-download-monitor and database-restore-monitor)
- Update dispatch calls to target specific components using ->to() method
- This prevents both activity monitors from listening to the same activityMonitor event and displaying identical output
- S3 download now shows in s3-download-monitor component
- Database restore now shows in database-restore-monitor component
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add Alpine.js entangle bindings for s3StorageId and s3Path to enable
reactive button state without server requests
- Change button disabled binding from PHP :disabled to Alpine x-bind:disabled
for client-side reactivity using deferred wire:model inputs
- Replace S3Storage::findOrFail with ownedByCurrentTeam()->findOrFail in
checkS3File() and downloadFromS3() methods
- Remove redundant manual team verification since ownedByCurrentTeam scope
automatically filters to current team
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit introduces functionality for integrating S3 storage into the import process. It allows users to select S3 storage, check for file existence, and download files directly from S3. This enhancement improves the flexibility of the import feature by enabling users to work with files stored in S3, addressing a common use case for teams that utilize cloud storage solutions.
Removed duplicate queue_application_deployment() call in Heading.php deploy method that was causing "Deployment already queued for this commit" error to display even though deployment was successfully queued.
Also changed notification type from 'success' to 'error' when deployment is actually skipped for proper user feedback.
Add detection system for PORT environment variable to help users configure applications correctly:
- Add detectPortFromEnvironment() method to Application model to detect PORT env var
- Add getDetectedPortInfoProperty() computed property in General Livewire component
- Display contextual info banners in UI when PORT is detected:
- Warning when PORT exists but ports_exposes is empty
- Warning when PORT doesn't match ports_exposes configuration
- Info message when PORT matches ports_exposes
- Add deployment logging to warn about PORT/ports_exposes mismatches
- Include comprehensive unit tests for port detection logic
The ports_exposes field remains authoritative for proxy configuration, while
PORT detection provides helpful suggestions to users.
Track container restart counts from Docker and detect crash loops to provide better visibility into application health issues.
- Add restart_count, last_restart_at, and last_restart_type columns to applications table
- Detect restart count increases from Docker inspect data and send notifications
- Show restart count badge in UI with warning icon on Logs navigation
- Distinguish between crash restarts and manual restarts
- Implement 30-second grace period to prevent false "exited" status during crash loops
- Reset restart count on manual stop, restart, and redeploy actions
- Add unit tests for restart count tracking logic
This helps users quickly identify when containers are in crash loops and need attention, even when the container status flickers between states during Docker's restart backoff period.