TenantAtlas/app/Support/Ui/EnterpriseDetail/EnterpriseDetailSectionFactory.php
ahmido 20b6aa6a32 refactor: reduce operation run detail density (#194)
## 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
2026-03-26 13:23:52 +00:00

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,
);
}
}