Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message
Nova
wm/wm-package
cursor
laravel
wm
wm-package

Si applica quando tocchi Resource, campi, action o card Nova del package.

Install
php artisan boost:add-skill wm/wm-package

Save this content to: .cursor/rules/nova.md

# Trappole: Nova

Si applica quando tocchi Resource, campi, action o card Nova del package.

- Sui campi Media si usa **sempre `->singleMediaRules()`, mai `->rules()`**: quest'ultimo valida
  l'intero array della collection e blocca **ogni** salvataggio del form, anche senza toccare il
  campo (oc:8247).
- `Images::make()` (Ebess) impone `['image']` non sovrascrivibile, e con Laravel 12 quella regola
  esclude gli SVG: per un SVG serve `Files::make()` (oc:8272).
- Nel callback `->store()` di un campo `File`, `return null` **distrugge il valore esistente** a
  ogni update senza file: si torna `true` per non toccarlo. E il callback gira prima del `save()`,
  quindi in creazione `$model->id` è `null` (oc:8175).
- `Multiselect::options()` accetta **un solo argomento**: il secondo è ignorato in silenzio
  (oc:7953).
- Il titolo di una Resource **non può essere una colonna enum** (500 in pagina): serve un metodo
  `title()`. E i modelli devono dichiarare nullable anche le colonne obbligatorie, perché Nova
  costruisce i campi su un'istanza vuota (oc:8489).
- Una classe Tailwind che Nova non usa nella propria UI **viene eliminata dal purge e non ha alcun
  effetto**: si usano solo classi verificate nel CSS di Nova, o CSS scoped (oc:7546).
- `<Teleport to="body">` è obbligatorio per un modale dentro i tab di Nova, altrimenti è
  disallineato (oc:7546).
- Il toast 422 di Nova mostra sempre una stringa fissa: un messaggio di validazione custom non è
  mostrabile senza patchare il vendor (oc:8247).
- I link costruiti a mano in un field usano `Nova::path()`: un path hardcoded perde il prefisso
  `/nova` (oc:8089).
- **Il package registra una sola policy** (`App`). Un consumer che monta la Resource `EcTrack`
  senza registrare `EcTrackPolicy` lascia Nova autorizzare chiunque — verificalo quando aggiungi
  una Resource EC a un consumer (oc:8181).
- Nei campi di un'Action, `$request->resourceId` è vuoto nella richiesta che risolve un
  `dependsOn()`: la tendina dipendente resta vuota — Nova manda `resources`, una lista di id,
  nella `PATCH` gestita da `ActionRequest`, quindi vanno letti entrambi (oc:8569).
- Un'Action istanziata a mano in un test ha `runCallback` nullo e risulta **sempre**
  autorizzata: il `canRun()` va preso dall'istanza che la Resource restituisce, altrimenti il
  test non verifica nulla (oc:8569).
- `->sole()` vincola un'azione a una singola risorsa **solo lato UI Nova**: il server
  (`DispatchAction::forModels()`) non lo applica, e una richiesta con più risorse selezionate
  arriva comunque a `handle()` con più elementi in `$models` — un'azione che assume
  `$models->first()` processa solo il primo mostrando comunque successo per tutti. `->standalone()`
  ha un significato opposto (azione eseguibile senza nessun modello selezionato): non sono
  intercambiabili nonostante il nome suggerisca il contrario (oc:8543).
- In una Nova Action, `Bus::dispatch()`/`Job::dispatch()` "nudo" può far leggere a un worker un
  dato non ancora committato: Nova avvolge `handle()` in una transazione DB, e le connessioni di
  coda hanno `after_commit => false` in `config/queue.php` — un dispatch senza `->afterCommit()`
  pusha il job in coda prima del commit (oc:8543).
- `Bus::chain($jobs)->dispatch()->afterCommit()` fallisce (`Call to a member function afterCommit()
  on null`): a differenza di `Job::dispatch()`, `PendingChain::dispatch()` non è fluente e non ha
  un metodo `afterCommit()` proprio — dispatcha subito e ritorna `null`. Solo il primo job di una
  catena viene effettivamente accodato (gli altri partono in base al suo esito), quindi va marcato
  lui: `$chain[0]->afterCommit(); Bus::chain($chain)->dispatch();` (oc:8543).
