{{-- La page Rapport — voir le docblock de `ReportBuilder` pour le raisonnement. Deux colonnes sur desktop, comme la page Élément : la composition à gauche, les réglages qui valent pour tout le rapport à droite, dans une carte collante. ► **Le piège de la grille**, déjà corrigé une fois sur la page Élément : une piste `1fr` déborde si son enfant direct n'a pas `min-w-0`. Les blocs contiennent des menus et des titres longs — sans ça, la carte de droite part hors de l'écran sur une fenêtre de 1 280 px. --}} @php $blocker = $this->blocker(); $scope = $this->scope(); @endphp @vite(['resources/js/report-blocks.js']) {{-- Deux onglets qui n'ont rien à voir : composer un rapport à la demande, régler des récapitulatifs récurrents — même patron que `WorkspaceSettings::$activeTab`. --}}
@foreach (['composer' => ['Composer', 'heroicon-o-document-chart-bar'], 'recaps' => ['Récapitulatifs', 'heroicon-o-envelope']] as $cle => [$libelle, $icone]) @endforeach
@if ($activeTab === 'recaps') @include('filament.app.pages.partials.report-recaps') @endif @if ($activeTab === 'composer')
{{-- ============================ Composition ============================ --}}
{{-- Périmètre. En tête, parce que c'est ce qui décide de tout le reste. Les deux menus sont là même quand la page arrive avec un périmètre : le bouton « Rapport » d'un projet n'est qu'un raccourci vers cet écran, et on doit pouvoir changer d'avis sans repartir d'ailleurs. --}}
Périmètre
Projet
@if ($this->selectableRoots()->isNotEmpty()) @endif
@if ($scope !== null)
@php($children = $this->selectableChildren()) @if ($children->isNotEmpty())
Éléments couverts @if ($this->selectedElementIds !== []) @endif
{{-- Les enfants directs seulement : ce qui se trouve sous un élément retenu est décidé par la profondeur, pas par une case. Une liste de 163 lignes ne serait pas utilisable. --}}
@foreach ($children as $child) @endforeach
{{ $this->selectedElementIds === [] ? 'Tous les éléments du premier niveau.' : count($this->selectedElementIds).' élément(s) sur '.$children->count().'.' }}
@endif {{ $this->scopeCount() }} élément(s) couvert(s) · {{ $this->reportRangeLabel() }} @else Un rapport couvre un projet, ou l'un de ses chantiers. Le bloc Portefeuille, lui, couvre tous les projets actifs. @endif
{{-- Les blocs. --}}
Contenu du rapport
@foreach ($this->blocks as $index => $raw) @php($block = $this->block($index)) @continue($block === null)
{{-- Poignée : seul point de saisie, sinon tout clic dans un menu amorcerait un glissement. --}}
{{-- La ligne de résumé : c'est elle qui permet de relire un rapport de six blocs sans ouvrir un seul menu. --}} {{-- Les réglages du bloc, propres à son type. --}}
@if ($block->type === \App\Services\Reporting\ReportBlockType::Planning) {{-- Ni « Rendu » ni « Échelle » : le premier découle du **format** (Gantt dessiné en PowerPoint, tableau daté en Word et Excel), la seconde de la **période** (`DateRange::suggestedScale()`). Une année à l'échelle du jour donnait 365 colonnes illisibles. --}}
Découpage
Affichage
@endif @if ($block->type === \App\Services\Reporting\ReportBlockType::Elements)
Rendu {{-- « Liste » retirée : elle n'apportait rien qu'un tableau sans en-tête. Le Kanban, lui, est une autre lecture des mêmes données — dessiné en PowerPoint, en tableau ailleurs. --}}
Découpage
Statuts {{-- « Tous » n'est pas l'absence de filtre déguisée : c'est le seul choix qui a du sens sous un Kanban, dont l'intérêt est justement de répartir les éléments entre les statuts. Sans lui, un Kanban « Terminés » n'aurait qu'une colonne remplie. --}}
@endif @if ($block->type->hasTypeFilter()) {{-- Vide = tous, même règle que la sélection d'éléments et les pages du Focus ; le dernier type coché ne se décoche pas. --}}
Types d'éléments
@php($selectedTypes = array_filter(array_keys($this->elementTypeFilters()), fn ($t) => $this->isBlockTypeSelected($index, $t))) @foreach ($this->elementTypeFilters() as $typeCode => $typeLabel) @php($isTypeSelected = $this->isBlockTypeSelected($index, $typeCode)) @endforeach
@endif @if ($block->type->needsTarget())
Focus sur
{{-- Les pages du tableau de bord, enregistrées avec la recette. Toutes cochées par défaut ; la dernière ne se décoche pas. --}}
Pages
@php($selectedPages = array_filter($this->focusPages($index), fn ($p) => $this->isFocusPageSelected($index, $p->value))) @foreach ($this->focusPages($index) as $page) @php($isSelected = $this->isFocusPageSelected($index, $page->value)) @endforeach
@endif @if ($block->type->hasPeriod())
Période @if ($block->period->needsDates()) De A @else

{{ ucfirst($this->blockRangeLabel($index)) }}

@endif
{{-- Le périmètre du bloc, sur le modèle de sa période : « Hérite du rapport » par défaut, une surcharge si on la demande. --}}
Profondeur
@if ($scope !== null && $this->selectableChildren()->isNotEmpty())
Sélection
@foreach ($this->selectableChildren() as $child) @endforeach @if ($block->elementIds !== []) @endif
@endif @endif
{{-- Motif déjà en place partout : la croix n'apparaît qu'au survol. --}}
@endforeach
{{-- Ajout d'un bloc. --}} Ajouter un bloc @foreach ($this->blockTypes() as $type) {{ $type->label() }} @endforeach
{{-- ============================= Carte méta ============================= --}}
@if ($this->configurations()->isNotEmpty()) Modèles @foreach ($this->configurations() as $configuration) {{ $configuration->name }} @endforeach @endif
{{-- L'horodatage est ajouté à la génération et non ici : un champ qui se réécrit pendant qu'on tape est pire que le doublon de noms qu'il évite. Le dire suffit. --}} La date et l'heure sont ajoutées au nom du document : _{{ now()->format('Ymd_Hi') }} @error('name') {{ $message }} @enderror
Format
@foreach ($this->formats() as $value => $label) @endforeach
@if ($this->defaultPeriod === \App\Services\Reporting\ReportPeriod::Custom->value)
@endif {{-- Les blocs qui héritent liront celle-ci : la montrer résolue évite d'avoir à générer le document pour savoir ce qu'elle vaut. --}} {{ $this->reportRangeLabel() }}
@if ($this->saveToDocuments)
Rattachement
@foreach ($this->attachableProjects()->whereIn('id', $this->attachProjectIds) as $project)
{{ $project->name }}
@endforeach @foreach ($this->attachableElements()->whereIn('id', $this->attachElementIds) as $element)
{{ $element->title }}
@endforeach

Sans rattachement, le rapport n'apparaît que dans vos documents.

@endif
@if ($blocker !== null)

{{ $blocker }}

@endif {{ $this->saveToDocuments ? 'Générer' : 'Générer et télécharger' }} Génération… @if ($this->lastDocument() !== null)
Dernier rapport {{ $this->lastDocument()->title }} {{ $this->lastDocument()->humanFileSize() }}
@endif
Enregistrer la modèle @if ($this->configurationId !== null) @endif
@endif