++ fix mobile
This commit is contained in:
15
HANDOFF.md
15
HANDOFF.md
@@ -147,6 +147,21 @@ assistente e operatore); creazione/modifica/cestino restano su `territori.manage
|
||||
sono sotto `@can('territori.manage')`; il link "Dettaglio" resta visibile a
|
||||
tutti. Il menu laterale mostra "Territori" a chi ha `territori.assign`.
|
||||
|
||||
### Assegnare un territorio ne azzera il flag "prioritario"
|
||||
|
||||
`prioritario` è un flag **manuale**; `is_prioritario` è true se il flag è acceso
|
||||
*oppure* se la giacenza supera la soglia — ma la parte a soglia vale solo per i
|
||||
territori *in reparto* (`scopePrioritari`/`getIsPrioritarioAttribute` filtrano su
|
||||
`inReparto`). Quindi un territorio assegnato può risultare prioritario **solo**
|
||||
per via del flag manuale. Regola: alla creazione di un'assegnazione **aperta** il
|
||||
flag viene spento. È implementata come evento `Assegnazione::created` (in
|
||||
`booted()`), guardato su `returned_at === null` e `prioritario === true`, così
|
||||
copre ogni via di creazione (pagina Assegna, CRUD del Registro, import XML) senza
|
||||
duplicare la logica. Interazione con l'import XML: per i backup creati dopo questa
|
||||
regola è un no-op (nessun territorio assegnato è prioritario); su backup vecchi
|
||||
con stato contraddittorio l'import normalizza il flag anziché riprodurlo tale e
|
||||
quale.
|
||||
|
||||
### Export/Import XML: backup completo e round-trip
|
||||
|
||||
`Livewire/Settings/XmlExchange` esporta e reimporta **tutti** i dati gestionali,
|
||||
|
||||
@@ -35,6 +35,26 @@ class Assegnazione extends Model
|
||||
];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
// Assegnare un territorio ne azzera il flag "prioritario": una volta in
|
||||
// carico a un proclamatore (assegnazione aperta) non ha più senso
|
||||
// segnalarlo come prioritario. La priorità automatica per soglia di
|
||||
// giacenza riguarda solo i territori in reparto, quindi resta il solo
|
||||
// flag manuale da spegnere. Vale per ogni via di creazione (pagina
|
||||
// Assegna, CRUD del Registro, import XML di assegnazioni aperte).
|
||||
static::created(function (self $assegnazione): void {
|
||||
if ($assegnazione->returned_at !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$territorio = $assegnazione->territorio;
|
||||
if ($territorio && $territorio->prioritario) {
|
||||
$territorio->update(['prioritario' => false]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ─── Relationships ─────────────────────────────────────────
|
||||
|
||||
public function territorio()
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
@error('descrizione') <p class="text-red-500 text-xs mt-1">{{ $message }}</p> @enderror
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label for="start_date" class="block text-sm font-medium text-gray-700">Data Inizio *</label>
|
||||
<input wire:model="start_date" type="date" id="start_date" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 text-sm" required>
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-sm text-right">
|
||||
<div class="flex items-center justify-end gap-1">
|
||||
<div class="flex flex-wrap items-center justify-end gap-1">
|
||||
<a href="{{ route('campagne.show', $campagna) }}" class="btn-action btn-action-indigo" title="Dettaglio">
|
||||
<svg class="h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"/></svg>
|
||||
</a>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="min-w-full divide-y divide-gray-200 table-striped">
|
||||
<thead style="background:linear-gradient(180deg,#f9fafb,#f3f4f6)">
|
||||
<tr>
|
||||
@@ -22,7 +23,7 @@
|
||||
<td class="px-4 py-3 text-sm font-semibold text-gray-900">{{ $proclamatore->nome_completo }}</td>
|
||||
<td class="px-4 py-3 text-sm text-gray-600">{{ $proclamatore->deleted_at->format('d/m/Y H:i') }}</td>
|
||||
<td class="px-4 py-3 text-sm text-right">
|
||||
<div class="flex items-center justify-end gap-1">
|
||||
<div class="flex flex-wrap items-center justify-end gap-1">
|
||||
<button wire:click="restore({{ $proclamatore->id }})" class="btn-action btn-action-green">Ripristina</button>
|
||||
<button wire:click="forceDelete({{ $proclamatore->id }})" wire:confirm="Eliminare DEFINITIVAMENTE questo proclamatore? Questa azione è irreversibile." class="btn-action btn-action-red">Elimina</button>
|
||||
</div>
|
||||
@@ -35,6 +36,7 @@
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="px-4 py-3 border-t border-gray-200">
|
||||
{{ $proclamatori->links() }}
|
||||
</div>
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
</td>
|
||||
<td class="px-4 py-3 text-sm text-gray-600">{{ $proclamatore->assegnazioni_aperte_count ?? $proclamatore->assegnazioni()->aperte()->count() }}</td>
|
||||
<td class="px-4 py-3 text-sm text-right">
|
||||
<div class="flex items-center justify-end gap-1">
|
||||
<div class="flex flex-wrap items-center justify-end gap-1">
|
||||
<a href="{{ route('proclamatori.show', $proclamatore) }}" class="btn-action btn-action-indigo" title="Dettaglio">
|
||||
<svg class="h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"/></svg>
|
||||
</a>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<div>
|
||||
<div class="mb-6 flex items-center justify-between">
|
||||
<div class="mb-6 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
|
||||
<h1 class="text-2xl font-bold text-gray-900">Registro Assegnazioni</h1>
|
||||
@can('settings.manage')
|
||||
<button wire:click="openCreate" class="btn-action btn-action-indigo" style="padding:8px 18px;font-size:14px;border-radius:8px">
|
||||
@@ -143,7 +143,7 @@
|
||||
{{ $editingId ? 'Modifica voce' : 'Nuova voce' }}
|
||||
</h2>
|
||||
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:14px;">
|
||||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:14px;">
|
||||
{{-- Territorio --}}
|
||||
<div style="grid-column:1/-1;">
|
||||
<label style="font-size:13px;font-weight:600;color:#374151;display:block;margin-bottom:4px;">Territorio *</label>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden max-w-lg">
|
||||
<ul class="divide-y divide-gray-200">
|
||||
@forelse($tipologie as $tipo)
|
||||
<li class="px-4 py-3 flex items-center justify-between hover:bg-gray-50">
|
||||
<li class="px-4 py-3 flex flex-wrap items-center justify-between gap-x-2 gap-y-1 hover:bg-gray-50">
|
||||
@if($editingId === $tipo->id)
|
||||
<form wire:submit="saveEdit" class="flex items-center gap-2 flex-1">
|
||||
<input wire:model="editingNome" type="text" class="flex-1 rounded-lg border-gray-300 text-sm focus:ring-indigo-500 focus:border-indigo-500">
|
||||
@@ -34,7 +34,7 @@
|
||||
@endif
|
||||
<span class="text-xs text-gray-400">{{ $tipo->territori()->count() }} territori</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<button wire:click="startEdit({{ $tipo->id }})" class="text-yellow-600 hover:text-yellow-800 text-xs">Rinomina</button>
|
||||
<button wire:click="toggleActive({{ $tipo->id }})" class="text-xs {{ $tipo->attivo ? 'text-gray-500' : 'text-green-600' }}">{{ $tipo->attivo ? 'Disattiva' : 'Attiva' }}</button>
|
||||
<button wire:click="deleteTipologia({{ $tipo->id }})" wire:confirm="Eliminare la tipologia '{{ $tipo->nome }}'?" class="text-red-500 hover:text-red-700 text-xs">Elimina</button>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden max-w-lg">
|
||||
<ul class="divide-y divide-gray-200">
|
||||
@forelse($zone as $zona)
|
||||
<li class="px-4 py-3 flex items-center justify-between hover:bg-gray-50">
|
||||
<li class="px-4 py-3 flex flex-wrap items-center justify-between gap-x-2 gap-y-1 hover:bg-gray-50">
|
||||
@if($editingId === $zona->id)
|
||||
<form wire:submit="saveEdit" class="flex items-center gap-2 flex-1">
|
||||
<input wire:model="editingNome" type="text" class="flex-1 rounded-lg border-gray-300 text-sm focus:ring-indigo-500 focus:border-indigo-500">
|
||||
@@ -34,7 +34,7 @@
|
||||
@endif
|
||||
<span class="text-xs text-gray-400">{{ $zona->territori()->count() }} territori</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<button wire:click="startEdit({{ $zona->id }})" class="text-yellow-600 hover:text-yellow-800 text-xs">Rinomina</button>
|
||||
<button wire:click="toggleActive({{ $zona->id }})" class="text-xs {{ $zona->attivo ? 'text-gray-500' : 'text-green-600' }}">{{ $zona->attivo ? 'Disattiva' : 'Attiva' }}</button>
|
||||
<button wire:click="deleteZona({{ $zona->id }})" wire:confirm="Eliminare la zona '{{ $zona->nome }}'?" class="text-red-500 hover:text-red-700 text-xs">Elimina</button>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="min-w-full divide-y divide-gray-200 table-striped">
|
||||
<thead style="background:linear-gradient(180deg,#f9fafb,#f3f4f6)">
|
||||
<tr>
|
||||
@@ -22,7 +23,7 @@
|
||||
<td class="px-4 py-3 text-sm font-semibold text-gray-900">{{ $territorio->numero }}</td>
|
||||
<td class="px-4 py-3 text-sm text-gray-600">{{ $territorio->deleted_at->format('d/m/Y H:i') }}</td>
|
||||
<td class="px-4 py-3 text-sm text-right">
|
||||
<div class="flex items-center justify-end gap-1">
|
||||
<div class="flex flex-wrap items-center justify-end gap-1">
|
||||
<button wire:click="restore({{ $territorio->id }})" class="btn-action btn-action-green">Ripristina</button>
|
||||
<button wire:click="forceDelete({{ $territorio->id }})" wire:confirm="Eliminare DEFINITIVAMENTE il territorio {{ $territorio->numero }}? Questa azione è irreversibile." class="btn-action btn-action-red">Elimina</button>
|
||||
</div>
|
||||
@@ -35,6 +36,7 @@
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="px-4 py-3 border-t border-gray-200">
|
||||
{{ $territori->links() }}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user