137 lines
4.7 KiB
PHP
137 lines
4.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Filament\System\Widgets;
|
|
|
|
use App\Models\PlatformUser;
|
|
use App\Support\Auth\PlatformCapabilities;
|
|
use App\Support\Badges\BadgeDomain;
|
|
use App\Support\Badges\BadgeRenderer;
|
|
use App\Support\CustomerHealth\WorkspaceHealthSummaryQuery;
|
|
use App\Support\SystemConsole\SystemConsoleWindow;
|
|
use App\Support\System\SystemOperationRunLinks;
|
|
use Filament\Widgets\Widget;
|
|
|
|
class CustomerHealthTopWorkspaces extends Widget
|
|
{
|
|
protected static bool $isLazy = false;
|
|
|
|
protected int|string|array $columnSpan = 'full';
|
|
|
|
protected string $view = 'filament.system.widgets.customer-health-top-workspaces';
|
|
|
|
public ?string $window = null;
|
|
|
|
public static function canView(): bool
|
|
{
|
|
$user = auth('platform')->user();
|
|
|
|
if (! $user instanceof PlatformUser) {
|
|
return false;
|
|
}
|
|
|
|
if ($user->hasCapability(PlatformCapabilities::DIRECTORY_VIEW)) {
|
|
return true;
|
|
}
|
|
|
|
if (! static::canOpenRuns($user)) {
|
|
return false;
|
|
}
|
|
|
|
$window = SystemConsoleWindow::fromNullable((string) request()->query('window'));
|
|
|
|
return app(WorkspaceHealthSummaryQuery::class)
|
|
->attentionNeeded($window, 10)
|
|
->contains(fn (array $summary): bool => static::canAccessNextLink($summary['next_link'], $user));
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
protected function getViewData(): array
|
|
{
|
|
$window = SystemConsoleWindow::fromNullable($this->window ?? (string) request()->query('window'));
|
|
$windowLabel = SystemConsoleWindow::options()[$window->value] ?? 'Last 24 hours';
|
|
$user = auth('platform')->user();
|
|
|
|
return [
|
|
'windowLabel' => $windowLabel,
|
|
'rows' => app(WorkspaceHealthSummaryQuery::class)
|
|
->attentionNeeded($window, 10)
|
|
->filter(fn (array $summary): bool => $user instanceof PlatformUser && static::canAccessNextLink($summary['next_link'], $user))
|
|
->map(fn (array $summary): array => $this->presentSummary($summary)),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @param array{label: string, url: string} $nextLink
|
|
*/
|
|
private static function canAccessNextLink(array $nextLink, PlatformUser $user): bool
|
|
{
|
|
if ($user->hasCapability(PlatformCapabilities::DIRECTORY_VIEW)) {
|
|
return true;
|
|
}
|
|
|
|
return static::canOpenRuns($user)
|
|
&& $nextLink['url'] === SystemOperationRunLinks::index();
|
|
}
|
|
|
|
private static function canOpenRuns(PlatformUser $user): bool
|
|
{
|
|
return $user->hasCapability(PlatformCapabilities::OPERATIONS_VIEW)
|
|
|| ($user->hasCapability(PlatformCapabilities::OPS_VIEW) && $user->hasCapability(PlatformCapabilities::RUNBOOKS_VIEW));
|
|
}
|
|
|
|
/**
|
|
* @param array{
|
|
* workspace_id: int,
|
|
* workspace_name: string,
|
|
* overall_level: string,
|
|
* dimensions: array<string, array{label: string, level: string, windowed: bool}>,
|
|
* dominant_dimension_keys: list<string>,
|
|
* non_ok_dimension_count: int,
|
|
* next_link: array{label: string, url: string}
|
|
* } $summary
|
|
* @return array{
|
|
* workspace_id: int,
|
|
* workspace_label: string,
|
|
* overall: array{label: string, color: string, icon: ?string},
|
|
* dominant_copy: string,
|
|
* dominant_dimensions: list<array{label: string, color: string, icon: ?string}>,
|
|
* next_link: array{label: string, url: string}
|
|
* }
|
|
*/
|
|
private function presentSummary(array $summary): array
|
|
{
|
|
$dominantDimensions = collect($summary['dominant_dimension_keys'])
|
|
->take(2)
|
|
->map(function (string $dimensionKey) use ($summary): array {
|
|
$dimension = $summary['dimensions'][$dimensionKey];
|
|
$badge = BadgeRenderer::spec(BadgeDomain::SystemHealth, $dimension['level']);
|
|
|
|
return [
|
|
'label' => $dimension['label'],
|
|
'color' => $badge->color,
|
|
'icon' => $badge->icon,
|
|
];
|
|
})
|
|
->values()
|
|
->all();
|
|
|
|
$overallBadge = BadgeRenderer::spec(BadgeDomain::SystemHealth, $summary['overall_level']);
|
|
|
|
return [
|
|
'workspace_id' => $summary['workspace_id'],
|
|
'workspace_label' => $summary['workspace_name'],
|
|
'overall' => [
|
|
'label' => $overallBadge->label,
|
|
'color' => $overallBadge->color,
|
|
'icon' => $overallBadge->icon,
|
|
],
|
|
'dominant_copy' => implode(', ', array_column($dominantDimensions, 'label')),
|
|
'dominant_dimensions' => $dominantDimensions,
|
|
'next_link' => $summary['next_link'],
|
|
];
|
|
}
|
|
} |