- I Field dentro un `Tab` finiscono anche sull'index se non hanno restrizioni di visibilità: il tab
  DEM porta sull'index `round_trip` e le durate bici/escursionismo. Una Resource che usa
  `getDemTabFields()` dichiara `fieldsForIndex()` (oc:8571).
- `Boolean::resolveDefaultValue()` restituisce il default solo in una richiesta di Action o di
  creazione: in un test su `fields()` di un'Action serve un `ActionRequest` reale, altrimenti torna
  `null` (oc:8543).
- L'`help()` di un campo è reso con `v-html`: un valore letto dal DB va passato da `e()`, altrimenti
  il markup arriva nel browser dell'utente (oc:8543).
- Il `MultiSelect` nativo di Nova è una `<select multiple>` del browser (si sceglie una voce sola
  solo con un clic senza modificatori, le altre con ⌘/Ctrl): per le select multiple si usa il
  `Multiselect` di Outl1ne, come nel resto del package (oc:8588).
- `Multiselect` di Outl1ne su un attributo `properties->chiave` salva una **stringa** JSON dentro
  `properties` se non si chiama `->saveAsJSON()`: decide guardando il cast della chiave con la
  freccia, che non esiste (oc:8588).
- Dopo un'Action Nova **ricrea** il dettaglio: `getResource()` in
  `vendor/laravel/nova/resources/js/views/Detail.vue` azzera `panels`, i campi si smontano e si
  rimontano. Lo stato di un componente — la vista di una mappa, dati caricati — si perde: ciò che
  deve sopravvivere va tenuto fuori dal componente (oc:8662).
- Un campo che tiene altri campi come oggetti nel proprio meta (come `FlexibleTranslatable` con i
  sotto-campi per lingua), messo in un layout Flexible, condivide quegli oggetti con gli altri
  gruppi e con il template del layout (`Layout::cloneField()` fa un clone superficiale): nell'edit
  i valori arrivano vuoti, perché la risposta di Nova serializza il campo due volte (`fields` e
  `panels`) dopo il `resolve(true)` del template, oppure presi da un altro gruppo — i sotto-campi
  vanno serializzati subito nel `jsonSerialize()` del campo (oc:8675).
- **Nova traduce da sé `$confirmButtonText`, `$cancelButtonText` e `$confirmText` delle Action**
  (`Nova::__()`): una stringa italiana lì è una chiave di traduzione italiana, anche senza `__()`.
  `Filter::name()` invece non traduce `$name`: per un nome traducibile si ridefinisce `name()` con
  `__()` (oc:8672).

Trappole: Nova

