++ scelta di territori e proclamatori con ricerca

Al posto delle tendine (Assegna, Registro, editor delle piantine) un
campo in cui si scrive e compaiono le proposte più vicine: uguale, inizia
con, contiene, errore di battitura ("forse cercavi"); parole in qualsiasi
ordine, senza badare a maiuscole e accenti. Campo vuoto: la tendina
completa. Fatto anche per il telefono (16px, voci da 44px, scelta al tocco).

- Logica pura in resources/js/scelta.js con test node (tests/js).
- Opzioni dal server: Territorio/Proclamatore::opzioneScelta(); i
  territori già assegnati si trovano ("già assegnato a …") ma non si
  scelgono. Nomi cifrati ordinati e cercati decifrati, mai in SQL.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Francesco Picone
2026-10-19 15:35:56 +02:00
parent 2873424c3c
commit fda428f242
16 changed files with 814 additions and 76 deletions

View File

@@ -145,6 +145,24 @@ class Territorio extends Model
return false;
}
/**
* L'opzione per il campo di scelta con ricerca (<x-scelta>): si cerca per
* numero, zona e tipologia. Con $motivo compare cercando ma non si può
* scegliere ("già assegnato a …").
*/
public function opzioneScelta(?string $motivo = null, ?string $nota = null): array
{
$dettaglio = trim(($this->zona?->nome ?? '') . ($this->tipologia?->nome ? " ({$this->tipologia->nome})" : ''));
return array_filter([
'valore' => (string) $this->id,
'etichetta' => "N° {$this->numero}" . ($nota ? " ({$nota})" : ''),
'dettaglio' => $dettaglio !== '' ? $dettaglio : null,
'chiavi' => [(string) $this->numero, (string) $this->zona?->nome, (string) $this->tipologia?->nome],
'motivo' => $motivo,
], fn ($v) => $v !== null);
}
// ─── Scopes ─────────────────────────────────────────────────
public function scopeAttivi($query)