Use Dokploy projects in dashboard widget
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled

This commit is contained in:
Codex Agent
2026-01-29 10:40:10 +01:00
parent b8bb7926c0
commit 78af7838bf
5 changed files with 581 additions and 50 deletions

View File

@@ -5,87 +5,263 @@
$statusColors = [
'done' => 'success',
'healthy' => 'success',
'running' => 'success',
'deploying' => 'warning',
'pending' => 'warning',
'starting' => 'warning',
'warning' => 'warning',
'unreachable' => 'danger',
'error' => 'danger',
'failed' => 'danger',
'unhealthy' => 'danger',
];
$statusIcons = [
'done' => Heroicon::CheckCircle,
'healthy' => Heroicon::CheckCircle,
'running' => Heroicon::CheckCircle,
'deploying' => Heroicon::ArrowPath,
'pending' => Heroicon::Clock,
'starting' => Heroicon::Clock,
'warning' => Heroicon::ExclamationTriangle,
'unreachable' => Heroicon::ExclamationTriangle,
'error' => Heroicon::XCircle,
'failed' => Heroicon::XCircle,
'unhealthy' => Heroicon::XCircle,
];
$serviceColors = [
'running' => 'success',
'done' => 'success',
'healthy' => 'success',
'starting' => 'warning',
'deploying' => 'warning',
'pending' => 'warning',
'unhealthy' => 'danger',
'error' => 'danger',
'failed' => 'danger',
];
$cardsGrid = (new ComponentAttributeBag())->grid(['default' => 1, 'lg' => 2]);
$stacked = (new ComponentAttributeBag())->grid(['default' => 1], GridDirection::Column);
$detailsGrid = (new ComponentAttributeBag())->grid(['default' => 1, 'md' => 2], GridDirection::Column);
$serviceGrid = (new ComponentAttributeBag())->grid(['default' => 1], GridDirection::Column);
@endphp
<x-filament-widgets::widget>
<x-filament::section heading="Infra Status (Dokploy)">
<div {{ $cardsGrid }}>
@forelse($composes as $compose)
<x-filament::card
:heading="$compose['label']"
:description="$compose['name'] ?? ''"
>
<x-slot name="afterHeader">
<x-filament::badge
:color="$statusColors[$compose['status']] ?? 'gray'"
:icon="$statusIcons[$compose['status']] ?? Heroicon::QuestionMarkCircle"
>
{{ ucfirst($compose['status']) }}
</x-filament::badge>
<x-filament::badge color="gray" :icon="Heroicon::Identification">
{{ $compose['compose_id'] }}
</x-filament::badge>
</x-slot>
@if(isset($compose['error']))
<x-filament::badge color="danger" :icon="Heroicon::ExclamationTriangle">
{{ $compose['error'] }}
</x-filament::badge>
@else
<div {{ $serviceGrid }}>
@forelse($compose['services'] as $service)
<x-filament::badge
:color="$serviceColors[$service['status']] ?? 'gray'"
:icon="array_key_exists($service['status'] ?? '', $serviceColors) ? Heroicon::Server : Heroicon::QuestionMarkCircle"
>
{{ $service['name'] }}: {{ strtoupper($service['status'] ?? 'N/A') }}
</x-filament::badge>
@empty
<x-filament::badge color="gray" :icon="Heroicon::QuestionMarkCircle">
No services reported.
</x-filament::badge>
@endforelse
<x-filament::badge color="gray" :icon="Heroicon::Clock">
Last deploy:
{{ $compose['last_deploy'] ? \Illuminate\Support\Carbon::parse($compose['last_deploy'])->diffForHumans() : '—' }}
@if(!empty($projects))
<div {{ $cardsGrid }}>
@forelse($projects as $project)
<x-filament::card :heading="$project['label']" :description="$project['name'] ?? ''">
<x-slot name="afterHeader">
<x-filament::badge
:color="$statusColors[$project['status']] ?? 'gray'"
:icon="$statusIcons[$project['status']] ?? Heroicon::QuestionMarkCircle"
>
{{ ucfirst($project['status']) }}
</x-filament::badge>
<x-filament::badge color="gray" :icon="Heroicon::Identification">
{{ $project['project_id'] }}
</x-filament::badge>
</x-slot>
<div {{ $stacked }}>
@if(isset($project['error']))
<x-filament::badge color="danger" :icon="Heroicon::ExclamationTriangle">
{{ $project['error'] }}
</x-filament::badge>
@else
@if(!empty($project['description']))
<x-filament::badge color="gray" :icon="Heroicon::InformationCircle">
{{ $project['description'] }}
</x-filament::badge>
@endif
<div {{ $detailsGrid }}>
<x-filament::badge color="gray" :icon="Heroicon::RectangleStack">
Apps: {{ $project['applications_count'] ?? 0 }}
</x-filament::badge>
<x-filament::badge color="gray" :icon="Heroicon::ServerStack">
Services: {{ $project['services_count'] ?? 0 }}
</x-filament::badge>
<x-filament::badge color="gray" :icon="Heroicon::Clock">
Last update:
{{ $project['updated_at'] ? \Illuminate\Support\Carbon::parse($project['updated_at'])->diffForHumans() : '—' }}
</x-filament::badge>
</div>
<div {{ $stacked }}>
<x-filament::badge color="gray" :icon="Heroicon::RectangleStack">
Applications
</x-filament::badge>
@forelse($project['applications'] as $application)
<div {{ $stacked }}>
<x-filament::badge
:color="$statusColors[$application['status']] ?? 'gray'"
:icon="$statusIcons[$application['status']] ?? Heroicon::QuestionMarkCircle"
>
{{ $application['name'] ?? 'App' }}
@if(!empty($application['status']))
({{ strtoupper($application['status']) }})
@endif
</x-filament::badge>
<div {{ $detailsGrid }}>
@if(!empty($application['id']))
<x-filament::badge color="gray" :icon="Heroicon::Identification">
{{ $application['id'] }}
</x-filament::badge>
@endif
@if(!empty($application['repository']))
<x-filament::badge color="gray" :icon="Heroicon::CodeBracket">
{{ $application['repository'] }}
</x-filament::badge>
@endif
@if(!empty($application['branch']))
<x-filament::badge color="gray" :icon="Heroicon::ChevronDown">
{{ $application['branch'] }}
</x-filament::badge>
@endif
@if(!empty($application['server']))
<x-filament::badge color="gray" :icon="Heroicon::Server">
{{ $application['server'] }}
</x-filament::badge>
@endif
@if(!empty($application['url']))
<x-filament::badge color="gray" :icon="Heroicon::GlobeAlt">
{{ $application['url'] }}
</x-filament::badge>
@endif
<x-filament::badge color="gray" :icon="Heroicon::Clock">
Last deploy:
{{ $application['last_deploy'] ? \Illuminate\Support\Carbon::parse($application['last_deploy'])->diffForHumans() : '—' }}
</x-filament::badge>
</div>
@if(!empty($application['monitoring']))
<div {{ $detailsGrid }}>
@foreach($application['monitoring'] as $metric)
<x-filament::badge color="gray" :icon="Heroicon::ChartBar">
{{ $metric['label'] }}: {{ $metric['value'] }}
</x-filament::badge>
@endforeach
</div>
@endif
</div>
@empty
<x-filament::badge color="gray" :icon="Heroicon::QuestionMarkCircle">
No applications reported.
</x-filament::badge>
@endforelse
</div>
<div {{ $stacked }}>
<x-filament::badge color="gray" :icon="Heroicon::ServerStack">
Services
</x-filament::badge>
<div {{ $serviceGrid }}>
@forelse($project['services'] as $service)
<x-filament::badge
:color="$serviceColors[$service['status']] ?? 'gray'"
:icon="Heroicon::Server"
>
{{ strtoupper($service['type'] ?? 'service') }}
@if(!empty($service['name']))
- {{ $service['name'] }}
@endif
@if(!empty($service['status']))
({{ strtoupper($service['status']) }})
@endif
</x-filament::badge>
<div {{ $detailsGrid }}>
@if(!empty($service['id']))
<x-filament::badge color="gray" :icon="Heroicon::Identification">
{{ $service['id'] }}
</x-filament::badge>
@endif
@if(!empty($service['version']))
<x-filament::badge color="gray" :icon="Heroicon::Cube">
{{ $service['version'] }}
</x-filament::badge>
@endif
@if(!empty($service['external_port']))
<x-filament::badge color="gray" :icon="Heroicon::Signal">
Port {{ $service['external_port'] }}
</x-filament::badge>
@endif
</div>
@empty
<x-filament::badge color="gray" :icon="Heroicon::QuestionMarkCircle">
No services reported.
</x-filament::badge>
@endforelse
</div>
</div>
@endif
</div>
@endif
</x-filament::card>
@empty
<x-filament::empty-state
heading="No Dokploy compose stacks configured."
:icon="Heroicon::QuestionMarkCircle"
/>
@endforelse
</div>
</x-filament::card>
@empty
<x-filament::empty-state
heading="No Dokploy projects configured."
:icon="Heroicon::QuestionMarkCircle"
/>
@endforelse
</div>
@else
<div {{ $cardsGrid }}>
@forelse($composes as $compose)
<x-filament::card
:heading="$compose['label']"
:description="$compose['name'] ?? ''"
>
<x-slot name="afterHeader">
<x-filament::badge
:color="$statusColors[$compose['status']] ?? 'gray'"
:icon="$statusIcons[$compose['status']] ?? Heroicon::QuestionMarkCircle"
>
{{ ucfirst($compose['status']) }}
</x-filament::badge>
<x-filament::badge color="gray" :icon="Heroicon::Identification">
{{ $compose['compose_id'] }}
</x-filament::badge>
</x-slot>
@if(isset($compose['error']))
<x-filament::badge color="danger" :icon="Heroicon::ExclamationTriangle">
{{ $compose['error'] }}
</x-filament::badge>
@else
<div {{ $serviceGrid }}>
@forelse($compose['services'] as $service)
<x-filament::badge
:color="$serviceColors[$service['status']] ?? 'gray'"
:icon="array_key_exists($service['status'] ?? '', $serviceColors) ? Heroicon::Server : Heroicon::QuestionMarkCircle"
>
{{ $service['name'] }}: {{ strtoupper($service['status'] ?? 'N/A') }}
</x-filament::badge>
@empty
<x-filament::badge color="gray" :icon="Heroicon::QuestionMarkCircle">
No services reported.
</x-filament::badge>
@endforelse
<x-filament::badge color="gray" :icon="Heroicon::Clock">
Last deploy:
{{ $compose['last_deploy'] ? \Illuminate\Support\Carbon::parse($compose['last_deploy'])->diffForHumans() : '—' }}
</x-filament::badge>
</div>
@endif
</x-filament::card>
@empty
<x-filament::empty-state
heading="No Dokploy compose stacks configured."
:icon="Heroicon::QuestionMarkCircle"
/>
@endforelse
</div>
@endif
</x-filament::section>
</x-filament-widgets::widget>