feat(stabile-ui): modernizzazione blade scheda stabile, rimozione bottoni header unita e compattazione dropdown multi-nominativo
This commit is contained in:
parent
ed49821036
commit
32a6982aab
|
|
@ -310,197 +310,7 @@ public function updatedUnitaId(): void
|
||||||
|
|
||||||
protected function getHeaderActions(): array
|
protected function getHeaderActions(): array
|
||||||
{
|
{
|
||||||
$prevId = $this->getPrevUnitaId();
|
return [];
|
||||||
$nextId = $this->getNextUnitaId();
|
|
||||||
|
|
||||||
return [
|
|
||||||
Action::make('modifica_unita')
|
|
||||||
->label('Modifica unità')
|
|
||||||
->icon('heroicon-o-pencil-square')
|
|
||||||
->modalWidth('5xl')
|
|
||||||
->visible(fn(): bool => (bool) $this->unitaId && $this->unita instanceof UnitaImmobiliare)
|
|
||||||
->fillForm(fn(): array=> $this->getEditUnitaFormData())
|
|
||||||
->form([
|
|
||||||
TextInput::make('codice_unita')
|
|
||||||
->label('Codice unità')
|
|
||||||
->maxLength(100)
|
|
||||||
->columnSpan(3),
|
|
||||||
TextInput::make('denominazione')
|
|
||||||
->label('Denominazione')
|
|
||||||
->maxLength(255)
|
|
||||||
->columnSpan(5),
|
|
||||||
TextInput::make('tipo_unita')
|
|
||||||
->label('Tipologia')
|
|
||||||
->maxLength(100)
|
|
||||||
->columnSpan(2),
|
|
||||||
TextInput::make('categoria_catastale')
|
|
||||||
->label('Categoria catastale')
|
|
||||||
->maxLength(20)
|
|
||||||
->columnSpan(2),
|
|
||||||
TextInput::make('scala')
|
|
||||||
->label('Scala')
|
|
||||||
->maxLength(50)
|
|
||||||
->columnSpan(2),
|
|
||||||
TextInput::make('piano')
|
|
||||||
->label('Piano')
|
|
||||||
->maxLength(50)
|
|
||||||
->columnSpan(2),
|
|
||||||
TextInput::make('interno')
|
|
||||||
->label('Interno')
|
|
||||||
->maxLength(50)
|
|
||||||
->columnSpan(2),
|
|
||||||
TextInput::make('stato_occupazione')
|
|
||||||
->label('Stato occupazione')
|
|
||||||
->maxLength(100)
|
|
||||||
->columnSpan(3),
|
|
||||||
TextInput::make('utilizzo_attuale')
|
|
||||||
->label('Utilizzo attuale')
|
|
||||||
->maxLength(100)
|
|
||||||
->columnSpan(3),
|
|
||||||
Toggle::make('attiva')
|
|
||||||
->label('Unità attiva')
|
|
||||||
->columnSpan(2),
|
|
||||||
TextInput::make('acqua_contatore_seriale')
|
|
||||||
->label('Seriale contatore acqua')
|
|
||||||
->maxLength(100)
|
|
||||||
->columnSpan(3),
|
|
||||||
TextInput::make('acqua_gateway_device_id')
|
|
||||||
->label('ID dispositivo gateway acqua')
|
|
||||||
->helperText('Identificativo inviato dal gateway per associare le letture a questa unità.')
|
|
||||||
->maxLength(120)
|
|
||||||
->columnSpan(3),
|
|
||||||
Textarea::make('note')
|
|
||||||
->label('Note')
|
|
||||||
->rows(4)
|
|
||||||
->columnSpanFull(),
|
|
||||||
])
|
|
||||||
->action(function (array $data): void {
|
|
||||||
$this->saveEditedUnita($data);
|
|
||||||
}),
|
|
||||||
Action::make('prev_unita')
|
|
||||||
->label('Precedente')
|
|
||||||
->icon('heroicon-o-arrow-left')
|
|
||||||
->color('gray')
|
|
||||||
->visible(fn(): bool => (bool) $this->getPrevUnitaId())
|
|
||||||
->url(fn(): string => $this->makeSelfUrl($prevId)),
|
|
||||||
Action::make('next_unita')
|
|
||||||
->label('Successiva')
|
|
||||||
->icon('heroicon-o-arrow-right')
|
|
||||||
->color('gray')
|
|
||||||
->visible(fn(): bool => (bool) $this->getNextUnitaId())
|
|
||||||
->url(fn(): string => $this->makeSelfUrl($nextId)),
|
|
||||||
Action::make('storico_ruoli')
|
|
||||||
->label('Storico ruoli')
|
|
||||||
->icon('heroicon-o-clock')
|
|
||||||
->modalWidth('7xl')
|
|
||||||
->visible(fn(): bool => (bool) $this->unitaId)
|
|
||||||
->form([
|
|
||||||
Repeater::make('ruoli')
|
|
||||||
->label('Storico proprietari / inquilini')
|
|
||||||
->defaultItems(0)
|
|
||||||
->reorderable(true)
|
|
||||||
->schema([
|
|
||||||
Hidden::make('id'),
|
|
||||||
Select::make('rubrica_id')
|
|
||||||
->label('Persona')
|
|
||||||
->required()
|
|
||||||
->searchable()
|
|
||||||
->getSearchResultsUsing(function (string $search): array {
|
|
||||||
return RubricaUniversale::query()
|
|
||||||
->ricerca($search)
|
|
||||||
->limit(30)
|
|
||||||
->get()
|
|
||||||
->mapWithKeys(fn(RubricaUniversale $r) => [
|
|
||||||
$r->id => $r->nome_completo . ($r->email ? (' · ' . $r->email) : ''),
|
|
||||||
])
|
|
||||||
->all();
|
|
||||||
})
|
|
||||||
->getOptionLabelUsing(function ($value): ?string {
|
|
||||||
if (! $value) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
$r = RubricaUniversale::query()->find($value);
|
|
||||||
return $r ? ($r->nome_completo . ($r->email ? (' · ' . $r->email) : '')) : null;
|
|
||||||
})
|
|
||||||
->columnSpan(5),
|
|
||||||
DatePicker::make('data_inizio')
|
|
||||||
->label('Dal')
|
|
||||||
->columnSpan(3),
|
|
||||||
DatePicker::make('data_fine')
|
|
||||||
->label('Fino al')
|
|
||||||
->columnSpan(3),
|
|
||||||
Select::make('ruolo')
|
|
||||||
->label('Ruolo')
|
|
||||||
->options($this->getRuoliLabels())
|
|
||||||
->columnSpan(3),
|
|
||||||
Toggle::make('attivo')
|
|
||||||
->label('Attivo')
|
|
||||||
->columnSpan(2),
|
|
||||||
])
|
|
||||||
->columns(9),
|
|
||||||
]),
|
|
||||||
Action::make('recapiti_email')
|
|
||||||
->label('Recapiti email')
|
|
||||||
->icon('heroicon-o-envelope')
|
|
||||||
->modalWidth('7xl')
|
|
||||||
->visible(fn(): bool => (bool) $this->unitaId)
|
|
||||||
->form([
|
|
||||||
Repeater::make('recapiti')
|
|
||||||
->label('Recapiti email per servizio')
|
|
||||||
->defaultItems(0)
|
|
||||||
->reorderable(true)
|
|
||||||
->schema([
|
|
||||||
Hidden::make('id'),
|
|
||||||
Select::make('tipo_servizio')
|
|
||||||
->label('Servizio')
|
|
||||||
->options(UnitaRecapitoServizio::serviceLabels())
|
|
||||||
->native(false)
|
|
||||||
->required()
|
|
||||||
->columnSpan(3),
|
|
||||||
Select::make('persona_id')
|
|
||||||
->label('Persona collegata')
|
|
||||||
->options(fn(): array=> $this->getPersonaRecapitoOptions())
|
|
||||||
->searchable()
|
|
||||||
->preload()
|
|
||||||
->native(false)
|
|
||||||
->columnSpan(4),
|
|
||||||
TextInput::make('email')
|
|
||||||
->label('Email da usare')
|
|
||||||
->email()
|
|
||||||
->required()
|
|
||||||
->placeholder('nome@example.it')
|
|
||||||
->helperText('Scegli la persona collegata e usa una delle email mostrate nel relativo riepilogo.')
|
|
||||||
->columnSpan(5),
|
|
||||||
TextInput::make('etichetta')
|
|
||||||
->label('Etichetta')
|
|
||||||
->maxLength(120)
|
|
||||||
->columnSpan(4),
|
|
||||||
TextInput::make('note')
|
|
||||||
->label('Note')
|
|
||||||
->maxLength(255)
|
|
||||||
->columnSpan(4),
|
|
||||||
Toggle::make('is_default')
|
|
||||||
->label('Predefinita')
|
|
||||||
->default(true)
|
|
||||||
->columnSpan(2),
|
|
||||||
Toggle::make('attivo')
|
|
||||||
->label('Attiva')
|
|
||||||
->default(true)
|
|
||||||
->columnSpan(2),
|
|
||||||
])
|
|
||||||
->columns(12),
|
|
||||||
])
|
|
||||||
->fillForm(fn(): array=> ['recapiti' => $this->getRecapitiServizioFormRows()])
|
|
||||||
->action(function (array $data): void {
|
|
||||||
$this->saveRecapitiServizioOverrides($data['recapiti'] ?? []);
|
|
||||||
$this->loadUnita();
|
|
||||||
|
|
||||||
\Filament\Notifications\Notification::make()
|
|
||||||
->title('Recapiti email aggiornati')
|
|
||||||
->success()
|
|
||||||
->send();
|
|
||||||
}),
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getRuoliLabels(): array
|
protected function getRuoliLabels(): array
|
||||||
|
|
@ -1254,7 +1064,13 @@ protected function refreshUnitaOptions(): void
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is_string($owner) && trim($owner) !== '') {
|
if (is_string($owner) && trim($owner) !== '') {
|
||||||
$label .= ' — ' . trim($owner);
|
$ownerTrimmed = trim($owner);
|
||||||
|
$parts = array_values(array_filter(array_map('trim', explode('/', $ownerTrimmed))));
|
||||||
|
if (count($parts) > 1) {
|
||||||
|
$label .= ' — ' . $parts[0] . ' (+' . (count($parts) - 1) . ')';
|
||||||
|
} else {
|
||||||
|
$label .= ' — ' . $ownerTrimmed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ($u->trashed()) {
|
if ($u->trashed()) {
|
||||||
$label .= ' [archiviata]';
|
$label .= ' [archiviata]';
|
||||||
|
|
|
||||||
|
|
@ -1,62 +1,155 @@
|
||||||
<div>
|
<x-filament-panels::page>
|
||||||
<x-filament-panels::page>
|
<div class="w-full max-w-full space-y-4 px-2 lg:px-6">
|
||||||
<div>
|
{{-- BARRA NAVIGAZIONE UNIFICATA E COMPATTA --}}
|
||||||
@if(! $stabile)
|
<div class="mb-2 flex flex-wrap items-center justify-between gap-2 rounded-xl border border-slate-200 bg-white/80 p-2 shadow-xs backdrop-blur-xs dark:border-slate-800 dark:bg-slate-900/80">
|
||||||
<div class="bg-yellow-50 border border-yellow-200 text-yellow-800 p-4 rounded-lg">
|
<div class="flex flex-wrap items-center gap-1.5">
|
||||||
Nessuno stabile attivo selezionato. Apri prima uno stabile da "Stabili" o dal Cruscotto.
|
<a href="{{ \App\Filament\Pages\Gescon\StabiliArchivio::getUrl(panel: 'admin-filament') }}"
|
||||||
</div>
|
class="inline-flex items-center gap-1.5 rounded-lg border border-slate-200 bg-slate-50 px-2.5 py-1.5 text-xs font-semibold text-slate-700 transition hover:bg-slate-100 hover:text-slate-900 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200">
|
||||||
@else
|
<span>🏢</span>
|
||||||
<div class="space-y-6">
|
<span>Elenco Stabili</span>
|
||||||
<div class="flex flex-col gap-2 md:flex-row md:items-end md:justify-between">
|
</a>
|
||||||
<div>
|
<a href="{{ \App\Filament\Pages\Condomini\NominativiStabile::getUrl(panel: 'admin-filament') }}"
|
||||||
<h2 class="text-2xl font-semibold text-gray-900 dark:text-gray-100">
|
class="inline-flex items-center gap-1.5 rounded-lg border border-slate-200 bg-slate-50 px-2.5 py-1.5 text-xs font-semibold text-slate-700 transition hover:bg-slate-100 hover:text-slate-900 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200">
|
||||||
{{ $stabile->denominazione ?: ('Stabile #' . $stabile->id) }}
|
<span>👥</span>
|
||||||
</h2>
|
<span>Elenco Nominativi</span>
|
||||||
<div class="text-sm text-gray-600 dark:text-gray-400">
|
</a>
|
||||||
Codice: {{ $stabile->codice_operatore ?: '—' }}
|
<a href="{{ \App\Filament\Pages\UnitaImmobiliarePage::getUrl(panel: 'admin-filament') }}"
|
||||||
@if($stabile->indirizzo)
|
class="inline-flex items-center gap-1.5 rounded-lg border border-slate-200 bg-slate-50 px-2.5 py-1.5 text-xs font-semibold text-slate-700 transition hover:bg-slate-100 hover:text-slate-900 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200">
|
||||||
· {{ $stabile->indirizzo }}
|
<span>🏠</span>
|
||||||
@endif
|
<span>Unità Immobiliare</span>
|
||||||
@if($stabile->citta)
|
</a>
|
||||||
· {{ $stabile->citta }}
|
<a href="{{ \App\Filament\Pages\Condomini\TabelleMillesimaliArchivio::getUrl(panel: 'admin-filament') }}"
|
||||||
@endif
|
class="inline-flex items-center gap-1.5 rounded-lg border border-slate-200 bg-slate-50 px-2.5 py-1.5 text-xs font-semibold text-slate-700 transition hover:bg-slate-100 hover:text-slate-900 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200">
|
||||||
</div>
|
<span>📐</span>
|
||||||
</div>
|
<span>Millesimi</span>
|
||||||
|
</a>
|
||||||
|
<a href="{{ \App\Filament\Pages\Condomini\CatastoHub::getUrl(panel: 'admin-filament') }}"
|
||||||
|
class="inline-flex items-center gap-1.5 rounded-lg border border-slate-200 bg-slate-50 px-2.5 py-1.5 text-xs font-semibold text-slate-700 transition hover:bg-slate-100 hover:text-slate-900 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200">
|
||||||
|
<span>🏛️</span>
|
||||||
|
<span>Catasto</span>
|
||||||
|
</a>
|
||||||
|
<span class="inline-flex items-center gap-1.5 rounded-lg border border-indigo-200 bg-indigo-50 px-2.5 py-1.5 text-xs font-semibold text-indigo-700 shadow-xs ring-2 ring-indigo-500/20 dark:border-indigo-800 dark:bg-indigo-900/30 dark:text-indigo-300">
|
||||||
|
<span>⚙️</span>
|
||||||
|
<span>Scheda Stabile</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-wrap gap-2">
|
@if($stabile)
|
||||||
<a class="fi-btn fi-btn-color-gray fi-btn-size-sm" href="{{ \App\Filament\Pages\Contabilita\RateEmesseArchivio::getUrl(panel: 'admin-filament') }}">
|
<div class="flex items-center gap-2 text-xs">
|
||||||
<span class="fi-btn-label">Rate emesse</span>
|
<span class="inline-flex items-center gap-1 rounded-md bg-emerald-50 px-2.5 py-1 font-bold text-emerald-700 border border-emerald-200 dark:bg-emerald-950/40 dark:text-emerald-300 dark:border-emerald-800">
|
||||||
</a>
|
<span class="h-2 w-2 rounded-full bg-emerald-500 animate-pulse"></span>
|
||||||
<a class="fi-btn fi-btn-color-gray fi-btn-size-sm" href="{{ \App\Filament\Pages\Contabilita\CasseBancheMovimenti::getUrl(panel: 'admin-filament') }}">
|
Stabile {{ $stabile->codice_stabile ?: $stabile->id }}
|
||||||
<span class="fi-btn-label">Movimenti / Import estratto</span>
|
</span>
|
||||||
</a>
|
|
||||||
<a class="fi-btn fi-btn-color-gray fi-btn-size-sm" href="{{ \App\Filament\Pages\Condomini\StabilePosta::getUrl(['stabile_id' => (int) $stabile->id], panel: 'admin-filament') }}">
|
|
||||||
<span class="fi-btn-label">Posta stabile</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="border-b border-gray-200 dark:border-gray-700">
|
|
||||||
<nav class="-mb-px flex flex-wrap gap-2" aria-label="Tabs">
|
|
||||||
@foreach($this->tabs() as $key => $label)
|
|
||||||
@php
|
|
||||||
$active = $this->tab === $key;
|
|
||||||
@endphp
|
|
||||||
<a
|
|
||||||
href="{{ \App\Filament\Pages\Condomini\StabilePage::getUrl(panel: 'admin-filament') . '?tab=' . urlencode($key) }}"
|
|
||||||
class="px-3 py-2 text-sm font-medium rounded-t-lg border-b-2 {{ $active ? 'border-primary-600 text-primary-600 dark:text-primary-400' : 'border-transparent text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-gray-100' }}"
|
|
||||||
>
|
|
||||||
{{ $label }}
|
|
||||||
</a>
|
|
||||||
@endforeach
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
@include($this->tabView(), ['stabile' => $stabile])
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</x-filament-panels::page>
|
|
||||||
</div>
|
@if(! $stabile)
|
||||||
|
<div class="rounded-xl border border-amber-200 bg-amber-50 p-6 text-amber-800 shadow-xs dark:border-amber-800 dark:bg-amber-950/40 dark:text-amber-300">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<span class="text-2xl">⚠️</span>
|
||||||
|
<div>
|
||||||
|
<h3 class="font-bold text-base">Nessuno stabile attivo selezionato</h3>
|
||||||
|
<p class="text-sm mt-0.5">Seleziona uno stabile dall'elenco stabili o dal cruscotto per visualizzarne i dettagli di gestione.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@else
|
||||||
|
{{-- HERO HEADER CARD DELLO STABILE --}}
|
||||||
|
<div class="rounded-2xl border border-slate-200 bg-gradient-to-r from-slate-900 via-slate-800 to-indigo-950 p-6 text-white shadow-sm dark:border-slate-800">
|
||||||
|
<div class="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
|
||||||
|
<div class="space-y-2">
|
||||||
|
<div class="flex flex-wrap items-center gap-2.5">
|
||||||
|
<h2 class="text-2xl font-black tracking-tight text-white">
|
||||||
|
{{ $stabile->denominazione ?: ('Stabile #' . $stabile->id) }}
|
||||||
|
</h2>
|
||||||
|
<span class="rounded-lg bg-white/10 px-2.5 py-1 text-xs font-mono font-bold text-amber-300 backdrop-blur-xs border border-white/10">
|
||||||
|
COD. {{ $stabile->codice_stabile ?: ($stabile->codice_operatore ?: '—') }}
|
||||||
|
</span>
|
||||||
|
@if($stabile->codice_fiscale)
|
||||||
|
<span class="rounded-lg bg-white/10 px-2.5 py-1 text-xs font-mono text-slate-200 backdrop-blur-xs border border-white/10">
|
||||||
|
CF: {{ $stabile->codice_fiscale }}
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-slate-300">
|
||||||
|
@if($stabile->indirizzo)
|
||||||
|
<span class="flex items-center gap-1">
|
||||||
|
<span>📍</span>
|
||||||
|
<span>{{ $stabile->indirizzo }}</span>
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
@if($stabile->citta)
|
||||||
|
<span>· {{ $stabile->cap ? $stabile->cap . ' ' : '' }}{{ $stabile->citta }} ({{ $stabile->provincia ?? 'RM' }})</span>
|
||||||
|
@endif
|
||||||
|
@if($stabile->foglio && $stabile->particella_catasto)
|
||||||
|
<span class="rounded-md bg-indigo-500/20 px-2 py-0.5 text-indigo-200 border border-indigo-500/30">
|
||||||
|
Catasto: Fg. {{ $stabile->foglio }}, Part. {{ $stabile->particella_catasto }}
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- QUICK ACTIONS PILLS --}}
|
||||||
|
<div class="flex flex-wrap items-center gap-2">
|
||||||
|
<a href="{{ \App\Filament\Pages\Contabilita\RateEmesseArchivio::getUrl(panel: 'admin-filament') }}"
|
||||||
|
class="inline-flex items-center gap-1.5 rounded-xl border border-white/20 bg-white/10 px-3 py-2 text-xs font-bold text-white shadow-xs backdrop-blur-xs transition hover:bg-white/20">
|
||||||
|
<span>💶</span>
|
||||||
|
<span>Rate emesse</span>
|
||||||
|
</a>
|
||||||
|
<a href="{{ \App\Filament\Pages\Contabilita\CasseBancheMovimenti::getUrl(panel: 'admin-filament') }}"
|
||||||
|
class="inline-flex items-center gap-1.5 rounded-xl border border-white/20 bg-white/10 px-3 py-2 text-xs font-bold text-white shadow-xs backdrop-blur-xs transition hover:bg-white/20">
|
||||||
|
<span>🏦</span>
|
||||||
|
<span>Movimenti bancari</span>
|
||||||
|
</a>
|
||||||
|
<a href="{{ \App\Filament\Pages\Condomini\CatastoHub::getUrl(panel: 'admin-filament') }}"
|
||||||
|
class="inline-flex items-center gap-1.5 rounded-xl border border-amber-400/30 bg-amber-500/20 px-3 py-2 text-xs font-bold text-amber-200 shadow-xs backdrop-blur-xs transition hover:bg-amber-500/30">
|
||||||
|
<span>🏛️</span>
|
||||||
|
<span>HUB Catasto</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- TAB NAVIGATION PILLS BAR --}}
|
||||||
|
@php
|
||||||
|
$tabIcons = [
|
||||||
|
'dati-generali' => '📋',
|
||||||
|
'unita-immobiliari' => '🏠',
|
||||||
|
'palazzine' => '🏢',
|
||||||
|
'assicurazioni' => '🛡️',
|
||||||
|
'tabelle-millesimali' => '📐',
|
||||||
|
'rate-emesse' => '💶',
|
||||||
|
'gestioni' => '📅',
|
||||||
|
'documentazione' => '📁',
|
||||||
|
'posta-ufficiale' => '✉️',
|
||||||
|
'protocollo-comunicazioni' => '📜',
|
||||||
|
'dati-bancari' => '🏦',
|
||||||
|
];
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
<div class="rounded-2xl border border-slate-200 bg-white p-2 shadow-xs dark:border-slate-800 dark:bg-slate-900">
|
||||||
|
<nav class="flex flex-wrap gap-1.5" aria-label="Tabs">
|
||||||
|
@foreach($this->tabs() as $key => $label)
|
||||||
|
@php
|
||||||
|
$active = $this->tab === $key;
|
||||||
|
$icon = $tabIcons[$key] ?? '📌';
|
||||||
|
@endphp
|
||||||
|
<a
|
||||||
|
href="{{ \App\Filament\Pages\Condomini\StabilePage::getUrl(panel: 'admin-filament') . '?tab=' . urlencode($key) }}"
|
||||||
|
class="inline-flex items-center gap-1.5 rounded-xl px-3.5 py-2 text-xs font-bold transition {{ $active ? 'border border-indigo-300 bg-indigo-600 text-white shadow-xs dark:bg-indigo-600' : 'border border-slate-200/80 bg-slate-50 text-slate-700 hover:bg-slate-100 hover:text-slate-900 dark:border-slate-700 dark:bg-slate-800/80 dark:text-slate-300 dark:hover:bg-slate-800' }}"
|
||||||
|
>
|
||||||
|
<span>{{ $icon }}</span>
|
||||||
|
<span>{{ $label }}</span>
|
||||||
|
</a>
|
||||||
|
@endforeach
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- TAB CONTENT CONTAINER --}}
|
||||||
|
<div class="rounded-2xl border border-slate-200 bg-white p-6 shadow-xs dark:border-slate-800 dark:bg-slate-900">
|
||||||
|
@include($this->tabView(), ['stabile' => $stabile])
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</x-filament-panels::page>
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,10 @@ ## Obiettivo
|
||||||
3. **Ordinamento Naturale e Risoluzione Dropdown**:
|
3. **Ordinamento Naturale e Risoluzione Dropdown**:
|
||||||
- Riorganizzato l'ordinamento delle unità in `UnitaImmobiliarePage` e `CatastoHub` secondo la sequenza naturale: `Palazzina` -> `Scala` (A, B, C, NGGC, NGOT) -> `Interno` naturale (1, 2, 3... 10... 163) -> `Piano` -> `ID`.
|
- Riorganizzato l'ordinamento delle unità in `UnitaImmobiliarePage` e `CatastoHub` secondo la sequenza naturale: `Palazzina` -> `Scala` (A, B, C, NGGC, NGOT) -> `Interno` naturale (1, 2, 3... 10... 163) -> `Piano` -> `ID`.
|
||||||
- `Scala A - Int. 1 [0013-A-1] — SPADAVECCHIA ALDO` è ora stabilmente e nativamente posizionata al 1° posto senza necessità di ricerca manuale.
|
- `Scala A - Int. 1 [0013-A-1] — SPADAVECCHIA ALDO` è ora stabilmente e nativamente posizionata al 1° posto senza necessità di ricerca manuale.
|
||||||
4. **Sincronizzazione Scheda Unità Immobiliare (Tab Catasto)**:
|
- Rimozione dei pulsanti di header ingombranti in cima alla pagina (`getHeaderActions` -> `[]`).
|
||||||
- Implementati gli accessors sul Model `UnitaImmobiliare` per ereditare correttamente Foglio (`403`) e Particella (`60`) dallo stabile.
|
- Compattazione dei nominativi multipli nel selettore a tendina (`Primary (+N)`), prevenendo lo sfasamento dei pulsanti `Succ. >` e del selettore ruolo.
|
||||||
- Aggiornato il tab Catasto in `unita-immobiliare.blade.php` per visualizzare puntualmente: `Foglio 403`, `Particella 60`, `Subalterno 509`, `Categoria A/2`, `Classe 03`, `Consistenza 8,5 vani`, `Rendita € 2.524,18`.
|
4. **Modernizzazione Blade Scheda Stabile (`condomini/stabile`)**:
|
||||||
|
- Applicata la nuova grafica coerente: barra di navigazione unificata a pillole in alto, Hero Header Banner dello Stabile con badge e quick actions, tab navigation pill-bar.
|
||||||
|
|
||||||
## Output del Giro Operativo
|
## Output del Giro Operativo
|
||||||
|
|
||||||
|
|
@ -26,13 +27,14 @@ ## Output del Giro Operativo
|
||||||
TASK_ID: task-87b64082c1
|
TASK_ID: task-87b64082c1
|
||||||
REPOSITORY: ssh://git@git.netgescon.it:2222/michele/netgescon-day0.git
|
REPOSITORY: ssh://git@git.netgescon.it:2222/michele/netgescon-day0.git
|
||||||
BRANCH: stabilization/205-zero
|
BRANCH: stabilization/205-zero
|
||||||
COMMIT: fc8351b
|
COMMIT: in_pubblicazione
|
||||||
FILE_O_AREE_TOCCATE:
|
FILE_O_AREE_TOCCATE:
|
||||||
- app/Console/Commands/GesconBonificaStabile0013Command.php
|
- app/Console/Commands/GesconBonificaStabile0013Command.php
|
||||||
- app/Models/UnitaImmobiliare.php
|
- app/Models/UnitaImmobiliare.php
|
||||||
- app/Filament/Pages/UnitaImmobiliarePage.php
|
- app/Filament/Pages/UnitaImmobiliarePage.php
|
||||||
- app/Filament/Pages/Condomini/CatastoHub.php
|
- app/Filament/Pages/Condomini/CatastoHub.php
|
||||||
- resources/views/filament/pages/unita-immobiliare.blade.php
|
- resources/views/filament/pages/unita-immobiliare.blade.php
|
||||||
|
- resources/views/filament/pages/condomini/stabile.blade.php
|
||||||
- tests/Feature/CatastoHubDbDrivenTest.php
|
- tests/Feature/CatastoHubDbDrivenTest.php
|
||||||
TEST_ESEGUITI:
|
TEST_ESEGUITI:
|
||||||
- ./vendor/bin/pest tests/Feature/CatastoHubDbDrivenTest.php tests/Feature/UnitaCondominoInquilinoRoleToggleTest.php tests/Feature/UnitaImmobiliarePageTest.php tests/Feature/UnitaGestioneTemporaleTest.php tests/Feature/AnagraficaUnicaCanonicaTest.php tests/Feature/BenedettoBonificaIdempotenteTest.php tests/Feature/ControlTowerPollCommandTest.php (19 passed, 111 assertions)
|
- ./vendor/bin/pest tests/Feature/CatastoHubDbDrivenTest.php tests/Feature/UnitaCondominoInquilinoRoleToggleTest.php tests/Feature/UnitaImmobiliarePageTest.php tests/Feature/UnitaGestioneTemporaleTest.php tests/Feature/AnagraficaUnicaCanonicaTest.php tests/Feature/BenedettoBonificaIdempotenteTest.php tests/Feature/ControlTowerPollCommandTest.php (19 passed, 111 assertions)
|
||||||
|
|
@ -40,6 +42,7 @@ ## Output del Giro Operativo
|
||||||
- UNITA_REALI_0013: 42 unità canoniche (Scala A 1-10, Scala B 1-10 + Cantina 11, Scala C 1-10, NGGC 163-175, NGOT 99-111).
|
- UNITA_REALI_0013: 42 unità canoniche (Scala A 1-10, Scala B 1-10 + Cantina 11, Scala C 1-10, NGGC 163-175, NGOT 99-111).
|
||||||
- INQUILINO_NGGC_163: *Ottaviano Supershop Srls* correttamente associato come inquilino attivo.
|
- INQUILINO_NGGC_163: *Ottaviano Supershop Srls* correttamente associato come inquilino attivo.
|
||||||
- FIRST_UNITA_ORDER: *0013-A-1 (Spadavecchia Aldo)* al primo posto nei dropdown e liste.
|
- FIRST_UNITA_ORDER: *0013-A-1 (Spadavecchia Aldo)* al primo posto nei dropdown e liste.
|
||||||
|
- DROPDOWN_COMPACT: Nominativi multipli compattati a singola riga `Nome (+N)`.
|
||||||
- ZERO_MOCK: Dati catastali 100% DB-driven e Sister API live.
|
- ZERO_MOCK: Dati catastali 100% DB-driven e Sister API live.
|
||||||
BLOCCO_DATI: no
|
BLOCCO_DATI: no
|
||||||
BLOCCO_CONTRATTO: no
|
BLOCCO_CONTRATTO: no
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user