## Summary - collapse secondary and diagnostic operation-run sections by default to reduce page density - visually emphasize the primary next step while keeping counts readable but secondary - keep failures and other actionable detail available without dominating the default reading path ## Testing - vendor/bin/sail artisan test --compact tests/Feature/Filament/OperationRunBaselineTruthSurfaceTest.php tests/Feature/Filament/OperationRunEnterpriseDetailPageTest.php tests/Feature/Filament/EnterpriseDetailTemplateRegressionTest.php tests/Feature/Operations/TenantlessOperationRunViewerTest.php - vendor/bin/sail bin pint --dirty --format agent Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #194
283 lines
8.8 KiB
PHP
283 lines
8.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Support\Ui\EnterpriseDetail;
|
|
|
|
final class EnterpriseDetailSectionFactory
|
|
{
|
|
/**
|
|
* @param array{label: string, color?: string, icon?: ?string, iconColor?: ?string}|null $badge
|
|
* @param 'default'|'danger'|'success'|'warning'|null $tone Optional color tone for the card border/value
|
|
* @param bool $mono Whether the value should be rendered in monospace font (e.g. hashes, IDs)
|
|
* @return array{label: string, value: string, hint?: ?string, badge?: ?array{label: string, color?: string, icon?: ?string, iconColor?: ?string}, tone?: string, mono?: bool}
|
|
*/
|
|
public function keyFact(string $label, mixed $value, ?string $hint = null, ?array $badge = null, ?string $tone = null, bool $mono = false): array
|
|
{
|
|
$displayValue = match (true) {
|
|
is_bool($value) => $value ? 'Yes' : 'No',
|
|
$value === null => '—',
|
|
is_scalar($value) => trim((string) $value) !== '' ? (string) $value : '—',
|
|
default => '—',
|
|
};
|
|
|
|
return array_filter([
|
|
'label' => $label,
|
|
'value' => $displayValue,
|
|
'hint' => $hint,
|
|
'badge' => $badge,
|
|
'tone' => $tone,
|
|
'mono' => $mono ?: null,
|
|
], static fn (mixed $item): bool => $item !== null);
|
|
}
|
|
|
|
/**
|
|
* @return array{label: string, color?: string, icon?: ?string, iconColor?: ?string}
|
|
*/
|
|
public function statusBadge(string $label, string $color = 'gray', ?string $icon = null, ?string $iconColor = null): array
|
|
{
|
|
return array_filter([
|
|
'label' => $label,
|
|
'color' => $color,
|
|
'icon' => $icon,
|
|
'iconColor' => $iconColor,
|
|
], static fn (mixed $item): bool => $item !== null);
|
|
}
|
|
|
|
/**
|
|
* @return array{title: string, description?: ?string, icon?: ?string}
|
|
*/
|
|
public function emptyState(string $title, ?string $description = null, ?string $icon = null): array
|
|
{
|
|
return array_filter([
|
|
'title' => $title,
|
|
'description' => $description,
|
|
'icon' => $icon,
|
|
], static fn (mixed $item): bool => $item !== null);
|
|
}
|
|
|
|
/**
|
|
* @param list<array<string, mixed>> $facts
|
|
* @param array{
|
|
* label?: string,
|
|
* text: string,
|
|
* source: string,
|
|
* secondaryGuidance?: list<array{label: string, text: string, source: string}>
|
|
* } $primaryNextStep
|
|
* @param array{
|
|
* summaryLine?: ?string,
|
|
* primaryFacts?: list<array<string, mixed>>,
|
|
* diagnosticFacts?: list<array<string, mixed>>
|
|
* }|null $compactCounts
|
|
* @return array{
|
|
* title: string,
|
|
* description?: ?string,
|
|
* facts: list<array<string, mixed>>,
|
|
* primaryNextStep: array{
|
|
* label?: string,
|
|
* text: string,
|
|
* source: string,
|
|
* secondaryGuidance?: list<array{label: string, text: string, source: string}>
|
|
* },
|
|
* compactCounts?: array{
|
|
* summaryLine?: ?string,
|
|
* primaryFacts?: list<array<string, mixed>>,
|
|
* diagnosticFacts?: list<array<string, mixed>>
|
|
* },
|
|
* attentionNote?: ?string
|
|
* }
|
|
*/
|
|
public function decisionZone(
|
|
array $facts,
|
|
array $primaryNextStep,
|
|
?string $description = null,
|
|
?array $compactCounts = null,
|
|
?string $attentionNote = null,
|
|
string $title = 'Decision',
|
|
): array {
|
|
return array_filter([
|
|
'title' => $title,
|
|
'description' => $description,
|
|
'facts' => array_values($facts),
|
|
'primaryNextStep' => $primaryNextStep,
|
|
'compactCounts' => $compactCounts,
|
|
'attentionNote' => $attentionNote,
|
|
], static fn (mixed $item): bool => $item !== null);
|
|
}
|
|
|
|
/**
|
|
* @param list<array{label: string, text: string, source: string}> $secondaryGuidance
|
|
* @return array{
|
|
* label: string,
|
|
* text: string,
|
|
* source: string,
|
|
* secondaryGuidance: list<array{label: string, text: string, source: string}>
|
|
* }
|
|
*/
|
|
public function primaryNextStep(string $text, string $source, array $secondaryGuidance = [], string $label = 'Primary next step'): array
|
|
{
|
|
return [
|
|
'label' => $label,
|
|
'text' => $text,
|
|
'source' => $source,
|
|
'secondaryGuidance' => array_values($secondaryGuidance),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @param list<array<string, mixed>> $primaryFacts
|
|
* @param list<array<string, mixed>> $diagnosticFacts
|
|
* @return array{
|
|
* summaryLine?: ?string,
|
|
* primaryFacts: list<array<string, mixed>>,
|
|
* diagnosticFacts: list<array<string, mixed>>
|
|
* }
|
|
*/
|
|
public function countPresentation(?string $summaryLine = null, array $primaryFacts = [], array $diagnosticFacts = []): array
|
|
{
|
|
return [
|
|
'summaryLine' => $summaryLine,
|
|
'primaryFacts' => array_values($primaryFacts),
|
|
'diagnosticFacts' => array_values($diagnosticFacts),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @param list<array<string, mixed>> $items
|
|
*/
|
|
public function factsSection(
|
|
string $id,
|
|
string $kind,
|
|
string $title,
|
|
array $items,
|
|
?array $emptyState = null,
|
|
?PageActionData $action = null,
|
|
?string $description = null,
|
|
bool $visible = true,
|
|
bool $collapsible = false,
|
|
bool $collapsed = false,
|
|
): DetailSectionData {
|
|
return new DetailSectionData(
|
|
id: $id,
|
|
kind: $kind,
|
|
title: $title,
|
|
items: $items,
|
|
emptyState: $emptyState,
|
|
action: $action,
|
|
visible: $visible,
|
|
description: $description,
|
|
collapsible: $collapsible,
|
|
collapsed: $collapsed,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $viewData
|
|
*/
|
|
public function viewSection(
|
|
string $id,
|
|
string $kind,
|
|
string $title,
|
|
string $view,
|
|
array $viewData = [],
|
|
?array $emptyState = null,
|
|
?PageActionData $action = null,
|
|
?string $description = null,
|
|
bool $visible = true,
|
|
bool $collapsible = false,
|
|
bool $collapsed = false,
|
|
): DetailSectionData {
|
|
return new DetailSectionData(
|
|
id: $id,
|
|
kind: $kind,
|
|
title: $title,
|
|
emptyState: $emptyState,
|
|
action: $action,
|
|
visible: $visible,
|
|
description: $description,
|
|
view: $view,
|
|
viewData: $viewData,
|
|
collapsible: $collapsible,
|
|
collapsed: $collapsed,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param list<array<string, mixed>> $items
|
|
*/
|
|
public function supportingFactsCard(
|
|
string $kind,
|
|
string $title,
|
|
array $items,
|
|
?PageActionData $action = null,
|
|
?string $description = null,
|
|
bool $visible = true,
|
|
?array $emptyState = null,
|
|
): SupportingCardData {
|
|
return new SupportingCardData(
|
|
kind: $kind,
|
|
title: $title,
|
|
items: $items,
|
|
visible: $visible,
|
|
action: $action,
|
|
description: $description,
|
|
emptyState: $emptyState,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $viewData
|
|
*/
|
|
public function supportingViewCard(
|
|
string $kind,
|
|
string $title,
|
|
string $view,
|
|
array $viewData = [],
|
|
?PageActionData $action = null,
|
|
?string $description = null,
|
|
bool $visible = true,
|
|
?array $emptyState = null,
|
|
): SupportingCardData {
|
|
return new SupportingCardData(
|
|
kind: $kind,
|
|
title: $title,
|
|
visible: $visible,
|
|
action: $action,
|
|
description: $description,
|
|
view: $view,
|
|
viewData: $viewData,
|
|
emptyState: $emptyState,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param list<array<string, mixed>> $entries
|
|
* @param array<string, mixed> $viewData
|
|
*/
|
|
public function technicalDetail(
|
|
string $title,
|
|
array $entries = [],
|
|
?string $description = null,
|
|
?string $view = null,
|
|
array $viewData = [],
|
|
?array $emptyState = null,
|
|
bool $visible = true,
|
|
bool $collapsible = true,
|
|
bool $collapsed = true,
|
|
string $variant = 'technical',
|
|
): TechnicalDetailData {
|
|
return new TechnicalDetailData(
|
|
title: $title,
|
|
entries: $entries,
|
|
collapsible: $collapsible,
|
|
collapsed: $collapsed,
|
|
visible: $visible,
|
|
description: $description,
|
|
view: $view,
|
|
viewData: $viewData,
|
|
emptyState: $emptyState,
|
|
variant: $variant,
|
|
);
|
|
}
|
|
}
|