User: {userId}
Record: {recordId ?? 'No record context'}
Component: {componentId}
);
};
export default defineFrontComponent({
universalIdentifier: 'b2c3d4e5-f6a7-8901-bcde-f23456789012',
name: 'record-info',
component: RecordInfo,
});
```
Hook disponibili:
| Hook | Restituisce | Descrizione |
| --------------------------------------------- | ----------------- | --------------------------------------------------------------------- |
| `useUserId()` | `string` o `null` | L'ID dell'utente corrente |
| `useRecordId()` | `string` o `null` | L'ID del record corrente (quando posizionato su una pagina di record) |
| `useFrontComponentId()` | `string` | L'ID di questa istanza di componente |
| `useFrontComponentExecutionContext(selector)` | varia | Accedi all'intero contesto di esecuzione con una funzione selettore |
#### API di comunicazione con l'host
I componenti front-end possono attivare navigazione, modali e notifiche utilizzando funzioni da `twenty-sdk`:
| Funzione | Descrizione |
| ----------------------------------------------- | ------------------------------------- |
| `navigate(to, params?, queryParams?, options?)` | Naviga a una pagina dell'app |
| `openSidePanelPage(params)` | Apri un pannello laterale |
| `closeSidePanel()` | Chiudi il pannello laterale |
| `openCommandConfirmationModal(params)` | Mostra una finestra di conferma |
| `enqueueSnackbar(params)` | Mostra una notifica toast |
| `unmountFrontComponent()` | Smonta il componente |
| `updateProgress(progress)` | Aggiorna un indicatore di avanzamento |
#### Opzioni del comando
Aggiungere un campo `command` a `defineFrontComponent` registra il componente nel menu comandi (Cmd+K). Se `isPinned` è `true`, compare anche come pulsante di azione rapida nell'angolo in alto a destra della pagina.
| Campo | Obbligatorio | Descrizione |
| --------------------------------------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `universalIdentifier` | Sì | ID univoco stabile per il comando |
| `etichetta` | Sì | Etichetta completa mostrata nel menu comandi (Cmd+K) |
| `shortLabel` | No | Etichetta breve visualizzata sul pulsante di azione rapida fissato |
| `icona` | No | Nome dell'icona visualizzato accanto all'etichetta (ad es. `'IconBolt'`, `'IconSend'`) |
| `isPinned` | No | Quando `true`, mostra il comando come pulsante di azione rapida nell'angolo in alto a destra della pagina |
| `availabilityType` | No | Controlla dove compare il comando: `'GLOBAL'` (sempre disponibile), `'RECORD_SELECTION'` (solo quando sono selezionati dei record) o `'FALLBACK'` (mostrato quando nessun altro comando corrisponde) |
| `availabilityObjectUniversalIdentifier` | No | Limita il comando alle pagine di uno specifico tipo di oggetto (ad es. solo sui record Company) |
| `conditionalAvailabilityExpression` | No | Un'espressione booleana per controllare dinamicamente se il comando è visibile (vedi sotto) |
#### Espressioni di disponibilità condizionale
Il campo `conditionalAvailabilityExpression` consente di controllare quando un comando è visibile in base al contesto della pagina corrente. Importa variabili tipizzate e operatori da `twenty-sdk` per costruire espressioni:
```tsx
import {
defineFrontComponent,
pageType,
numberOfSelectedRecords,
objectPermissions,
everyEquals,
isDefined,
} from 'twenty-sdk';
export default defineFrontComponent({
universalIdentifier: '...',
name: 'bulk-action',
component: BulkAction,
command: {
universalIdentifier: '...',
label: 'Bulk Update',
availabilityType: 'RECORD_SELECTION',
conditionalAvailabilityExpression: everyEquals(
objectPermissions,
'canUpdateObjectRecords',
true,
),
},
});
```
**Variabili di contesto** — rappresentano lo stato corrente della pagina:
| Variabile | Tipo | Descrizione |
| ------------------------------ | --------- | ------------------------------------------------------------------------ |
| `pageType` | `string` | Tipo di pagina corrente (ad es. `'RecordIndexPage'`, `'RecordShowPage'`) |
| `isInSidePanel` | `boolean` | Indica se il componente è renderizzato in un pannello laterale |
| `numberOfSelectedRecords` | `numero` | Numero di record attualmente selezionati |
| `isSelectAll` | `boolean` | Indica se "seleziona tutto" è attivo |
| `selectedRecords` | `array` | Gli oggetti dei record selezionati |
| `favoriteRecordIds` | `array` | ID dei record aggiunti ai preferiti |
| `objectPermissions` | `oggetto` | Autorizzazioni per il tipo di oggetto corrente |
| `targetObjectReadPermissions` | `oggetto` | Autorizzazioni di lettura per l'oggetto di destinazione |
| `targetObjectWritePermissions` | `oggetto` | Autorizzazioni di scrittura per l'oggetto di destinazione |
| `featureFlags` | `oggetto` | Flag delle funzionalità attivi |
| `objectMetadataItem` | `oggetto` | Metadati del tipo di oggetto corrente |
| `hasAnySoftDeleteFilterOnView` | `boolean` | Indica se la vista corrente ha un filtro di soft-delete |
**Operatori** — combinano variabili in espressioni booleane:
| Operatore | Descrizione |
| ----------------------------------- | -------------------------------------------------------------------- |
| `isDefined(value)` | `true` se il valore non è null/undefined |
| `isNonEmptyString(value)` | `true` se il valore è una stringa non vuota |
| `includes(array, value)` | `true` se l'array contiene il valore |
| `includesEvery(array, prop, value)` | `true` se la proprietà di ogni elemento include il valore |
| `every(array, prop)` | `true` se la proprietà è truthy su ogni elemento |
| `everyDefined(array, prop)` | `true` se la proprietà è definita su ogni elemento |
| `everyEquals(array, prop, value)` | `true` se la proprietà è uguale al valore su ogni elemento |
| `some(array, prop)` | `true` se la proprietà è truthy su almeno un elemento |
| `someDefined(array, prop)` | `true` se la proprietà è definita su almeno un elemento |
| `someEquals(array, prop, value)` | `true` se la proprietà è uguale al valore su almeno un elemento |
| `someNonEmptyString(array, prop)` | `true` se la proprietà è una stringa non vuota su almeno un elemento |
| `none(array, prop)` | `true` se la proprietà è falsy su ogni elemento |
| `noneDefined(array, prop)` | `true` se la proprietà è undefined su ogni elemento |
| `noneEquals(array, prop, value)` | `true` se la proprietà non è uguale al valore su alcun elemento |
#### Asset pubblici
I componenti front-end possono accedere ai file dalla directory `public/` dell'app utilizzando `getPublicAssetUrl`:
```tsx
import { defineFrontComponent, getPublicAssetUrl } from 'twenty-sdk';
const Logo = () =>