Si applica quando tocchi Resource, campi, action o card Nova del package.

  • Sui campi Media si usa sempre ->singleMediaRules(), mai ->rules(): quest'ultimo valida l'intero array della collection e blocca ogni salvataggio del form, anche senza toccare il campo (oc:8247).
  • Images::make() (Ebess) impone ['image'] non sovrascrivibile, e con Laravel 12 quella regola esclude gli SVG: per un SVG serve Files::make() (oc:8272).
  • Nel callback ->store() di un campo File, return null distrugge il valore esistente a ogni update senza file: si torna true per non toccarlo. E il callback gira prima del save(), quindi in creazione $model->id è null (oc:8175).
  • Multiselect::options() accetta un solo argomento: il secondo è ignorato in silenzio (oc:7953).
  • Il titolo di una Resource non può essere una colonna enum (500 in pagina): serve un metodo title(). E i modelli devono dichiarare nullable anche le colonne obbligatorie, perché Nova costruisce i campi su un'istanza vuota (oc:8489).
  • Una classe Tailwind che Nova non usa nella propria UI viene eliminata dal purge e non ha alcun effetto: si usano solo classi verificate nel CSS di Nova, o CSS scoped (oc:7546).
  • <Teleport to="body"> è obbligatorio per un modale dentro i tab di Nova, altrimenti è disallineato (oc:7546).
  • Il toast 422 di Nova mostra sempre una stringa fissa: un messaggio di validazione custom non è mostrabile senza patchare il vendor (oc:8247).
  • I link costruiti a mano in un field usano Nova::path(): un path hardcoded perde il prefisso /nova (oc:8089).
  • Il package registra una sola policy (App). Un consumer che monta la Resource EcTrack senza registrare EcTrackPolicy lascia Nova autorizzare chiunque — verificalo quando aggiungi una Resource EC a un consumer (oc:8181).
  • Nei campi di un'Action, $request->resourceId è vuoto nella richiesta che risolve un dependsOn(): la tendina dipendente resta vuota — Nova manda resources, una lista di id, nella PATCH gestita da ActionRequest, quindi vanno letti entrambi (oc:8569).
  • Un'Action istanziata a mano in un test ha runCallback nullo e risulta sempre autorizzata: il canRun() va preso dall'istanza che la Resource restituisce, altrimenti il test non verifica nulla (oc:8569).
  • ->sole() vincola un'azione a una singola risorsa solo lato UI Nova: il server (DispatchAction::forModels()) non lo applica, e una richiesta con più risorse selezionate arriva comunque a handle() con più elementi in $models — un'azione che assume $models->first() processa solo il primo mostrando comunque successo per tutti. ->standalone() ha un significato opposto (azione eseguibile senza nessun modello selezionato): non sono intercambiabili nonostante il nome suggerisca il contrario (oc:8543).
  • In una Nova Action, Bus::dispatch()/Job::dispatch() "nudo" può far leggere a un worker un dato non ancora committato: Nova avvolge handle() in una transazione DB, e le connessioni di coda hanno after_commit => false in config/queue.php — un dispatch senza ->afterCommit() pusha il job in coda prima del commit (oc:8543).
  • Bus::chain($jobs)->dispatch()->afterCommit() fallisce (Call to a member function afterCommit() on null): a differenza di Job::dispatch(), PendingChain::dispatch() non è fluente e non ha un metodo afterCommit() proprio — dispatcha subito e ritorna null. Solo il primo job di una catena viene effettivamente accodato (gli altri partono in base al suo esito), quindi va marcato lui: $chain[0]->afterCommit(); Bus::chain($chain)->dispatch(); (oc:8543).
  • I Field dentro un Tab finiscono anche sull'index se non hanno restrizioni di visibilità: il tab DEM porta sull'index round_trip e le durate bici/escursionismo. Una Resource che usa getDemTabFields() dichiara fieldsForIndex() (oc:8571).
  • Boolean::resolveDefaultValue() restituisce il default solo in una richiesta di Action o di creazione: in un test su fields() di un'Action serve un ActionRequest reale, altrimenti torna null (oc:8543).
  • L'help() di un campo è reso con v-html: un valore letto dal DB va passato da e(), altrimenti il markup arriva nel browser dell'utente (oc:8543).
  • Il MultiSelect nativo di Nova è una <select multiple> del browser (si sceglie una voce sola solo con un clic senza modificatori, le altre con ⌘/Ctrl): per le select multiple si usa il Multiselect di Outl1ne, come nel resto del package (oc:8588).
  • Multiselect di Outl1ne su un attributo properties->chiave salva una stringa JSON dentro properties se non si chiama ->saveAsJSON(): decide guardando il cast della chiave con la freccia, che non esiste (oc:8588).
  • Dopo un'Action Nova ricrea il dettaglio: getResource() in vendor/laravel/nova/resources/js/views/Detail.vue azzera panels, i campi si smontano e si rimontano. Lo stato di un componente — la vista di una mappa, dati caricati — si perde: ciò che deve sopravvivere va tenuto fuori dal componente (oc:8662).
  • Un campo che tiene altri campi come oggetti nel proprio meta (come FlexibleTranslatable con i sotto-campi per lingua), messo in un layout Flexible, condivide quegli oggetti con gli altri gruppi e con il template del layout (Layout::cloneField() fa un clone superficiale): nell'edit i valori arrivano vuoti, perché la risposta di Nova serializza il campo due volte (fields e panels) dopo il resolve(true) del template, oppure presi da un altro gruppo — i sotto-campi vanno serializzati subito nel jsonSerialize() del campo (oc:8675).
  • Nova traduce da sé $confirmButtonText, $cancelButtonText e $confirmText delle Action (Nova::__()): una stringa italiana lì è una chiave di traduzione italiana, anche senza __(). Filter::name() invece non traduce $name: per un nome traducibile si ridefinisce name() con __() (oc:8672).
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo