@navette-js/panels 1.0.0-beta.1 → 1.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.ts CHANGED
@@ -14,7 +14,7 @@ import type { DataAdapter } from '@navette-js/database';
14
14
  import { Table, type ColumnState, type FilterState, type TableHost } from '@navette-js/tables';
15
15
  import { Component, type WireRuntime } from '@navette-js/wire';
16
16
  export declare const ASSET_VERSION = "5.11.2.0";
17
- /** Utilisateur connecté. Votre fournisseur d'authentification peut y ajouter ce qu'il veut (rôle, équipe…) : les politiques le reçoivent tel quel. */
17
+ /** The signed-in user. Your auth provider may add any field (role, team…): policies receive it as-is. */
18
18
  export type User = {
19
19
  id: string | number;
20
20
  name: string;
@@ -22,18 +22,18 @@ export type User = {
22
22
  [key: string]: unknown;
23
23
  };
24
24
  /**
25
- * Politique d'une resource : une fonction par capacité, nommée comme dans Laravel
26
- * (`viewAny`, `create`, `update`, `delete`, `deleteAny`, `restore`, `forceDelete`, `reorder`, ou vos propres noms).
27
- * Capacité absente : autorisée.
25
+ * Resource policy: one function per ability
26
+ * (`viewAny`, `create`, `update`, `delete`, `deleteAny`, `restore`, `forceDelete`, `reorder`, or your own names).
27
+ * A missing ability is allowed.
28
28
  */
29
29
  export type Policy<R = any> = Partial<Record<string, (user: User, record: R | null) => boolean | Promise<boolean>>>;
30
- /** Plugin : un paquet de configuration réutilisable. `register` reçoit le panel en cours de construction ; `boot` est appelé au montage du routeur. */
30
+ /** A reusable bundle of configuration. `register` receives the panel being built; `boot` is called when the router is mounted. */
31
31
  export type Plugin = {
32
32
  id: string;
33
33
  register(panel: Panel): void;
34
34
  boot?(panel: Panel): void;
35
35
  };
36
- /** Question posée au crochet d'autorisation du panel. `resource`, `page` ou `widget` dit sur quoi elle porte. */
36
+ /** Question asked to the panel's authorization hook. `resource`, `page` or `widget` tells what it is about. */
37
37
  export type AuthorizationCheck = {
38
38
  user: User;
39
39
  ability: string;
@@ -42,26 +42,26 @@ export type AuthorizationCheck = {
42
42
  page: typeof Page | null;
43
43
  widget: typeof Widget | null;
44
44
  };
45
- /** Rend `true` ou `false` pour décider, `undefined` pour laisser la politique de la resource (ou `canAccess` / `canView`) répondre. */
45
+ /** Return `true` or `false` to decide, or `undefined` to let the resource policy (or `canAccess` / `canView`) answer. */
46
46
  export type Authorizer = (check: AuthorizationCheck) => boolean | undefined | Promise<boolean | undefined>;
47
47
  type MaybePromise<T> = T | Promise<T>;
48
48
  /**
49
- * Fournisseur d'utilisateurs. `attempt` et `find` suffisent pour la connexion ; les méthodes facultatives activent
50
- * l'inscription (`create`, `findByEmail`), la réinitialisation du mot de passe (`findByEmail`, `update`, `getPasswordFingerprint`),
51
- * la vérification de l'adresse (`hasVerifiedEmail`, `markEmailAsVerified`) et la page de profil (`update`).
52
- * `knexAuthProvider(knex)` les fournit toutes pour une table `users` au format de Laravel.
49
+ * User provider. `attempt` and `find` are enough for login; the optional methods enable
50
+ * registration (`create`, `findByEmail`), password reset (`findByEmail`, `update`, `getPasswordFingerprint`),
51
+ * email verification (`hasVerifiedEmail`, `markEmailAsVerified`) and the profile page (`update`).
52
+ * `knexAuthProvider(knex)` implements all of them for a `users` table.
53
53
  */
54
54
  export interface AuthProvider {
55
55
  attempt(email: string, password: string): MaybePromise<User | null>;
56
56
  find(id: string | number): MaybePromise<User | null>;
57
57
  findByEmail?(email: string): MaybePromise<User | null>;
58
- /** Crée l'utilisateur ; le mot de passe est reçu en clair, à hacher par le fournisseur. */
58
+ /** Creates the user. The password is plain text; the provider must hash it. */
59
59
  create?(data: {
60
60
  name: string;
61
61
  email: string;
62
62
  password: string;
63
63
  }): MaybePromise<User>;
64
- /** Met à jour nom, adresse ou mot de passe (en clair, à hacher). Changer d'adresse doit annuler sa vérification. */
64
+ /** Updates name, email or password (plain text, to hash). Changing the email must reset its verification. */
65
65
  update?(user: User, data: {
66
66
  name?: string;
67
67
  email?: string;
@@ -69,25 +69,25 @@ export interface AuthProvider {
69
69
  }): MaybePromise<User>;
70
70
  hasVerifiedEmail?(user: User): MaybePromise<boolean>;
71
71
  markEmailAsVerified?(user: User): MaybePromise<void>;
72
- /** Valeur qui change avec le mot de passe enregistré : un lien de réinitialisation déjà servi devient invalide. */
72
+ /** A value that changes with the stored password, so a used reset link becomes invalid. */
73
73
  getPasswordFingerprint?(user: User): MaybePromise<string>;
74
74
  }
75
75
  /**
76
- * Locataires d'un panel (équipes, organisations…) : port de `->tenant(Team::class)`. Chaque page du panel vit alors
77
- * sous `/<panel>/<clé du locataire>/…`, et seul un membre du locataire peut l'ouvrir.
76
+ * Panel tenants (teams, organizations…). Every panel page then lives under
77
+ * `/<panel>/<tenant key>/…`, and only a member of the tenant can open it.
78
78
  */
79
79
  export interface TenantProvider<T = any> {
80
- /** Locataires dont l'utilisateur est membre. */
80
+ /** Tenants the user is a member of. */
81
81
  getTenants(user: User): MaybePromise<T[]>;
82
- /** Locataire d'après sa clé dans l'adresse (venue du navigateur : à valider). */
82
+ /** Tenant from its URL key (comes from the browser: validate it). */
83
83
  find(key: string): MaybePromise<T | null>;
84
84
  canAccess(user: User, tenant: T): MaybePromise<boolean>;
85
85
  getKey(tenant: T): string;
86
86
  getName(tenant: T): string;
87
- /** Texte au-dessus du nom dans le menu (« Current team »), ou `null`. */
87
+ /** Text above the tenant name in the menu ("Current team"), or `null`. */
88
88
  getCurrentTenantLabel?(tenant: T): string | null;
89
89
  getAvatarUrl?(tenant: T): string | null;
90
- /** Création (page d'inscription d'un locataire) : l'utilisateur en devient membre. */
90
+ /** Creates a tenant (tenant registration page); the user becomes a member. */
91
91
  create?(data: Record<string, unknown>, user: User): MaybePromise<T>;
92
92
  update?(tenant: T, data: Record<string, unknown>): MaybePromise<T>;
93
93
  }
@@ -100,8 +100,8 @@ export type PanelContext = {
100
100
  tenant?: unknown;
101
101
  };
102
102
  /**
103
- * Thème prédéfini d'un panel : un jeu de couleurs (palettes ou simples couleurs), éventuellement une police et du CSS.
104
- * Quand un panel en déclare plusieurs, l'utilisateur choisit le sien dans son menu ; le choix est gardé dans un cookie.
103
+ * Predefined panel theme: a set of colors (palettes or plain colors), optionally a font and some CSS.
104
+ * When a panel declares several, users pick theirs from the user menu; the choice is kept in a cookie.
105
105
  */
106
106
  export type Theme = {
107
107
  id: string;
@@ -111,7 +111,7 @@ export type Theme = {
111
111
  family: string;
112
112
  url?: string;
113
113
  };
114
- /** CSS ajouté à la page pour ce thème (écrit par le développeur du panel, inséré tel quel). */
114
+ /** CSS added to the page for this theme (written by the panel developer, inserted as-is). */
115
115
  css?: string;
116
116
  };
117
117
  export declare class NavigationItem {
@@ -130,7 +130,7 @@ export declare class NavigationItem {
130
130
  group(group: string | null): this;
131
131
  sort(sort: number): this;
132
132
  badge(badge: string | number | null, color?: string): this;
133
- /** Par défaut un élément est actif sur son URL exacte, comme une page Filament (les resources fourniront leur propre règle). */
133
+ /** By default an item is active on its exact URL; this overrides the rule. */
134
134
  isActiveWhen(fn: (path: string) => boolean): this;
135
135
  isActive(path: string): boolean;
136
136
  }
@@ -162,57 +162,57 @@ export declare class Panel {
162
162
  brandLogo(url: string): this;
163
163
  darkModeBrandLogo(url: string): this;
164
164
  brandLogoHeight(height: string): this;
165
- /** Icône d'onglet du navigateur. */
165
+ /** Browser tab icon. */
166
166
  favicon(url: string | null): this;
167
167
  getFavicon(): string | null;
168
168
  /**
169
- * Feuille de thème compilée par l'application (Tailwind) : elle remplace la feuille par défaut de Filament.
170
- * Équivalent de `->viteTheme()` : le thème importe `@navette-js/panels/theme.css` et déclare ses propres sources.
169
+ * Theme stylesheet compiled by the application (Tailwind); it replaces the default stylesheet.
170
+ * The theme imports `@navette-js/panels/theme.css` and declares its own sources.
171
171
  */
172
172
  theme(url: string | null): this;
173
173
  getTheme(): string | null;
174
174
  /**
175
- * Mouvement et indicateurs de chargement propres à Navette (ressorts, pastille d'activité, roue des zones différées).
176
- * C'est un écart assumé avec Filament : `motion(false)` rend l'interface d'origine, sans rien d'ajouté.
175
+ * Navette's motion and loading indicators (springs, activity dot, spinner for deferred areas).
176
+ * `motion(false)` renders the plain interface without them.
177
177
  */
178
178
  motion(enabled?: boolean): this;
179
179
  hasMotion(): boolean;
180
- /** Thèmes proposés à l'utilisateur ; le premier est le thème par défaut. */
180
+ /** Themes offered to the user; the first one is the default. */
181
181
  themes(themes: Theme[]): this;
182
182
  getThemes(): Theme[];
183
- /** Thème de la requête : celui du cookie s'il est déclaré, sinon le premier. Null si le panel n'a pas de thèmes. */
183
+ /** Theme for the request: the cookie's theme if declared, otherwise the first one. `null` if the panel has no themes. */
184
184
  resolveTheme(req: Request): Theme | null;
185
185
  rememberTheme(res: Response, theme: Theme): void;
186
- /** Exécute un rendu avec les couleurs du thème de la requête. */
186
+ /** Runs a render with the colors of the request's theme. */
187
187
  withTheme<T>(req: Request, fn: () => T): T;
188
188
  setColors(colors: Record<string, Palette | string>): this;
189
- /** Police du panel. Sans URL : fournisseur Bunny Fonts, comme `->font('Albert Sans')` dans Filament. */
189
+ /** Panel font. Without a URL, it is loaded from Bunny Fonts. */
190
190
  font(family: string, url?: string): this;
191
191
  login(page?: typeof Login): this;
192
192
  auth(provider: AuthProvider): this;
193
193
  key(key: string): this;
194
194
  pages(pages: (typeof Page)[]): this;
195
- /** Enregistre des resources : leurs pages et leur élément de navigation. */
195
+ /** Registers resources: their pages and navigation items. */
196
196
  resources(resources: (typeof Resource)[]): this;
197
197
  navigationItems(items: NavigationItem[]): this;
198
- /** Ordre des groupes de navigation. */
198
+ /** Order of navigation groups. */
199
199
  navigationGroups(groups: string[]): this;
200
200
  private _plugins;
201
- /** Applique un plugin : un objet qui configure le panel (resources, pages, render hooks, thèmes…). */
201
+ /** Applies a plugin: an object that configures the panel (resources, pages, render hooks, themes…). */
202
202
  plugin(plugin: Plugin): this;
203
203
  plugins(plugins: Plugin[]): this;
204
204
  getPlugins(): Plugin[];
205
205
  private _renderHooks;
206
206
  /**
207
- * Insère du HTML à un emplacement nommé de l'interface de ce panel (noms : `PanelsRenderHook`, `TablesRenderHook`, `ActionsRenderHook`, `WidgetsRenderHook`).
208
- * `scopes` limite le hook à certaines pages ou resources (leur classe). Le HTML rendu est inséré tel quel : échappez toute donnée avec `e()`.
207
+ * Inserts HTML at a named location of this panel's UI (names: `PanelsRenderHook`, `TablesRenderHook`, `ActionsRenderHook`, `WidgetsRenderHook`).
208
+ * `scopes` limits the hook to some pages or resources (their class). The HTML is inserted as-is: escape any data with `e()`.
209
209
  */
210
210
  renderHook(name: string, render: RenderHookCallback, scopes?: unknown | unknown[] | null): this;
211
211
  getRenderHooks(): RenderHookRegistry;
212
212
  private _authorizer;
213
- /** Branche votre propre système de permissions : consulté avant toute politique, pour chaque capacité, page et widget. */
213
+ /** Plugs in your own permission system: consulted before any policy, for every ability, page and widget. */
214
214
  authorizeUsing(authorizer: Authorizer | null): this;
215
- /** Décision d'autorisation : le crochet du panel d'abord, puis la règle fournie ; sans utilisateur, toujours non. */
215
+ /** Authorization decision: the panel hook first, then the given rule. Always `false` without a user. */
216
216
  authorize(user: User | null, ability: string, subject?: {
217
217
  resource?: unknown;
218
218
  record?: unknown;
@@ -220,10 +220,10 @@ export declare class Panel {
220
220
  widget?: typeof Widget;
221
221
  rule?: (() => boolean | Promise<boolean>) | null;
222
222
  }): Promise<boolean>;
223
- /** Une page est-elle accessible à cet utilisateur ? Liste : `viewAny` ; création : `create` ; édition : vérifiée sur l'enregistrement ; page libre : `canAccess`. */
223
+ /** Whether the user can open a page. List: `viewAny`; create: `create`; edit: checked against the record; custom page: `canAccess`. */
224
224
  canAccessPage(PageClass: typeof Page, user: User | null): Promise<boolean>;
225
225
  private _widgets;
226
- /** Widgets du panel (tableau de bord, pages libres) : enregistrés comme composants, à afficher par `getHeaderWidgets()` d'une page. */
226
+ /** Panel widgets (dashboard, custom pages): registered as components, displayed through a page's `getHeaderWidgets()`. */
227
227
  widgets(widgets: (typeof Widget)[]): this;
228
228
  getWidgets(): (typeof Widget)[];
229
229
  maxContentWidth(width: string): this;
@@ -237,27 +237,27 @@ export declare class Panel {
237
237
  private _globalSearchKeyBindings;
238
238
  private _globalSearchDebounce;
239
239
  private _globalSearchSuffix;
240
- /** `false` retire le champ de recherche globale. Il n'apparaît de toute façon que si une resource est cherchable. */
240
+ /** `false` removes the global search field. It only appears when at least one resource is searchable. */
241
241
  globalSearch(condition?: boolean): this;
242
- /** Raccourcis qui placent le curseur dans le champ : `['command+k', 'ctrl+k']`. */
242
+ /** Keyboard shortcuts that focus the field: `['command+k', 'ctrl+k']`. */
243
243
  globalSearchKeyBindings(keyBindings: string[]): this;
244
244
  getGlobalSearchKeyBindings(): string[];
245
- /** Délai entre la frappe et la recherche (`500ms` par défaut). */
245
+ /** Delay between typing and searching (`500ms` by default). */
246
246
  globalSearchDebounce(debounce: string): this;
247
247
  getGlobalSearchDebounce(): string;
248
248
  globalSearchFieldSuffix(suffix: string | null): this;
249
- /** Affiche le premier raccourci dans le champ, écrit selon la plateforme du navigateur (comme Filament : « META+K » hors Mac pour `command+k`). */
249
+ /** Shows the first shortcut in the field, written for the browser's platform (`command+k` shows as "META+K" outside macOS). */
250
250
  globalSearchFieldKeyBindingSuffix(): this;
251
251
  getGlobalSearchFieldSuffix(userAgent?: string): string | null;
252
252
  hasGlobalSearch(): boolean;
253
- /** Résultats par resource, dans l'ordre d'enregistrement ; seules les resources que l'utilisateur peut lister sont interrogées. */
253
+ /** Results per resource, in registration order. Only resources the user can list are queried. */
254
254
  getGlobalSearchResults(search: string, user: User | null): Promise<GlobalSearchCategory[]>;
255
255
  private _databaseNotifications;
256
256
  private _databaseNotificationsPolling;
257
- /** Active la cloche des notifications enregistrées en base, lues et écrites par ce stockage (`knexNotificationStore(knex)`). */
257
+ /** Enables the database notifications bell, read from and written to this store (`knexNotificationStore(knex)`). */
258
258
  databaseNotifications(store: DatabaseNotificationStore | null): this;
259
259
  getDatabaseNotifications(): DatabaseNotificationStore | null;
260
- /** Intervalle de rafraîchissement (`30s` par défaut) ; `null` pour ne pas interroger le serveur. */
260
+ /** Polling interval (`30s` by default); `null` disables polling. */
261
261
  databaseNotificationsPolling(interval: string | null): this;
262
262
  getDatabaseNotificationsPollingInterval(): string | null;
263
263
  private _topbar;
@@ -266,22 +266,22 @@ export declare class Panel {
266
266
  private _sidebarCollapsibleOnDesktop;
267
267
  private _sidebarFullyCollapsibleOnDesktop;
268
268
  private _positions;
269
- /** Barre du haut (présente par défaut, comme dans Filament) : `topbar(false)` met logo, recherche, cloche et menu dans la sidebar. */
269
+ /** Topbar, shown by default. `topbar(false)` moves the logo, search, bell and user menu into the sidebar. */
270
270
  topbar(condition?: boolean): this;
271
271
  hasTopbar(): boolean;
272
- /** Navigation dans la barre du haut (menus déroulants par groupe) au lieu de la sidebar. */
272
+ /** Navigation in the topbar (one dropdown per group) instead of the sidebar. */
273
273
  topNavigation(condition?: boolean): this;
274
274
  hasTopNavigation(): boolean;
275
- /** `navigation(false)` retire toute navigation (ni sidebar ni menus). */
275
+ /** `navigation(false)` removes all navigation (no sidebar, no menus). */
276
276
  navigation(condition?: boolean): this;
277
277
  hasNavigation(): boolean;
278
- /** Sidebar repliable sur grand écran en une colonne d'icônes. */
278
+ /** On desktop, the sidebar can collapse to a column of icons. */
279
279
  sidebarCollapsibleOnDesktop(condition?: boolean): this;
280
280
  isSidebarCollapsibleOnDesktop(): boolean;
281
- /** Sidebar entièrement masquable sur grand écran. */
281
+ /** On desktop, the sidebar can be fully hidden. */
282
282
  sidebarFullyCollapsibleOnDesktop(condition?: boolean): this;
283
283
  isSidebarFullyCollapsibleOnDesktop(): boolean;
284
- /** Emplacement du menu utilisateur ; par défaut, la barre du haut si elle existe. */
284
+ /** Where the user menu goes; defaults to the topbar when there is one. */
285
285
  userMenuPosition(position: 'topbar' | 'sidebar' | null): this;
286
286
  getUserMenuPosition(): 'topbar' | 'sidebar';
287
287
  globalSearchPosition(position: 'topbar' | 'sidebar' | null): this;
@@ -289,7 +289,7 @@ export declare class Panel {
289
289
  databaseNotificationsPosition(position: 'topbar' | 'sidebar' | null): this;
290
290
  getDatabaseNotificationsPosition(): 'topbar' | 'sidebar';
291
291
  private _userMenuItems;
292
- /** Éléments ajoutés au menu utilisateur (actions à adresse ou à modale). `sort()` négatif : au-dessus du choix du thème. Clés `profile` et `logout` : remplacent ceux par défaut. */
292
+ /** Items added to the user menu (URL or modal actions). A negative `sort()` places them above the theme switcher. Keys `profile` and `logout` replace the defaults. */
293
293
  userMenuItems(items: Record<string, Action> | Action[]): this;
294
294
  getUserMenuItems(): Record<string, Action>;
295
295
  private _registration;
@@ -297,37 +297,37 @@ export declare class Panel {
297
297
  private _emailVerification;
298
298
  private _profile;
299
299
  private _mailer;
300
- /** Page d'inscription (`/register`). Le fournisseur d'utilisateurs doit savoir créer (`create`) et chercher par adresse (`findByEmail`). */
300
+ /** Registration page (`/register`). The auth provider must implement `create` and `findByEmail`. */
301
301
  registration(page?: typeof Register | null): this;
302
302
  hasRegistration(): boolean;
303
303
  getRegistrationPage(): typeof Register | null;
304
- /** Mot de passe oublié : demande (`/password-reset/request`) et réinitialisation par un lien signé envoyé par e-mail. */
304
+ /** Password reset: request page (`/password-reset/request`), then reset through a signed link sent by email. */
305
305
  passwordReset(request?: typeof RequestPasswordReset, reset?: typeof ResetPassword): this;
306
306
  hasPasswordReset(): boolean;
307
307
  getPasswordResetPages(): {
308
308
  request: typeof RequestPasswordReset;
309
309
  reset: typeof ResetPassword;
310
310
  };
311
- /** Vérification de l'adresse e-mail : un lien signé est envoyé à l'inscription ; tant qu'il n'est pas suivi, seule l'invitation à vérifier est accessible (`isRequired`). */
311
+ /** Email verification: a signed link is sent on registration. Until it is followed, only the verification prompt is accessible (`isRequired`). */
312
312
  emailVerification(prompt?: typeof EmailVerificationPrompt, isRequired?: boolean): this;
313
313
  hasEmailVerification(): boolean;
314
314
  isEmailVerificationRequired(): boolean;
315
315
  getEmailVerificationPrompt(): typeof EmailVerificationPrompt | null;
316
- /** Page de profil (`/profile`) : nom, adresse, mot de passe. `isSimple` : mise en page simple (par défaut) ou complète. */
316
+ /** Profile page (`/profile`): name, email, password. `isSimple`: simple layout (default) or full panel layout. */
317
317
  profile(page?: typeof EditProfile, isSimple?: boolean): this;
318
318
  hasProfile(): boolean;
319
319
  getProfile(): {
320
320
  page: typeof EditProfile;
321
321
  isSimple: boolean;
322
322
  };
323
- /** Envoi des e-mails (réinitialisation, vérification). Par défaut : écrits dans la console. */
323
+ /** Mailer for password reset and verification emails. Defaults to the console. */
324
324
  mailer(mailer: Mailer): this;
325
325
  sendMail(message: MailMessage): Promise<void>;
326
326
  getAuthKey(): string;
327
327
  getRegistrationUrl(): string;
328
328
  getRequestPasswordResetUrl(): string;
329
329
  getResetPasswordUrl(user: User, fingerprint: string): string;
330
- /** Charge d'un jeton de réinitialisation valide pour ce panel, sinon `null`. */
330
+ /** Payload of a password reset token valid for this panel, otherwise `null`. */
331
331
  readResetPasswordToken(token: unknown): {
332
332
  uid: string | number;
333
333
  fp: string;
@@ -336,7 +336,7 @@ export declare class Panel {
336
336
  checkVerifyEmailUrl(id: string, hash: string, expires: unknown, signature: unknown): boolean;
337
337
  getEmailVerificationPromptUrl(): string;
338
338
  getProfileUrl(): string | null;
339
- /** L'utilisateur doit-il encore vérifier son adresse avant d'utiliser le panel ? */
339
+ /** Whether the user must still verify their email before using the panel. */
340
340
  mustVerifyEmail(user: User | null): Promise<boolean>;
341
341
  private _tenant;
342
342
  private _tenantOwnershipColumn;
@@ -346,8 +346,8 @@ export declare class Panel {
346
346
  private _tenantMenuItems;
347
347
  private _tenantScope;
348
348
  /**
349
- * Rend le panel multi-locataire. `ownershipColumn` : colonne qui rattache un enregistrement à son locataire (`team_id`) ;
350
- * les resources du panel ne lisent et n'écrivent alors que les enregistrements du locataire courant (voir `Resource.isScopedToTenant`).
349
+ * Makes the panel multi-tenant. `ownershipColumn` is the column linking a record to its tenant (`team_id`);
350
+ * the panel's resources then only read and write the current tenant's records (see `Resource.isScopedToTenant`).
351
351
  */
352
352
  tenant(provider: TenantProvider | null, options?: {
353
353
  ownershipColumn?: string;
@@ -355,54 +355,54 @@ export declare class Panel {
355
355
  hasTenancy(): boolean;
356
356
  getTenantProvider(): TenantProvider;
357
357
  getTenantOwnershipColumn(): string | null;
358
- /** Page de création d'un locataire (`/new`). */
358
+ /** Tenant registration page (`/new`). */
359
359
  tenantRegistration(page: typeof RegisterTenant | null): this;
360
360
  getTenantRegistrationPage(): typeof RegisterTenant | null;
361
- /** Page de profil du locataire (`/<locataire>/profile`). */
361
+ /** Tenant profile page (`/<tenant>/profile`). */
362
362
  tenantProfile(page: typeof EditTenantProfile | null): this;
363
363
  getTenantProfilePage(): typeof EditTenantProfile | null;
364
364
  tenantMenu(condition?: boolean): this;
365
365
  hasTenantMenu(): boolean;
366
366
  tenantMenuItems(items: Record<string, Action> | Action[]): this;
367
367
  getTenantMenuItems(): Record<string, Action>;
368
- /** Exécute `fn` pour un locataire : les adresses produites (`getUrl`) et les requêtes des resources lui sont rattachées. */
368
+ /** Runs `fn` for a tenant: generated URLs (`getUrl`) and resource queries are scoped to it. */
369
369
  withTenant<T>(tenant: unknown, fn: () => T): T;
370
- /** Locataire de la requête en cours (équivalent de `Filament::getTenant()`), ou `null`. */
370
+ /** Tenant of the current request, or `null`. */
371
371
  getTenant<T = any>(): T | null;
372
372
  getTenantUrlKey(tenant: unknown): string;
373
373
  private _subNavigationPosition;
374
- /** Position par défaut de la sous-navigation des pages (`start`, comme Filament). */
374
+ /** Default position of page sub-navigation (`start`). */
375
375
  subNavigationPosition(position: 'start' | 'end' | 'top'): this;
376
376
  getSubNavigationPosition(): 'start' | 'end' | 'top';
377
377
  private _appUrl;
378
- /** Adresse publique de l'application (`https://exemple.fr`), utilisée dans les liens envoyés par e-mail. Sans elle, l'origine de la requête est reprise : à éviter en production (en-tête `Host` falsifiable). */
378
+ /** Public URL of the application (`https://example.com`), used in emailed links. Without it the request origin is used, which should be avoided in production (the `Host` header can be forged). */
379
379
  appUrl(url: string | null): this;
380
380
  getAppUrl(): string | null;
381
381
  getMaxContentWidth(): string;
382
- /** Adresse dans le panel ; dans un panel à locataires, préfixée par le locataire courant (ou celui donné). */
382
+ /** URL inside the panel; in a multi-tenant panel, prefixed with the current (or given) tenant. */
383
383
  getUrl(sub?: string, tenant?: unknown): string;
384
- /** Adresse hors locataire (connexion, inscription, profil, création d'un locataire). */
384
+ /** URL outside any tenant (login, registration, profile, tenant registration). */
385
385
  getBaseUrl(sub?: string): string;
386
386
  getLoginUrl(): string;
387
387
  getLogoutUrl(): string;
388
- /** Préfixe de l'endpoint Livewire de ce panel (`/livewire`, ou `/<chemin>/livewire`) : chaque panel a le sien. */
388
+ /** Prefix of this panel's Livewire endpoint (`/livewire` or `/<path>/livewire`): each panel has its own. */
389
389
  getLivewirePrefix(): string;
390
390
  assetUrl(file: string): string;
391
391
  getBrand(): Record<string, unknown>;
392
392
  getFont(): typeof this._font;
393
- /** Avatar par défaut : port de UiAvatarsProvider (service externe ui-avatars.com, initiales du nom). */
393
+ /** Default avatar: the name's initials from the external ui-avatars.com service. */
394
394
  getUserAvatarUrl(user: User): string;
395
- /** Avatar d'un locataire : celui de son fournisseur (`getAvatarUrl`), sinon ses initiales. */
395
+ /** Tenant avatar: from the tenant provider (`getAvatarUrl`), otherwise its initials. */
396
396
  getTenantAvatarUrl(tenant: unknown): string;
397
397
  private _spa;
398
- /** Navigation sans rechargement (`wire:navigate`) entre les pages du panel, comme `->spa()`. */
398
+ /** SPA mode: navigate between panel pages without full reloads (`wire:navigate`). */
399
399
  spa(condition?: boolean): this;
400
400
  hasSpaMode(): boolean;
401
401
  getAvatarUrlFor(name: string): string;
402
- /** Groupes de navigation : pages enregistrées + éléments libres, triés, groupés dans l'ordre déclaré. */
403
- /** Compteurs de navigation calculés (équivalent de getNavigationBadge()) : adresse de la page → valeur. */
402
+ /** Navigation groups: registered pages plus custom items, sorted, grouped in the declared order. */
403
+ /** Computed navigation badges: page URL → value. */
404
404
  resolveNavigationBadges(): Promise<Map<string, string | number | null>>;
405
- /** Adresses des pages du menu que cet utilisateur ne peut pas ouvrir. */
405
+ /** URLs of menu pages this user cannot open. */
406
406
  resolveInaccessiblePages(user: User | null): Promise<Set<string>>;
407
407
  getNavigation(path: string, badges?: Map<string, string | number | null>, hidden?: Set<string>): {
408
408
  label: string | null;
@@ -423,9 +423,7 @@ export declare class Panel {
423
423
  user(req: Request): Promise<User | null>;
424
424
  }
425
425
  /**
426
- * Emplacements de render hook d'un panel — mêmes noms que `Filament\View\PanelsRenderHook`.
427
- * Ceux d'une brique pas encore portée (barre du haut, recherche globale, menu de locataire, sous-navigation, inscription,
428
- * réinitialisation du mot de passe, enregistrements liés) sont déclarés mais ne sont rendus nulle part pour l'instant : voir `UNPLACED_RENDER_HOOKS`.
426
+ * Render hook locations of a panel. A few are declared but not rendered anywhere yet: see `UNPLACED_RENDER_HOOKS`.
429
427
  */
430
428
  export declare const PanelsRenderHook: {
431
429
  readonly AUTH_LOGIN_FORM_AFTER: "panels::auth.login.form.after";
@@ -465,7 +463,7 @@ export declare const PanelsRenderHook: {
465
463
  readonly PAGE_HEADER_WIDGETS_END: "panels::page.header-widgets.end";
466
464
  readonly PAGE_HEADER_WIDGETS_START: "panels::page.header-widgets.start";
467
465
  readonly PAGE_START: "panels::page.start";
468
- /** Le nom contient « module-menu » dans Filament : conservé tel quel. */
466
+ /** The hook name says "module-menu", not "mobile-menu": kept for compatibility. */
469
467
  readonly PAGE_SUB_NAVIGATION_MOBILE_MENU_AFTER: "panels::page.sub-navigation.module-menu.after";
470
468
  readonly PAGE_SUB_NAVIGATION_MOBILE_MENU_BEFORE: "panels::page.sub-navigation.module-menu.before";
471
469
  readonly PAGE_SUB_NAVIGATION_SIDEBAR_AFTER: "panels::page.sub-navigation.sidebar.after";
@@ -513,27 +511,26 @@ export declare const PanelsRenderHook: {
513
511
  readonly USER_MENU_PROFILE_AFTER: "panels::user-menu.profile.after";
514
512
  readonly USER_MENU_PROFILE_BEFORE: "panels::user-menu.profile.before";
515
513
  };
516
- /** Emplacements de render hook des widgets — mêmes noms que `Filament\Widgets\View\WidgetsRenderHook`. Rendus par `TableWidget`. */
514
+ /** Widget render hook locations, rendered by `TableWidget`. */
517
515
  export declare const WidgetsRenderHook: {
518
516
  readonly TABLE_WIDGET_END: "widgets::table-widget.end";
519
517
  readonly TABLE_WIDGET_START: "widgets::table-widget.start";
520
518
  };
521
519
  /**
522
- * Emplacements déclarés mais rendus nulle part pour l'instant, avec la brique qui leur manque.
523
- * Les quatre « tabs » ne sont rendus par aucune vue de Filament 5.11.2 non plus.
520
+ * Hook locations that are declared but not rendered anywhere yet, with the reason.
524
521
  */
525
522
  export declare const UNPLACED_RENDER_HOOKS: Record<string, string>;
526
- /** Base commune : composant à état hébergeant des schémas (`<nom>Schema(schema)`). */
523
+ /** Common base: a stateful component hosting schemas (`<name>Schema(schema)`). */
527
524
  declare abstract class BasePage extends Component implements SchemaHost {
528
525
  get panel(): Panel;
529
526
  getSchema(name: string): Schema;
530
527
  contentSchema(schema: Schema): Schema;
531
- /** Portées des render hooks de cette page : sa classe (et sa resource pour une page de resource), comme `getRenderHookScopes()` dans Filament. */
528
+ /** Render hook scopes of this page: its class (and its resource, for a resource page). */
532
529
  getRenderHookScopes(): unknown[];
533
530
  }
534
- /** Page d'un panel, dans la mise en page complète (sidebar, en-tête). */
531
+ /** A panel page, in the full layout (sidebar, header). */
535
532
  export declare class Page extends BasePage {
536
- /** Méthodes que le navigateur peut appeler. Une sous-classe ajoute les siennes : `static callable = ['approve']`. */
533
+ /** Methods the browser may call. A subclass adds its own: `static callable = ['approve']`. */
537
534
  static callable: string[];
538
535
  static slug: string;
539
536
  static title: string | null;
@@ -544,11 +541,11 @@ export declare class Page extends BasePage {
544
541
  static navigationBadge: string | number | null;
545
542
  static navigationBadgeColor: string;
546
543
  static shouldRegisterNavigation: boolean;
547
- /** Page réservée à certains utilisateurs : rendre `false` la retire du menu et la refuse (403). */
544
+ /** Restricts the page to some users: returning `false` hides it from the menu and denies it (403). */
548
545
  static canAccess(_user: User): boolean | Promise<boolean>;
549
546
  static getTitle(): string;
550
547
  static getNavigationLabel(): string;
551
- /** Chaque requête, y compris les mises à jour envoyées par le navigateur, exige un utilisateur authentifié : un snapshot conservé après déconnexion ne suffit pas. */
548
+ /** Every request, including browser updates, requires an authenticated user: a snapshot kept after logout is not enough. */
552
549
  boot(): Promise<void>;
553
550
  protected isAccessAuthorized(ctx: PanelContext): boolean | Promise<boolean>;
554
551
  getTitle(): string;
@@ -559,27 +556,27 @@ export declare class Page extends BasePage {
559
556
  }[];
560
557
  getHeaderActions(): Action[];
561
558
  getPageClasses(): string[];
562
- /** Sous-navigation de la page : vide par défaut. */
559
+ /** Page sub-navigation; empty by default. */
563
560
  getSubNavigation(): SubNavigationItem[] | Promise<SubNavigationItem[]>;
564
- /** Position de la sous-navigation : `start` (colonne avant le contenu), `end` (après) ou `top` (onglets). Par défaut : celle de la resource, sinon du panel. */
561
+ /** Sub-navigation position: `start` (column before the content), `end` (after) or `top` (tabs). Defaults to the resource's, then the panel's. */
565
562
  static subNavigationPosition: 'start' | 'end' | 'top' | null;
566
563
  getSubNavigationPosition(): 'start' | 'end' | 'top';
567
- /** Widgets affichés sous le contenu de la page (port de getFooterWidgets). */
564
+ /** Widgets shown below the page content. */
568
565
  getFooterWidgets(): (typeof Widget)[];
569
566
  getFooterWidgetsColumns(): number | Record<string, number>;
570
- /** Port de filament-widgets::components.widgets, dans le schéma `footerWidgets` de la page. */
567
+ /** Footer widget grid, in the page's `footerWidgets` schema. */
571
568
  protected renderFooterWidgets(): Promise<string>;
572
- /** Widgets affichés au-dessus du contenu de la page, et données passées à chacun (propriétés du widget). */
569
+ /** Widgets shown above the page content, with the data passed to each (widget properties). */
573
570
  getHeaderWidgets(): (typeof Widget)[];
574
571
  getHeaderWidgetsColumns(): number;
575
572
  getWidgetData(): Record<string, unknown>;
576
- /** Port de filament-widgets::components.widgets, dans le schéma `headerWidgets` de la page. */
573
+ /** Header widget grid, in the page's `headerWidgets` schema. */
577
574
  protected renderHeaderWidgets(): Promise<string>;
578
- /** Widgets que l'utilisateur courant a le droit de voir (port de filterVisibleWidgets). */
575
+ /** Widgets the current user is allowed to see. */
579
576
  protected filterVisibleWidgets(candidates: (typeof Widget)[]): Promise<(typeof Widget)[]>;
580
- /** Grille de widgets d'un schéma (port de Grid + getWidgetsSchemaComponents) : chaque widget est un composant enfant, « lazy » par défaut. */
577
+ /** Widget grid of a schema: each widget is a child component, lazy-loaded by default. */
581
578
  protected renderWidgetsGrid(widgets: (typeof Widget)[], columns: number | Record<string, number>, schemaKey: string): Promise<string>;
582
- /** Contenu de la page : par défaut son schéma `content`. */
579
+ /** Page content: its `content` schema by default. */
583
580
  protected renderContent(): Promise<string>;
584
581
  mountedActions: {
585
582
  name: string;
@@ -589,54 +586,54 @@ export declare class Page extends BasePage {
589
586
  }[];
590
587
  getActionMountContext(): Record<string, unknown>;
591
588
  protected getActionRecord(): unknown;
592
- /** Enregistrement visé par une action montée dans un contexte donné (ligne de table…). */
589
+ /** Record targeted by an action mounted in a given context (table row…). */
593
590
  protected resolveActionRecord(_context: Record<string, unknown>): Promise<unknown>;
594
- /** Actions pouvant être montées dans un contexte donné (en-tête de page par défaut). */
591
+ /** Actions that can be mounted in a given context (page header by default). */
595
592
  protected getMountableActions(context: Record<string, unknown>): Action[] | Promise<Action[]>;
596
593
  /**
597
- * Actions portées par un composant de schéma (Repeater : ajouter, supprimer, déplacer ; Section : actions d'en-tête).
598
- * La clé vient du navigateur : elle doit désigner un composant réel du schéma, ou le schéma lui-même.
594
+ * Actions owned by a schema component (Repeater: add, delete, move; Section: header actions).
595
+ * The key comes from the browser: it must match a real component of the schema, or the schema itself.
599
596
  */
600
597
  protected getSchemaComponentActions(key: string): Promise<Action[]>;
601
- /** Contexte retenu pour une action montée : celui du serveur, jamais celui du navigateur tel quel. */
598
+ /** Context kept for a mounted action: the server's, never the browser's as-is. */
602
599
  protected resolveMountContext(clientContext: unknown): Record<string, unknown>;
603
600
  private findMountableAction;
604
601
  private actionContext;
605
- /** Schéma du formulaire d'une action montée : clé `mountedActionSchema<n>`, état sous `mountedActions.<n>.data` (comme Filament). */
602
+ /** Form schema of a mounted action: key `mountedActionSchema<n>`, state under `mountedActions.<n>.data`. */
606
603
  getMountedActionSchema(index: number): Promise<Schema | null>;
607
604
  private renderActionModal;
608
- /** Annule un rendu partiel de modale préparé par un champ réactif, quand la même requête exécute ensuite une action. */
605
+ /** Cancels a partial modal render prepared by a live field when the same request then runs an action. */
609
606
  private cancelModalPartialRender;
610
- /** Champ réactif du formulaire d'une action montée : exécute `afterStateUpdated`, puis ne renvoie que la modale concernée (comme Filament). */
607
+ /** Live field in a mounted action's form: runs `afterStateUpdated`, then only returns the affected modal. */
611
608
  updatedMountedActions(_value: unknown, key: string | null): Promise<void>;
612
- /** Appel, depuis le JavaScript d'un champ, d'une méthode que ce champ expose (ex. recherche d'un Select). Sans rendu. */
609
+ /** Calls a method exposed by a field, from that field's JavaScript (e.g. Select search). Does not re-render. */
613
610
  callSchemaComponentMethod(componentKey: unknown, method: unknown, args?: unknown): Promise<unknown>;
614
- /** Une action masquée ne peut être ni montée ni exécutée, même par un appel forgé depuis le navigateur. */
611
+ /** A hidden action can be neither mounted nor run, even through a call forged by the browser. */
615
612
  private assertActionVisible;
616
613
  private syncActionModals;
617
- /** Faux pour un composant à table : ses modales sont rendues dans la table (comme Filament). */
614
+ /** False for a table component: its modals are rendered inside the table. */
618
615
  protected rendersActionModalsInPage(): boolean;
619
616
  renderActionModals(): Promise<string>;
620
- /** Monte une action : sans modale elle s'exécute tout de suite ; avec modale, seul le fragment des modales est renvoyé. */
617
+ /** Mounts an action: without a modal it runs immediately; with one, only the modals fragment is returned. */
621
618
  mountAction(name: unknown, args?: unknown, _context?: unknown): Promise<void>;
622
619
  unmountAction(_shouldCancelParentActions?: unknown): void;
623
620
  callMountedAction(_args?: unknown): Promise<void>;
624
621
  render(): Promise<string>;
625
622
  }
626
623
  /**
627
- * Tableau de bord (port de Filament\Pages\Dashboard) : une grille de widgets, précédée d'un formulaire de filtres
628
- * quand la page définit `filtersFormSchema(schema)` (port de HasFiltersForm). Les filtres sont passés aux widgets sous `pageFilters`.
624
+ * Dashboard: a widget grid, preceded by a filters form when the page defines `filtersFormSchema(schema)`.
625
+ * The filters are passed to widgets as `pageFilters`.
629
626
  */
630
627
  export declare class Dashboard extends Page {
631
628
  static slug: string;
632
629
  static title: string;
633
630
  static navigationIcon: string;
634
631
  static navigationSort: number;
635
- /** État du formulaire de filtres. Reste `null` tant que la page n'a pas de filtres. */
632
+ /** Filters form state. Stays `null` while the page has no filters. */
636
633
  filters: Record<string, unknown> | null;
637
- /** Widgets du tableau de bord. Par défaut : ceux du panel (`panel.widgets([...])`). */
634
+ /** Dashboard widgets. Defaults to the panel's (`panel.widgets([...])`). */
638
635
  getWidgets(): (typeof Widget)[];
639
- /** Colonnes de la grille : un nombre (au point de rupture `lg`), ou un nombre par point de rupture. */
636
+ /** Grid columns: a number (at the `lg` breakpoint), or one number per breakpoint. */
640
637
  getColumns(): number | Record<string, number>;
641
638
  hasFiltersForm(): boolean;
642
639
  getSchema(name: string): Schema;
@@ -644,26 +641,26 @@ export declare class Dashboard extends Page {
644
641
  getWidgetData(): Record<string, unknown>;
645
642
  protected renderContent(): Promise<string>;
646
643
  }
647
- /** Limiteur de tentatives en mémoire : `max` essais par fenêtre, par clé. Suffisant pour une instance ; à remplacer par un magasin partagé si le panel tourne sur plusieurs. */
644
+ /** In-memory rate limiter: `max` attempts per window, per key. Fine for a single instance; use a shared store when running several. */
648
645
  export declare class Throttle {
649
646
  private hits;
650
647
  private max;
651
648
  private windowMs;
652
649
  constructor(max?: number, windowMs?: number);
653
- /** Enregistre un essai ; rend 0 s'il est permis, sinon le nombre de secondes à attendre. */
650
+ /** Records an attempt; returns 0 if allowed, otherwise the number of seconds to wait. */
654
651
  hit(key: string, now?: number): number;
655
652
  clear(key: string): void;
656
653
  }
657
- /** Page à mise en page « simple » (connexion, inscription…). */
654
+ /** Page with the simple layout (login, registration…). */
658
655
  export declare abstract class SimplePage extends BasePage {
659
656
  abstract getTitle(): string;
660
657
  getHeading(): string | null;
661
- /** Sous-titre, en HTML de confiance (composé par la page, données échappées). */
658
+ /** Subheading, as trusted HTML (built by the page, with data escaped). */
662
659
  getSubheading(): string | null;
663
660
  hasLogo(): boolean;
664
661
  render(): Promise<string>;
665
662
  }
666
- /** Inscription (port de Filament\Auth\Pages\Register) : nom, adresse, mot de passe confirmé ; l'utilisateur est connecté, puis invité à vérifier son adresse si le panel l'exige. */
663
+ /** Registration page: name, email, confirmed password. The user is logged in, then asked to verify their email if the panel requires it. */
667
664
  export declare class Register extends SimplePage {
668
665
  static callable: string[];
669
666
  data: Record<string, unknown>;
@@ -673,13 +670,13 @@ export declare class Register extends SimplePage {
673
670
  getSubheading(): string | null;
674
671
  formSchema(schema: Schema): Schema;
675
672
  contentSchema(schema: Schema): Schema;
676
- /** Données validées, juste avant la création (ajouter une valeur, normaliser l'adresse…). */
673
+ /** Validated data, just before creation (add a value, normalize the email…). */
677
674
  protected mutateFormDataBeforeRegister(data: Record<string, unknown>): Record<string, unknown> | Promise<Record<string, unknown>>;
678
- /** Création de l'utilisateur : par défaut `create()` du fournisseur d'utilisateurs. */
675
+ /** Creates the user; defaults to the auth provider's `create()`. */
679
676
  protected handleRegistration(data: Record<string, unknown>): Promise<User> | User;
680
677
  register(): Promise<void>;
681
678
  }
682
- /** Demande de réinitialisation du mot de passe (port de RequestPasswordReset) : un lien signé, valable 60 minutes, part par e-mail. */
679
+ /** Password reset request page: a signed link, valid for 60 minutes, is sent by email. */
683
680
  export declare class RequestPasswordReset extends SimplePage {
684
681
  static callable: string[];
685
682
  data: Record<string, unknown>;
@@ -691,7 +688,7 @@ export declare class RequestPasswordReset extends SimplePage {
691
688
  contentSchema(schema: Schema): Schema;
692
689
  request(): Promise<void>;
693
690
  }
694
- /** Nouveau mot de passe, depuis le lien reçu par e-mail (port de ResetPassword). Le lien ne sert qu'une fois : il meurt avec l'ancien mot de passe. */
691
+ /** Sets a new password from the emailed link. The link works once: it dies with the old password. */
695
692
  export declare class ResetPassword extends SimplePage {
696
693
  static callable: string[];
697
694
  static locked: string[];
@@ -700,7 +697,7 @@ export declare class ResetPassword extends SimplePage {
700
697
  passwordConfirmation: string;
701
698
  token: string | null;
702
699
  mount(params: Record<string, unknown>): void;
703
- /** Comme Filament : le formulaire n'a pas de chemin d'état, ses champs sont des propriétés de la page. */
700
+ /** The form has no state path: its fields are page properties. */
704
701
  getSchema(name: string): Schema;
705
702
  getTitle(): string;
706
703
  getHeading(): string;
@@ -708,17 +705,17 @@ export declare class ResetPassword extends SimplePage {
708
705
  contentSchema(schema: Schema): Schema;
709
706
  resetPassword(): Promise<void>;
710
707
  }
711
- /** Invitation à vérifier son adresse (port de EmailVerificationPrompt), avec le lien « Resend it. ». */
708
+ /** Email verification prompt, with a "Resend it." link. */
712
709
  export declare class EmailVerificationPrompt extends SimplePage {
713
710
  static callable: string[];
714
711
  mount(): Promise<void>;
715
712
  getTitle(): string;
716
713
  getHeading(): string;
717
714
  contentSchema(schema: Schema): Schema;
718
- /** Seule action de la page : renvoyer l'e-mail (deux fois par minute au plus). */
715
+ /** The page's only action: resend the email (at most twice per minute). */
719
716
  mountAction(name: unknown): Promise<void>;
720
717
  }
721
- /** Profil de l'utilisateur (port de EditProfile) : nom, adresse, nouveau mot de passe ; le mot de passe actuel est exigé pour changer l'adresse ou le mot de passe. */
718
+ /** User profile page: name, email, new password. The current password is required to change the email or password. */
722
719
  export declare class EditProfile extends SimplePage {
723
720
  static callable: string[];
724
721
  static slug: string;
@@ -732,13 +729,13 @@ export declare class EditProfile extends SimplePage {
732
729
  contentSchema(schema: Schema): Schema;
733
730
  save(): Promise<void>;
734
731
  }
735
- /** Création d'un locataire (port de RegisterTenant) : la sous-classe donne son libellé et son formulaire (`formSchema`). */
732
+ /** Tenant registration page: the subclass provides its label and form (`formSchema`). */
736
733
  export declare abstract class RegisterTenant extends SimplePage {
737
734
  static callable: string[];
738
735
  static slug: string;
739
736
  data: Record<string, unknown>;
740
737
  static getLabel(): string;
741
- /** Le panel accepte-t-il la création ? Par défaut : si le fournisseur de locataires sait créer. */
738
+ /** Whether tenants can be created; by default, if the tenant provider implements `create`. */
742
739
  static canView(panel: Panel, _user: User): boolean | Promise<boolean>;
743
740
  boot(): Promise<void>;
744
741
  mount(): void;
@@ -750,7 +747,7 @@ export declare abstract class RegisterTenant extends SimplePage {
750
747
  protected handleRegistration(data: Record<string, unknown>): unknown;
751
748
  register(): Promise<void>;
752
749
  }
753
- /** Profil du locataire courant (port de EditTenantProfile), dans la mise en page complète. */
750
+ /** Current tenant's profile page, in the full layout. */
754
751
  export declare abstract class EditTenantProfile extends Page {
755
752
  static callable: string[];
756
753
  static slug: string;
@@ -775,9 +772,9 @@ export declare class Login extends SimplePage {
775
772
  contentSchema(schema: Schema): Schema;
776
773
  authenticate(): Promise<void>;
777
774
  }
778
- /** L'utilisateur du composant hôte a-t-il cette capacité sur la resource (ou le relation manager) du composant ? À utiliser dans `authorize()` de vos actions. */
775
+ /** Whether the host component's user has this ability on the component's resource (or relation manager). Use it in your actions' `authorize()`. */
779
776
  export declare const can: (livewire: unknown, ability: string, record?: unknown) => Promise<boolean> | boolean;
780
- /** Resource : un modèle, ses pages, sa table et sa navigation (port partiel de Filament\Resources\Resource). */
777
+ /** Resource: a model with its pages, table and navigation. */
781
778
  export declare abstract class Resource {
782
779
  static panel: Panel;
783
780
  static slug: string;
@@ -788,12 +785,12 @@ export declare abstract class Resource {
788
785
  static navigationSort: number;
789
786
  static navigationBadge: string | number | null;
790
787
  static adapter: DataAdapter;
791
- /** Dans un panel à locataires : les enregistrements sont-ils propres à chaque locataire ? (vrai par défaut, comme Filament) */
788
+ /** In a multi-tenant panel, whether records belong to each tenant (`true` by default). */
792
789
  static isScopedToTenant: boolean;
793
- /** Colonne du locataire pour cette resource (par défaut celle du panel : `panel.tenant(provider, { ownershipColumn })`). */
790
+ /** Tenant column for this resource (defaults to the panel's: `panel.tenant(provider, { ownershipColumn })`). */
794
791
  static tenantOwnershipColumn: string | null;
795
792
  /**
796
- * Pages de la resource, à remplacer par vos sous-classes pour en changer le comportement :
793
+ * Resource pages; replace them with your subclasses to change their behavior:
797
794
  * `static pages = { index: MyList, create: MyCreate, edit: MyEdit }`.
798
795
  */
799
796
  static pages: {
@@ -802,64 +799,64 @@ export declare abstract class Resource {
802
799
  edit?: typeof EditRecord;
803
800
  view?: typeof ViewRecord;
804
801
  };
805
- /** Page de consultation (`ViewRecord`) : vrai pour l'ajouter aux pages de la resource ; la ligne d'une table y mène alors, comme dans Filament. */
802
+ /** `true` adds a view page (`ViewRecord`) to the resource; table rows then link to it. */
806
803
  static hasViewPage: boolean;
807
- /** Qui peut faire quoi sur cette resource. Sans politique, tout utilisateur connecté peut tout. */
804
+ /** Who can do what on this resource. Without a policy, any signed-in user can do everything. */
808
805
  static policy: Policy | null;
809
- /** L'utilisateur a-t-il cette capacité (sur cet enregistrement, s'il y en a un) ? */
806
+ /** Whether the user has this ability (on this record, if any). */
810
807
  static can(ability: string, user: User | null, record?: unknown): Promise<boolean>;
811
- /** Widgets de la resource (équivalent de getWidgets()) : enregistrés comme composants. */
808
+ /** Resource widgets, registered as components. */
812
809
  static widgets: (typeof Widget)[];
813
- /** Widgets affichés au-dessus de la table de la page de liste (équivalent de ListRecords::getHeaderWidgets()). */
810
+ /** Widgets shown above the table on the list page. */
814
811
  static headerWidgets: (typeof Widget)[];
815
- /** Relation managers affichés sous le formulaire d'édition (équivalent de getRelations()). */
812
+ /** Relation managers shown below the edit form. */
816
813
  static relations: any[];
817
- /** Onglets de la page de liste (équivalent de ListRecords::getTabs()). */
814
+ /** Tabs of the list page. */
818
815
  static tabs(): Record<string, Tab>;
819
- /** Resource « simple » (équivalent de ManageRecords) : une seule page, création et édition en modales. */
816
+ /** Simple resource: a single page, with create and edit in modals. */
820
817
  static isSimple: boolean;
821
818
  static getPluralModelLabel(): string;
822
819
  static getTitleCasePluralModelLabel(): string;
823
820
  static getUrl(page?: string, record?: string | number): string;
824
- /** Pages d'enregistrements liés (port de ManageRelatedRecords) : `{ comments: ManagePostComments }` répond sous `<slug>/{record}/comments`. */
821
+ /** Related records pages: `{ comments: ManagePostComments }` is served at `<slug>/{record}/comments`. */
825
822
  static relatedPages: Record<string, typeof ManageRelatedRecords>;
826
- /** Pages proposées dans la sous-navigation d'un enregistrement, dans l'ordre : `['view', 'edit', 'comments']`. Vide : pas de sous-navigation. */
823
+ /** Pages listed in a record's sub-navigation, in order: `['view', 'edit', 'comments']`. Empty: no sub-navigation. */
827
824
  static recordSubNavigation: string[];
828
- /** Port de getRecordSubNavigation() + generateNavigationItems() : un onglet par page déclarée, celui de la page courante actif. */
825
+ /** Record sub-navigation: one tab per declared page, the current page's tab active. */
829
826
  static getRecordSubNavigation(page: {
830
827
  getRecordKey(): string | null;
831
828
  constructor: Function;
832
829
  }): SubNavigationItem[];
833
830
  private static _registered;
834
- /** Classe de page réellement enregistrée pour un nom (les pages sont générées une seule fois par resource). */
831
+ /** Page class actually registered under a name (pages are generated once per resource). */
835
832
  static getRegisteredPage(name: string): typeof Page | undefined;
836
833
  static table(table: Table): Table;
837
834
  static form(schema: Schema): Schema;
838
- /** Schéma de la page de consultation (équivalent de `infolist()`). */
835
+ /** Schema of the view page. */
839
836
  static infolist(schema: Schema): Schema;
840
- /** Colonnes interrogées par la recherche globale ; par défaut, l'attribut de titre. Tableau vide : resource non cherchable. */
837
+ /** Columns searched by global search; defaults to the title attribute. Empty array: the resource is not searchable. */
841
838
  static globallySearchableAttributes: string[] | null;
842
839
  static getGloballySearchableAttributes(): string[];
843
840
  static canGloballySearch(): boolean;
844
- /** Rang du groupe de cette resource dans les résultats (`$globalSearchSort`) ; sans rang : après les autres, dans l'ordre d'enregistrement. */
841
+ /** Position of this resource's group in the results; without one, after the others in registration order. */
845
842
  static globalSearchSort: number | null;
846
- /** Nombre de résultats rendus par resource (50, comme Filament). */
843
+ /** Maximum results rendered per resource. */
847
844
  static globalSearchResultsLimit: number;
848
845
  static getGlobalSearchResultTitle(record: any): string;
849
- /** Précisions affichées sous le titre : `{ Author: 'Jane' }`. Les valeurs vides sont écartées. */
846
+ /** Details shown under the title: `{ Author: 'Jane' }`. Empty values are skipped. */
850
847
  static getGlobalSearchResultDetails(_record: any): Record<string, unknown> | Promise<Record<string, unknown>>;
851
- /** Adresse d'un résultat : page « View », sinon édition ; pour une resource simple, la liste avec l'action ouverte. Nul si l'utilisateur n'a aucun accès. */
848
+ /** URL of a result: the view page, otherwise the edit page; for a simple resource, the list with the action open. `null` if the user has no access. */
852
849
  static getGlobalSearchResultUrl(record: any, user: User | null): Promise<string | null>;
853
850
  static getGlobalSearchResults(search: string, user: User | null): Promise<GlobalSearchResult[]>;
854
- /** Attribut affiché comme titre d'un enregistrement (`$recordTitleAttribute`). */
851
+ /** Attribute used as a record's title. */
855
852
  static recordTitleAttribute: string | null;
856
- /** Sans attribut de titre : le libellé du modèle, en capitales initiales (« Leave Request »), comme Filament. */
853
+ /** Without a title attribute: the model label in title case ("Leave Request"). */
857
854
  static getRecordTitle(record: any): string;
858
- /** Pages de la resource, générées : liste, création, édition. */
855
+ /** Generated resource pages: list, create, edit. */
859
856
  static getPages(): Record<string, typeof Page>;
860
857
  private static buildPages;
861
858
  }
862
- /** Onglet de sous-navigation d'une page. */
859
+ /** Sub-navigation tab of a page. */
863
860
  export type SubNavigationItem = {
864
861
  label: string;
865
862
  icon: string | null;
@@ -867,85 +864,85 @@ export type SubNavigationItem = {
867
864
  active: boolean;
868
865
  };
869
866
  type ColumnSpan = number | 'full';
870
- /** Widget : composant affiché dans une grille de page (port de Filament\Widgets\Widget). */
867
+ /** Widget: a component displayed in a page's widget grid. */
871
868
  export declare abstract class Widget extends Component {
872
869
  static componentName: string;
873
- /** Largeur dans la grille de widgets : un nombre de colonnes, ou `'full'`. */
870
+ /** Width in the widget grid: a number of columns, or `'full'`. */
874
871
  static columnSpan: ColumnSpan;
875
- /** Chargé quand il devient visible (comme `$isLazy`). */
872
+ /** Loaded when it becomes visible. */
876
873
  static isLazy: boolean;
877
874
  get panel(): Panel;
878
- /** Widget réservé à certains utilisateurs : rendre `false` le retire de la page et refuse son chargement. */
875
+ /** Restricts the widget to some users: returning `false` removes it from the page and refuses to load it. */
879
876
  static canView(_user: User): boolean | Promise<boolean>;
880
877
  boot(): Promise<void>;
881
- /** Classes et style de colonne de grille, au point de rupture `lg` comme Filament. */
878
+ /** Grid column classes and style, at the `lg` breakpoint. */
882
879
  protected gridColumn(): {
883
880
  classes: string[];
884
881
  style: string;
885
882
  };
886
883
  placeholder(): string;
887
- /** Enveloppe commune (port de filament-widgets::components.widget). */
884
+ /** Common widget wrapper. */
888
885
  protected wrap(content: string, classes?: string[]): string;
889
886
  }
890
887
  /**
891
- * Calendrier (propre à Navette) : vues mois, semaine et liste, navigation rendue par le serveur, sans bibliothèque JavaScript.
888
+ * Calendar widget: month, week and list views, server-rendered navigation, no JavaScript library.
892
889
  *
893
- * Le minimum : étendre la classe et rendre les événements de la période affichée.
890
+ * Minimal use: extend the class and return the events of the displayed period.
894
891
  *
895
892
  * class LeaveCalendar extends CalendarWidget {
896
893
  * static heading = 'Leave';
897
894
  * async getEvents({ start, end }) { return [{ id: 1, title: 'Ada — vacation', start: '2026-11-12', end: '2026-11-14', color: 'success' }]; }
898
895
  * }
899
896
  *
900
- * Tout le reste se redéfinit méthode par méthode : vues proposées, premier jour de la semaine, langue, libellés, nombre
901
- * d'événements par case, réaction au clic sur un jour (`onDateClick`) ou sur un événement (`onEventClick`), rendu d'un
902
- * événement (`renderEvent`), pied de case (`renderDayFooter`), boutons de la barre d'outils (`renderToolbarEnd`), et
903
- * l'apparence par les variables CSS de `.nv-cal` (`getExtraClasses`, `getStyle`).
897
+ * Everything else can be overridden method by method: available views, first day of the week, locale, labels, events
898
+ * per cell, day clicks (`onDateClick`) and event clicks (`onEventClick`), event rendering (`renderEvent`), cell footer
899
+ * (`renderDayFooter`), toolbar buttons (`renderToolbarEnd`), and appearance through the `.nv-cal` CSS variables
900
+ * (`getExtraClasses`, `getStyle`).
904
901
  */
905
902
  export declare abstract class CalendarWidget extends Widget {
906
903
  static columnSpan: ColumnSpan;
907
- /** Titre affiché avant la période (« Leave — November 2026 »). */
904
+ /** Heading shown before the period ("Leave — November 2026"). */
908
905
  static heading: string | null;
909
906
  static callable: string[];
910
- /** La vue et la date ne changent que par les méthodes ci-dessous, qui les valident. */
907
+ /** View and date only change through the methods below, which validate them. */
911
908
  static locked: string[];
912
909
  view: CalendarView;
913
- /** Date d'ancrage (`YYYY-MM-DD`) : le mois ou la semaine affichés la contiennent. Vide : aujourd'hui. */
910
+ /** Anchor date (`YYYY-MM-DD`): the displayed month or week contains it. Empty: today. */
914
911
  date: string;
915
- /** Événements dont une partie tombe entre `start` et `end` (inclus, `YYYY-MM-DD`). Appelée à chaque rendu : filtrez en base. */
912
+ /** Events overlapping `start`–`end` (inclusive, `YYYY-MM-DD`). Called on every render: filter in the database. */
916
913
  abstract getEvents(range: {
917
914
  start: string;
918
915
  end: string;
919
916
  view: CalendarView;
920
917
  }): CalendarEvent[] | Promise<CalendarEvent[]>;
921
- /** Vues proposées, la première étant celle d'arrivée. Une seule vue : le sélecteur disparaît. */
918
+ /** Available views; the first is the initial one. With a single view, the switcher is hidden. */
922
919
  getViews(): CalendarView[];
923
- /** 0 = dimanche, 1 = lundi… */
920
+ /** 0 = Sunday, 1 = Monday… */
924
921
  getFirstDayOfWeek(): number;
925
- /** Langue des noms de mois et de jours (`Intl`). */
922
+ /** Locale for month and day names (`Intl`). */
926
923
  getLocale(): string;
927
924
  getLabels(): CalendarLabels;
928
- /** En vue mois, au-delà de ce nombre, la case affiche « +N more » (qui ouvre la liste sur ce jour). */
925
+ /** In month view, beyond this number the cell shows "+N more" (which opens the list on that day). */
929
926
  getMaxEventsPerDay(): number;
930
927
  getHeading(): string | null;
931
- /** Date du jour, `YYYY-MM-DD` (UTC par défaut ; à redéfinir pour un autre fuseau). */
928
+ /** Today's date, `YYYY-MM-DD` (UTC by default; override for another time zone). */
932
929
  getToday(): string;
933
- /** Clic sur un numéro de jour. Redéfinir cette méthode rend les jours cliquables : ouvrir une page (`this.redirect`), notifier, changer de vue… */
930
+ /** Click on a day number. Overriding this makes days clickable: open a page (`this.redirect`), notify, switch view… */
934
931
  onDateClick(_date: string): void | Promise<void>;
935
- /** Clic sur un événement sans adresse. L'événement est relu côté serveur : `event.extra` est disponible. */
932
+ /** Click on an event without a URL. The event is reloaded server-side, so `event.extra` is available. */
936
933
  onEventClick(_event: CalendarEvent): void | Promise<void>;
937
- /** HTML d'un événement (déjà échappé), ou `null` pour le rendu par défaut (`renderCalendarEvent`). */
934
+ /** Already-escaped HTML for an event, or `null` for the default rendering (`renderCalendarEvent`). */
938
935
  renderEvent(_event: CalendarEvent, _context: {
939
936
  day: string;
940
937
  view: CalendarView;
941
938
  }): string | null;
942
- /** HTML ajouté au bas de chaque case (déjà échappé). */
939
+ /** Already-escaped HTML appended to the bottom of each cell. */
943
940
  renderDayFooter(_day: string, _events: CalendarEvent[]): string;
944
- /** HTML placé à droite de la barre d'outils (déjà échappé) : un lien « New », un filtre… */
941
+ /** Already-escaped HTML at the end of the toolbar: a "New" link, a filter… */
945
942
  renderToolbarEnd(): string;
946
- /** Classes ajoutées au calendrier, pour y accrocher vos styles ou redéfinir ses variables CSS. */
943
+ /** Extra classes on the calendar, to hook your styles or override its CSS variables. */
947
944
  getExtraClasses(): string[];
948
- /** Variables CSS posées sur le calendrier : `{ '--nv-cal-day-min-height': '9rem' }`. */
945
+ /** CSS variables set on the calendar: `{ '--nv-cal-day-min-height': '9rem' }`. */
949
946
  getStyle(): Record<string, string>;
950
947
  private anchor;
951
948
  private currentView;
@@ -954,30 +951,30 @@ export declare abstract class CalendarWidget extends Widget {
954
951
  nextPeriod(): void;
955
952
  goToToday(): void;
956
953
  setView(view: unknown): void;
957
- /** « +N more » : la liste, ancrée sur ce jour (ou la semaine si la liste n'est pas proposée). */
954
+ /** "+N more": the list view anchored on that day (or the week view if list is not available). */
958
955
  showDay(date: unknown): void;
959
956
  private datesClickable;
960
957
  private eventsClickable;
961
958
  selectDate(date: unknown): Promise<void>;
962
- /** L'identifiant vient du navigateur : l'événement est recherché parmi ceux de la période affichée, jamais cru sur parole. */
959
+ /** The id comes from the browser: the event is looked up among those of the displayed period, never trusted as-is. */
963
960
  selectEvent(id: unknown): Promise<void>;
964
961
  render(): Promise<string>;
965
962
  }
966
963
  /**
967
- * Page calendrier (propre à Navette) : le même calendrier que `CalendarWidget`, sur une page entière, avec les actions de
968
- * Filament — donc des modales, des formulaires, des confirmations, des panneaux latéraux.
964
+ * Calendar page: the same calendar as `CalendarWidget`, on a full page, with actions — so modals, forms,
965
+ * confirmations and slide-overs.
969
966
  *
970
967
  * class Planning extends CalendarPage {
971
968
  * static slug = 'planning';
972
969
  * async getEvents({ start, end }) { return db('shifts').where('day', '>=', start).where('day', '<=', end)… }
973
- * // Clic sur un jour : une modale avec un formulaire, prérempli avec la date.
970
+ * // Day click: a modal with a form, prefilled with the date.
974
971
  * dateAction() {
975
972
  * return Action.make('createShift').modalHeading('New shift')
976
973
  * .schema([Select.make('employee_id').options(…).required(), DatePicker.make('day').required()])
977
974
  * .fillForm(({ arguments: args }) => ({ day: CalendarPage.dateOf(args) }))
978
975
  * .action(async ({ data }) => { await db('shifts').insert(data); Notification.make().success().title('Saved').send(); });
979
976
  * }
980
- * // Clic sur un événement : une autre action ; l'événement est relu côté serveur.
977
+ * // Event click: another action; the event is reloaded server-side.
981
978
  * eventAction() {
982
979
  * return Action.make('editShift').schema([…])
983
980
  * .fillForm(async ({ livewire, arguments: args }) => (await livewire.findEvent(args.event))?.extra ?? {})
@@ -985,10 +982,10 @@ export declare abstract class CalendarWidget extends Widget {
985
982
  * }
986
983
  * }
987
984
  *
988
- * Trois façons de réagir à un clic, au choix : une **adresse** sur l'événement (`url` : page dédiée), une **action** (modale),
989
- * ou du **code libre** en redéfinissant `onDateClick()` / `onEventClick()` (rediriger, notifier, écrire en base, monter l'action
990
- * de son choix avec `this.mountAction(nom, arguments)`). `getHeaderActions()` ajoute des boutons en tête de page, et
991
- * `getCalendarActions()` déclare d'autres actions montables depuis votre propre rendu (`renderEvent`, `renderToolbarEnd`).
985
+ * Three ways to handle a click: a **URL** on the event (`url`: dedicated page), an **action** (modal),
986
+ * or **custom code** by overriding `onDateClick()` / `onEventClick()` (redirect, notify, write to the database, mount any
987
+ * action with `this.mountAction(name, arguments)`). `getHeaderActions()` adds buttons to the page header, and
988
+ * `getCalendarActions()` declares other actions mountable from your own rendering (`renderEvent`, `renderToolbarEnd`).
992
989
  */
993
990
  export declare abstract class CalendarPage extends Page {
994
991
  static callable: string[];
@@ -1015,19 +1012,19 @@ export declare abstract class CalendarPage extends Page {
1015
1012
  renderToolbarEnd(): string;
1016
1013
  getExtraClasses(): string[];
1017
1014
  getStyle(): Record<string, string>;
1018
- /** Action ouverte au clic sur un jour ; elle reçoit `arguments.date`. Nul : les jours ne sont pas cliquables (sauf `onDateClick` redéfini). */
1015
+ /** Action opened on day click; it receives `arguments.date`. `null`: days are not clickable (unless `onDateClick` is overridden). */
1019
1016
  dateAction(): Action | null;
1020
- /** Action ouverte au clic sur un événement sans adresse ; elle reçoit `arguments.event` (identifiant, à relire avec `findEvent`). */
1017
+ /** Action opened on click on an event without a URL; it receives `arguments.event` (an id, to resolve with `findEvent`). */
1021
1018
  eventAction(): Action | null;
1022
- /** Autres actions montables depuis votre propre HTML : `wire:click="mountAction('nom', { … })"`. */
1019
+ /** Other actions mountable from your own HTML: `wire:click="mountAction('name', { … })"`. */
1023
1020
  getCalendarActions(): Action[];
1024
- /** Par défaut : ouvre `dateAction()`. À redéfinir pour faire autre chose (rediriger vers une page de création, par exemple). */
1021
+ /** Opens `dateAction()` by default. Override to do something else (e.g. redirect to a create page). */
1025
1022
  onDateClick(date: string): Promise<void>;
1026
- /** Par défaut : ouvre `eventAction()`. L'événement a été retrouvé côté serveur avant l'appel. */
1023
+ /** Opens `eventAction()` by default. The event has been resolved server-side before the call. */
1027
1024
  onEventClick(event: CalendarEvent): Promise<void>;
1028
- /** Date d'un clic, relue dans les arguments d'une action : ils viennent du navigateur, seule une vraie date est rendue. */
1025
+ /** Clicked date, read from an action's arguments. They come from the browser: only a valid date is returned. */
1029
1026
  static dateOf(args: Record<string, unknown> | null | undefined): string | null;
1030
- /** Événement de la période affichée portant cet identifiant, ou nul : ne jamais agir sur un identifiant reçu sans passer par ici. */
1027
+ /** Event of the displayed period with this id, or `null`. Never act on a received id without going through this. */
1031
1028
  findEvent(id: unknown): Promise<CalendarEvent | null>;
1032
1029
  protected getMountableActions(context: Record<string, unknown>): Promise<Action[]>;
1033
1030
  private firstDay;
@@ -1045,12 +1042,12 @@ export declare abstract class CalendarPage extends Page {
1045
1042
  selectEvent(id: unknown): Promise<void>;
1046
1043
  protected renderContent(): Promise<string>;
1047
1044
  }
1048
- /** Compte de l'utilisateur connecté : avatar, nom, déconnexion (port de Filament\Widgets\AccountWidget). */
1045
+ /** Signed-in user's account: avatar, name, logout. */
1049
1046
  export declare class AccountWidget extends Widget {
1050
1047
  static isLazy: boolean;
1051
1048
  render(): string;
1052
1049
  }
1053
- /** Version de Navette et liens utiles (pendant de Filament\Widgets\FilamentInfoWidget, dont il reprend le balisage et les classes). */
1050
+ /** Navette version and useful links. */
1054
1051
  export declare class NavetteInfoWidget extends Widget {
1055
1052
  static isLazy: boolean;
1056
1053
  static homeUrl: string;
@@ -1059,7 +1056,7 @@ export declare class NavetteInfoWidget extends Widget {
1059
1056
  static version: string;
1060
1057
  render(): string;
1061
1058
  }
1062
- /** Une statistique d'un StatsOverviewWidget (port de Stat). */
1059
+ /** One stat of a StatsOverviewWidget. */
1063
1060
  export declare class Stat {
1064
1061
  private _description;
1065
1062
  private _descriptionIcon;
@@ -1074,79 +1071,79 @@ export declare class Stat {
1074
1071
  static make(label: string, value: string | number | null): Stat;
1075
1072
  description(text: string | null): this;
1076
1073
  descriptionIcon(name: string | null, position?: 'before' | 'after'): this;
1077
- /** Couleur de la description et de la courbe. */
1074
+ /** Color of the description and chart. */
1078
1075
  color(color: string | null): this;
1079
1076
  icon(name: string | null): this;
1080
- /** Courbe de tendance : une liste de valeurs, ou des valeurs par libellé. */
1077
+ /** Trend chart: a list of values, or values keyed by label. */
1081
1078
  chart(values: Record<string, number> | number[] | null): this;
1082
1079
  url(url: string | null): this;
1083
1080
  hasChart(): boolean;
1084
1081
  toHtml(panel: Panel, key: string): string;
1085
1082
  }
1086
- /** Rangée de statistiques (port de StatsOverviewWidget). */
1083
+ /** A row of stats. */
1087
1084
  export declare abstract class StatsOverviewWidget extends Widget {
1088
1085
  static columnSpan: ColumnSpan;
1089
- /** Intervalle de rafraîchissement (`'5s'` dans Filament par défaut), ou null pour ne pas rafraîchir. */
1086
+ /** Polling interval, or `null` to disable polling. */
1090
1087
  static pollingInterval: string | null;
1091
1088
  abstract getStats(): Stat[] | Promise<Stat[]>;
1092
- /** Colonnes de la rangée : comme Filament, trois, ou quatre quand le nombre de statistiques s'y prête. */
1089
+ /** Row columns: three, or four when the number of stats fits better. */
1093
1090
  protected getColumns(count: number): number;
1094
1091
  render(): Promise<string>;
1095
1092
  }
1096
- /** Données d'un graphique, au format de Chart.js : `{ datasets: [{ label, data, … }], labels: [...] }`. */
1093
+ /** Chart data in Chart.js format: `{ datasets: [{ label, data, … }], labels: [...] }`. */
1097
1094
  export type ChartData = {
1098
1095
  datasets?: Record<string, unknown>[];
1099
1096
  labels?: unknown[];
1100
1097
  [key: string]: unknown;
1101
1098
  };
1102
1099
  /**
1103
- * Graphique Chart.js (port de Filament\Widgets\ChartWidget). Une sous-classe donne `getType()` (`'line'`, `'bar'`, `'pie'`,
1104
- * `'doughnut'`, `'radar'`, `'polarArea'`, `'scatter'`, `'bubble'`) et `getData()`. Le rendu est fait dans le navigateur par le
1105
- * composant `chart.js` de Filament ; le serveur n'envoie de nouvelles données que si elles ont changé (somme de contrôle).
1100
+ * Chart.js chart. A subclass provides `getType()` (`'line'`, `'bar'`, `'pie'`, `'doughnut'`, `'radar'`, `'polarArea'`,
1101
+ * `'scatter'`, `'bubble'`) and `getData()`. Rendering happens in the browser; the server only sends new data when it
1102
+ * has changed (checksum).
1106
1103
  */
1107
1104
  export declare abstract class ChartWidget extends Widget {
1108
1105
  static callable: string[];
1109
1106
  static locked: string[];
1110
- /** Intervalle de rafraîchissement (`'5s'` par défaut dans Filament), ou null pour ne pas rafraîchir. */
1107
+ /** Polling interval, or `null` to disable polling. */
1111
1108
  static pollingInterval: string | null;
1112
1109
  static heading: string | null;
1113
1110
  static description: string | null;
1114
- /** Couleur des séries qui n'en précisent pas. */
1111
+ /** Color of datasets that do not set one. */
1115
1112
  static color: string;
1116
- /** Hauteur maximale du graphique (`'300px'`). */
1113
+ /** Maximum chart height (`'300px'`). */
1117
1114
  static maxHeight: string | null;
1118
1115
  static isCollapsible: boolean;
1119
1116
  dataChecksum: string | null;
1120
- /** Filtre choisi, parmi `getFilters()`. */
1117
+ /** Selected filter, one of `getFilters()`. */
1121
1118
  filter: string | null;
1122
1119
  private _cachedData;
1123
1120
  abstract getType(): string;
1124
1121
  getData(): ChartData | Promise<ChartData>;
1125
- /** Options de Chart.js. */
1122
+ /** Chart.js options. */
1126
1123
  getOptions(): Record<string, unknown> | null;
1127
- /** Filtres proposés dans l'en-tête : valeur vers libellé. */
1124
+ /** Filters offered in the header: value → label. */
1128
1125
  getFilters(): Record<string, string> | null;
1129
1126
  getHeading(): string | null;
1130
1127
  getDescription(): string | null;
1131
1128
  getColor(): string;
1132
1129
  getMaxHeight(): string | null;
1133
- /** Texte lu par les lecteurs d'écran à la place du graphique. */
1130
+ /** Text read by screen readers instead of the chart. */
1134
1131
  getChartAssistiveContent(): string | null;
1135
1132
  protected getCachedData(): Promise<ChartData>;
1136
1133
  protected generateDataChecksum(): Promise<string>;
1137
1134
  mount(): Promise<void>;
1138
- /** Appelé par le rafraîchissement périodique et avant chaque rendu : n'émet les données que si elles ont changé. */
1135
+ /** Called by polling and before each render: only emits data when it has changed. */
1139
1136
  updateChartData(): Promise<void>;
1140
1137
  render(): Promise<string>;
1141
1138
  }
1142
1139
  /**
1143
- * Table dans un widget (port de Filament\Widgets\TableWidget) : recherche, tri, pagination simple (précédent / suivant).
1144
- * Une sous-classe donne `table(table)` et `getDataAdapterForTable()`. Pas d'actions ni de filtres pour l'instant.
1140
+ * Table in a widget: search, sort, simple pagination (previous / next).
1141
+ * A subclass provides `table(table)` and `getDataAdapterForTable()`. No actions or filters yet.
1145
1142
  */
1146
1143
  export declare abstract class TableWidget extends Widget implements TableHost {
1147
1144
  static columnSpan: ColumnSpan;
1148
1145
  static callable: string[];
1149
- /** Titre de la table ; par défaut tiré du nom de la classe (`FlaggedOrders` : « Flagged Orders »). */
1146
+ /** Table heading; derived from the class name by default (`FlaggedOrders` → "Flagged Orders"). */
1150
1147
  static heading: string | null;
1151
1148
  tableSearch: string;
1152
1149
  tableSort: string | null;
@@ -1172,14 +1169,14 @@ export declare abstract class TableWidget extends Widget implements TableHost {
1172
1169
  updatedTableSort(): void;
1173
1170
  render(): Promise<string>;
1174
1171
  }
1175
- /** Widgets qui reçoivent les filtres du tableau de bord (port de InteractsWithPageFilters) : `static reactive = PAGE_FILTERS` et une propriété `pageFilters`. */
1172
+ /** For widgets that receive the dashboard filters: `static reactive = PAGE_FILTERS` plus a `pageFilters` property. */
1176
1173
  export declare const PAGE_FILTERS: string[];
1177
1174
  /**
1178
- * Widget de statistiques lié à la table d'une page de liste (port de InteractsWithPageTable) : il reçoit l'état de la table
1179
- * (recherche, filtres, onglet…) et peut agréger exactement les enregistrements qu'elle affiche.
1175
+ * Stats widget bound to a list page's table: it receives the table state (search, filters, tab…)
1176
+ * and can aggregate exactly the records the table displays.
1180
1177
  */
1181
1178
  export declare abstract class PageTableStatsWidget extends StatsOverviewWidget {
1182
- /** Page de liste dont la table est observée (équivalent de getTablePage()). */
1179
+ /** List page whose table is observed. */
1183
1180
  static tablePage: () => typeof ListRecords;
1184
1181
  static reactive: string[];
1185
1182
  activeTab: string | null;
@@ -1189,7 +1186,7 @@ export declare abstract class PageTableStatsWidget extends StatsOverviewWidget {
1189
1186
  tableRecordsPerPage: number;
1190
1187
  tableSearch: string;
1191
1188
  tableSort: string | null;
1192
- /** Agrégats sur la requête courante de la table. L'état reçu passe par la même validation que sur la page. */
1189
+ /** Aggregates over the table's current query. The received state goes through the same validation as on the page. */
1193
1190
  protected aggregatePageTable(columns?: {
1194
1191
  sum?: string[];
1195
1192
  avg?: string[];
@@ -1198,7 +1195,7 @@ export declare abstract class PageTableStatsWidget extends StatsOverviewWidget {
1198
1195
  sum: Record<string, number>;
1199
1196
  avg: Record<string, number>;
1200
1197
  }>;
1201
- /** Tendance mensuelle sur la requête courante de la table (voir `ObjectionAdapter.trendPerMonth`). */
1198
+ /** Monthly trend over the table's current query (see `ObjectionAdapter.trendPerMonth`). */
1202
1199
  protected trendPageTable(options: {
1203
1200
  start: Date;
1204
1201
  end: Date;
@@ -1207,12 +1204,12 @@ export declare abstract class PageTableStatsWidget extends StatsOverviewWidget {
1207
1204
  modify?: (query: any) => void;
1208
1205
  }): Promise<number[]>;
1209
1206
  }
1210
- /** Composant de schéma qui intègre la table du composant hôte (port de EmbeddedTable). */
1207
+ /** Schema component that embeds the host component's table. */
1211
1208
  export declare class EmbeddedTable extends SchemaComponent {
1212
1209
  static make(): EmbeddedTable;
1213
1210
  toHtml(): Promise<string>;
1214
1211
  }
1215
- /** Onglet d'une page de liste : restreint la requête de la table et peut afficher un compteur (port de Tab). */
1212
+ /** List page tab: restricts the table query and can show a badge. */
1216
1213
  export declare class Tab {
1217
1214
  private _label;
1218
1215
  private _badge;
@@ -1221,7 +1218,7 @@ export declare class Tab {
1221
1218
  private _query;
1222
1219
  constructor(label?: string | null);
1223
1220
  static make(label?: string | null): Tab;
1224
- /** Compteur, calculé après l'affichage de la page (comme `lazyLoadedBadge()`). */
1221
+ /** Badge computed after the page is displayed. */
1225
1222
  badge(resolver: () => number | string | null | Promise<number | string | null>): this;
1226
1223
  badgeColor(color: string): this;
1227
1224
  query(modifier: (query: any) => void): this;
@@ -1229,11 +1226,11 @@ export declare class Tab {
1229
1226
  hasBadge(): boolean;
1230
1227
  getBadge(): Promise<number | string | null>;
1231
1228
  getBadgeColor(): string;
1232
- /** Faux tant que `badgeColor()` n'a pas été appelé : un badge chargé après coup ne reçoit alors aucune classe de couleur, comme dans Filament. */
1229
+ /** False until `badgeColor()` is called: a lazy-loaded badge then gets no color class. */
1233
1230
  hasBadgeColor(): boolean;
1234
1231
  getQuery(): ((query: any) => void) | null;
1235
1232
  }
1236
- /** Page de liste d'une resource : état de table et méthodes appelées par le navigateur (port de ListRecords + InteractsWithTable). */
1233
+ /** Resource list page: table state and methods called by the browser. */
1237
1234
  export declare class ListRecords extends Page implements TableHost {
1238
1235
  static callable: string[];
1239
1236
  static resource: typeof Resource;
@@ -1249,20 +1246,20 @@ export declare class ListRecords extends Page implements TableHost {
1249
1246
  tableDeferredFilters: Record<string, FilterState>;
1250
1247
  tableColumns: ColumnState[];
1251
1248
  isTableReordering: boolean;
1252
- /** Regroupement courant de la table (`identifiant:direction`), choisi dans la barre d'outils. */
1249
+ /** Current table grouping (`id:direction`), chosen in the toolbar. */
1253
1250
  tableGrouping: string | null;
1254
1251
  updatedTableGrouping(): void;
1255
- /** Entre dans le mode « tri manuel » ou en sort (port de toggleTableReordering). */
1252
+ /** Toggles manual reordering mode. */
1256
1253
  toggleTableReordering(): Promise<void>;
1257
- /** Enregistre le nouvel ordre : seules les clés de la table sont retenues, chacune reçoit son rang (port de reorderTable). */
1254
+ /** Saves the new order: only keys belonging to the table are kept, each gets its position. */
1258
1255
  reorderTable(order: unknown, _draggedRecordKey?: unknown): Promise<void>;
1259
1256
  mount(_params?: Record<string, unknown>): Promise<void>;
1260
- /** Formulaire des filtres : un groupe par filtre, lié à `tableDeferredFilters.<filtre>`. */
1257
+ /** Filters form: one group per filter, bound to `tableDeferredFilters.<filter>`. */
1261
1258
  tableFiltersFormSchema(schema: Schema): Schema;
1262
1259
  applyTableFilters(): void;
1263
- /** Retrait d'un indicateur de filtre actif : le champ visé est effacé de l'état appliqué et du formulaire. */
1260
+ /** Removes an active filter indicator: the field is cleared from both the applied state and the form. */
1264
1261
  removeTableFilter(filterName: unknown, field?: unknown): void;
1265
- /** Champ réactif du formulaire des filtres (changement d'opérateur d'une règle) : exécute son `afterStateUpdated`. */
1262
+ /** Live field in the filters form (e.g. a rule's operator changed): runs its `afterStateUpdated`. */
1266
1263
  updatedTableDeferredFilters(_value: unknown, key: string | null): Promise<void>;
1267
1264
  resetTableFiltersForm(): void;
1268
1265
  removeTableFilters(): void;
@@ -1270,7 +1267,7 @@ export declare class ListRecords extends Page implements TableHost {
1270
1267
  resetTableColumnManager(): void;
1271
1268
  activeTab: string | null;
1272
1269
  getTabs(): Record<string, Tab>;
1273
- /** Onglet actif, ramené à une clé déclarée (une valeur inconnue envoyée par le navigateur vaut l'onglet par défaut). */
1270
+ /** Active tab, coerced to a declared key (an unknown value from the browser means the default tab). */
1274
1271
  getActiveTabKey(): string;
1275
1272
  updatedActiveTab(): void;
1276
1273
  modifyTableQuery(query: {
@@ -1278,27 +1275,27 @@ export declare class ListRecords extends Page implements TableHost {
1278
1275
  }): void;
1279
1276
  get resource(): typeof Resource;
1280
1277
  getHeaderWidgets(): (typeof Widget)[];
1281
- /** Port de ExposesTableToWidgets : l'état de la table est passé aux widgets, qui peuvent refaire la même requête. */
1278
+ /** The table state is passed to widgets, which can rerun the same query. */
1282
1279
  getWidgetData(): Record<string, unknown>;
1283
1280
  protected rendersActionModalsInPage(): boolean;
1284
1281
  getBulkActions(): Action[];
1285
- /** Actions de ligne déclarées par la table, groupes dépliés. */
1282
+ /** Row actions declared by the table, with groups flattened. */
1286
1283
  getRecordActions(): Action[];
1287
1284
  protected getMountableActions(context: Record<string, unknown>): Action[] | Promise<Action[]>;
1288
- /** Seules les formes de contexte connues sont retenues ; la clé d'enregistrement est revérifiée en base au montage. */
1285
+ /** Only known context shapes are kept; the record key is checked again in the database on mount. */
1289
1286
  protected resolveMountContext(clientContext: unknown): Record<string, unknown>;
1290
1287
  protected resolveActionRecord(context: Record<string, unknown>): Promise<unknown>;
1291
1288
  /**
1292
- * Écriture d'une cellule modifiable (port de `updateTableColumnState`). Tout vient du navigateur : la colonne doit exister, être
1293
- * modifiable et visible, l'enregistrement être dans la portée de la table et modifiable par l'utilisateur, la valeur être valide.
1289
+ * Writes an editable cell. Everything comes from the browser: the column must exist and be editable and visible, the record
1290
+ * must be in the table's scope and editable by the user, and the value must be valid.
1294
1291
  */
1295
1292
  updateTableColumnState(columnName: unknown, recordKey: unknown, input: unknown): Promise<unknown>;
1296
- /** Clés sélectionnées : la liste envoyée, ou — en mode « tout sélectionner » — tous les enregistrements de la requête courante sauf ceux désélectionnés. */
1293
+ /** Selected keys: the sent list, or, in "select all" mode, every record of the current query except deselected ones. */
1297
1294
  getSelectedRecordKeys(): Promise<string[]>;
1298
1295
  deselectAllTableRecords(): void;
1299
1296
  getTable(): Table;
1300
1297
  renderTable(): Promise<string>;
1301
- /** Actions affichées dans l'en-tête de la table (aucune pour une page de liste : elles sont dans l'en-tête de page). */
1298
+ /** Table header actions (none on a list page: they go in the page header). */
1302
1299
  protected renderTableHeaderActions(ctx: any): Promise<string[]>;
1303
1300
  sortTable(column?: string | null, direction?: string | null): void;
1304
1301
  gotoPage(page: number, _pageName?: string): void;
@@ -1319,77 +1316,77 @@ export declare class ListRecords extends Page implements TableHost {
1319
1316
  contentSchema(schema: Schema): Schema;
1320
1317
  }
1321
1318
  /**
1322
- * Table des enregistrements liés à un autre (port de RelationManager) : composant enfant de la page d'édition, chargé quand il devient visible.
1323
- * Les sous-classes déclarent `relationship`, `adapterFor()`, `table()` et `form()`.
1319
+ * Table of records related to another one: a child component of the edit page, loaded when it becomes visible.
1320
+ * Subclasses declare `relationship`, `adapterFor()`, `table()` and `form()`.
1324
1321
  */
1325
1322
  export declare class RelationManager extends ListRecords {
1326
1323
  static relationship: string;
1327
1324
  static modelLabel: string;
1328
1325
  static pluralModelLabel: string | null;
1329
1326
  static recordTitleAttribute: string | null;
1330
- /** Adaptateur limité aux enregistrements liés au propriétaire donné. */
1327
+ /** Data adapter limited to records related to the given owner. */
1331
1328
  static adapterFor(_ownerKey: string): DataAdapter;
1332
- /** Politique des enregistrements liés (mêmes capacités que celle d'une resource). */
1329
+ /** Policy for related records (same abilities as a resource policy). */
1333
1330
  static policy: Policy | null;
1334
1331
  protected isAccessAuthorized(ctx: PanelContext): Promise<boolean>;
1335
1332
  static table(table: Table): Table;
1336
1333
  static form(schema: Schema): Schema;
1337
1334
  static getTitle(): string;
1338
- /** Clé de l'enregistrement propriétaire : fixée au montage par la page, jamais modifiable depuis le navigateur. */
1335
+ /** Owner record key: set on mount by the page, never writable from the browser. */
1339
1336
  ownerRecord: string;
1340
1337
  static locked: string[];
1341
1338
  _facade: any;
1342
- /** Ce que ListRecords attend d'une resource, fourni ici par le relation manager. */
1339
+ /** What ListRecords expects from a resource, provided here by the relation manager. */
1343
1340
  get resource(): any;
1344
1341
  getTable(): Table;
1345
- /** Rattache un enregistrement existant au propriétaire. */
1342
+ /** Attaches an existing record to the owner. */
1346
1343
  static attach(_ownerKey: string, _recordKey: string): Promise<void>;
1347
- /** Détache des enregistrements du propriétaire, sans les supprimer. */
1344
+ /** Detaches records from the owner without deleting them. */
1348
1345
  static detach(_ownerKey: string, _recordKeys: string[]): Promise<void>;
1349
- /** Enregistrements rattachables correspondant à la recherche : [clé, libellé]. */
1346
+ /** Attachable records matching the search: [key, label]. */
1350
1347
  static searchAttachable(_ownerKey: string, _search: string): Promise<[string, string][]>;
1351
- /** Libellé d'un enregistrement rattachable, ou null s'il ne l'est pas (sert aussi de validation). */
1348
+ /** Label of an attachable record, or `null` if it is not attachable (also used as validation). */
1352
1349
  static attachableLabel(_ownerKey: string, _recordKey: string): Promise<string | null>;
1353
1350
  getHeaderActions(): Action[];
1354
1351
  placeholder(): string;
1355
- /** Comme Filament : un relation manager a ses propres emplacements, pas ceux de la page de liste. */
1352
+ /** A relation manager has its own render hook locations, not the list page's. */
1356
1353
  contentSchema(schema: Schema): Schema;
1357
1354
  render(): Promise<string>;
1358
1355
  }
1359
1356
  /**
1360
- * Page des enregistrements liés à un enregistrement (port de ManageRelatedRecords) : une table, avec création, consultation et
1361
- * édition en modales. Déclarée par `static relatedPages` de la resource propriétaire, elle répond sous `<slug>/{record}/<nom>`.
1357
+ * Page listing records related to a record: a table, with create, view and edit in modals.
1358
+ * Declared in the owner resource's `static relatedPages`, it is served at `<slug>/{record}/<name>`.
1362
1359
  */
1363
1360
  export declare class ManageRelatedRecords extends ListRecords {
1364
- /** Resource propriétaire : fixée à l'enregistrement de la page. */
1361
+ /** Owner resource: set when the page is registered. */
1365
1362
  static parentResource: typeof Resource;
1366
1363
  static relationship: string;
1367
1364
  static modelLabel: string;
1368
1365
  static pluralModelLabel: string | null;
1369
1366
  static recordTitleAttribute: string | null;
1370
1367
  static policy: Policy | null;
1371
- /** Adaptateur limité aux enregistrements liés au propriétaire donné. */
1368
+ /** Data adapter limited to records related to the given owner. */
1372
1369
  static adapterFor(_ownerKey: string): DataAdapter;
1373
1370
  static table(table: Table): Table;
1374
1371
  static form(schema: Schema): Schema;
1375
1372
  static infolist(schema: Schema): Schema;
1376
1373
  static getTitle(): string;
1377
1374
  static getNavigationLabel(): string;
1378
- /** Clé de l'enregistrement propriétaire : tirée de l'adresse au montage, jamais modifiable depuis le navigateur. */
1375
+ /** Owner record key: read from the URL on mount, never writable from the browser. */
1379
1376
  recordKey: string;
1380
1377
  static locked: string[];
1381
1378
  _owner: any;
1382
1379
  _facade: any;
1383
1380
  private get related();
1384
1381
  mount(params: Record<string, unknown>): Promise<void>;
1385
- /** Le propriétaire est relu et son accès vérifié à chaque requête. */
1382
+ /** The owner is reloaded and access to it checked on every request. */
1386
1383
  hydrate(): Promise<void>;
1387
1384
  getRecordKey(): string | null;
1388
- /** Ce que ListRecords attend d'une resource, fourni ici par la page. */
1385
+ /** What ListRecords expects from a resource, provided here by the page. */
1389
1386
  get resource(): any;
1390
1387
  getTable(): Table;
1391
1388
  getHeaderActions(): Action[];
1392
- /** Comme Filament : le contenu de la page est un groupe (onglets éventuels, puis la table). */
1389
+ /** The page content is a group (tabs, if any, then the table). */
1393
1390
  contentSchema(schema: Schema): Schema;
1394
1391
  getTitle(): string;
1395
1392
  getSubNavigation(): SubNavigationItem[];
@@ -1399,9 +1396,9 @@ export declare class ManageRelatedRecords extends ListRecords {
1399
1396
  }[];
1400
1397
  getPageClasses(): string[];
1401
1398
  }
1402
- /** Base des pages à formulaire d'une resource. */
1399
+ /** Base class for a resource's form pages. */
1403
1400
  declare abstract class ResourceFormPage extends Page {
1404
- /** Champ réactif du formulaire (`live()` + `afterStateUpdated()`) : `set(nom, valeur)` écrit à côté du champ modifié. */
1401
+ /** Live form field (`live()` + `afterStateUpdated()`): `set(name, value)` writes next to the updated field. */
1405
1402
  updatedData(_value: unknown, key: string | null): Promise<void>;
1406
1403
  static resource: typeof Resource;
1407
1404
  data: Record<string, unknown>;
@@ -1412,26 +1409,26 @@ declare abstract class ResourceFormPage extends Page {
1412
1409
  abstract getSubmitMethod(): string;
1413
1410
  abstract getFormActions(): Action[];
1414
1411
  protected getRecord(): unknown;
1415
- /** Deux colonnes par défaut à partir de `lg`, comme `defaultForm()` de Filament ; la resource peut en décider autrement. */
1412
+ /** Two columns from `lg` by default; the resource may decide otherwise. */
1416
1413
  formSchema(schema: Schema): Schema;
1417
1414
  /**
1418
- * Étapes d'un assistant (équivalent du trait HasWizard de Filament) : dès que la méthode en retourne, la page présente son formulaire
1419
- * étape par étape, avec « Back » / « Next » et le bouton d'enregistrement sur la dernière étape.
1415
+ * Wizard steps: as soon as this method returns some, the page shows its form step by step,
1416
+ * with "Back" / "Next" and the submit button on the last step.
1420
1417
  */
1421
1418
  protected getSteps(): Step[] | null;
1422
- /** Vrai : les étapes sont accessibles dans n'importe quel ordre, sans validation au passage. */
1419
+ /** `true`: steps can be visited in any order, without validation along the way. */
1423
1420
  protected hasSkippableSteps(): boolean;
1424
- /** Étape affichée à l'ouverture (à partir de 1). */
1421
+ /** Step shown on open (1-based). */
1425
1422
  protected getStartStep(): number;
1426
1423
  protected getWizardComponent(steps: Step[]): Wizard;
1427
1424
  contentSchema(schema: Schema): Schema;
1428
- /** Destination de « Cancel » quand le navigateur n'a pas d'historique : la liste, sauf si la page en décide autrement. */
1425
+ /** Where "Cancel" goes when the browser has no history: the list page, unless the page decides otherwise. */
1429
1426
  protected getCancelUrl(): string;
1430
1427
  protected cancelAction(): Action;
1431
- /** Valide le formulaire ; en cas d'erreur, les pose sur le composant et prévient le navigateur. */
1428
+ /** Validates the form; on error, sets the errors on the component and notifies the browser. */
1432
1429
  protected validateForm(): Promise<boolean>;
1433
1430
  }
1434
- /** Page de création d'un enregistrement (port de CreateRecord). */
1431
+ /** Record creation page. */
1435
1432
  export declare class CreateRecord extends ResourceFormPage {
1436
1433
  static callable: string[];
1437
1434
  mount(): void;
@@ -1444,81 +1441,81 @@ export declare class CreateRecord extends ResourceFormPage {
1444
1441
  }[];
1445
1442
  getPageClasses(): string[];
1446
1443
  getFormActions(): Action[];
1447
- /** Transforme les données validées avant la création (ajouter l'auteur, calculer un champ…). */
1444
+ /** Transforms validated data before creation (add the author, compute a field…). */
1448
1445
  protected mutateFormDataBeforeCreate(data: Record<string, unknown>): Record<string, unknown> | Promise<Record<string, unknown>>;
1449
- /** Juste avant la création ; lever une erreur l'annule. */
1446
+ /** Right before creation; throwing cancels it. */
1450
1447
  protected beforeCreate(_data: Record<string, unknown>): void | Promise<void>;
1451
- /** La création elle-même : par défaut, l'adaptateur de la resource. */
1448
+ /** The creation itself; defaults to the resource's data adapter. */
1452
1449
  protected handleRecordCreation(data: Record<string, unknown>): Promise<any>;
1453
- /** Après la création (journal, envoi d'un message…). */
1450
+ /** After creation (logging, sending a message…). */
1454
1451
  protected afterCreate(_record: any): void | Promise<void>;
1455
- /** Où aller ensuite : par défaut, la page d'édition du nouvel enregistrement. */
1452
+ /** Where to go next; defaults to the new record's edit page. */
1456
1453
  protected getRedirectUrl(record: any): string;
1457
- /** Titre de la notification de succès ; `null` pour ne rien afficher. */
1454
+ /** Success notification title; `null` to show nothing. */
1458
1455
  protected getCreatedNotificationTitle(): string | null;
1459
1456
  create(another?: boolean): Promise<void>;
1460
1457
  createAnother(): Promise<void>;
1461
1458
  }
1462
- /** Action de suppression d'un enregistrement, avec confirmation (port de Filament\Actions\DeleteAction dans une page de resource). */
1459
+ /** Delete action with confirmation. */
1463
1460
  export declare class DeleteAction {
1464
- /** Sur une page d'édition : supprime l'enregistrement de la page puis revient à la liste. Sur une ligne de table : supprime la ligne. */
1461
+ /** On an edit page, deletes the page's record and returns to the list. On a table row, deletes the row. */
1465
1462
  static make(): Action;
1466
1463
  }
1467
- /** Action de duplication : comme `Action`, avec la liste des attributs à ne pas recopier. */
1464
+ /** Replicate action: an `Action` with a list of attributes not to copy. */
1468
1465
  export type ReplicateActionInstance = Action & {
1469
1466
  excludeAttributes(attributes: string[]): ReplicateActionInstance;
1470
1467
  };
1471
- /** Duplication d'une ligne de table (port de ReplicateAction) : la copie reprend les attributs de l'enregistrement, sauf sa clé, ses dates et ceux exclus. */
1468
+ /** Duplicates a table row: the copy takes the record's attributes, except its key, timestamps and excluded ones. */
1472
1469
  export declare class ReplicateAction {
1473
1470
  static make(): ReplicateActionInstance;
1474
1471
  }
1475
- /** Création en modale avec le formulaire de la resource (port de CreateAction). */
1472
+ /** Create in a modal with the resource form. */
1476
1473
  export declare class CreateAction {
1477
- /** Sans argument, la resource (ou le relation manager) est celle du composant hôte. */
1474
+ /** Without an argument, the resource (or relation manager) is the host component's. */
1478
1475
  static make(resource?: typeof Resource | null): Action;
1479
1476
  }
1480
- /** Édition en modale d'une ligne de table, avec le formulaire de la resource (port de EditAction). */
1477
+ /** Edit a table row in a modal, with the resource form. */
1481
1478
  export declare class EditAction {
1482
- /** Sans argument, la resource (ou le relation manager) est celle du composant hôte. */
1479
+ /** Without an argument, the resource (or relation manager) is the host component's. */
1483
1480
  static make(resource?: typeof Resource | null): Action;
1484
1481
  }
1485
- /** Lien vers la page de consultation de l'enregistrement (port de ViewAction, quand la resource a une page « View »). */
1482
+ /** Link to the record's view page (when the resource has one). */
1486
1483
  export declare class ViewAction {
1487
1484
  static make(resource?: typeof Resource | null): Action;
1488
1485
  }
1489
- /** Rattache un enregistrement existant au propriétaire d'un relation manager (port de AttachAction). */
1486
+ /** Attaches an existing record to a relation manager's owner. */
1490
1487
  export declare class AttachAction {
1491
1488
  static make(): Action;
1492
1489
  }
1493
- /** Détache une ligne du propriétaire sans la supprimer (port de DetachAction). */
1490
+ /** Detaches a row from the owner without deleting it. */
1494
1491
  export declare class DetachAction {
1495
1492
  static make(): Action;
1496
1493
  }
1497
- /** Détache les lignes sélectionnées (port de DetachBulkAction). */
1494
+ /** Detaches the selected rows. */
1498
1495
  export declare class DetachBulkAction {
1499
1496
  static make(): Action;
1500
1497
  }
1501
- /** Restauration d'un enregistrement supprimé (port de RestoreAction). Visible seulement s'il est supprimé. */
1498
+ /** Restores a soft-deleted record. Only visible when the record is deleted. */
1502
1499
  export declare class RestoreAction {
1503
1500
  static make(): Action;
1504
1501
  }
1505
- /** Suppression définitive d'un enregistrement supprimé (port de ForceDeleteAction). Visible seulement s'il est supprimé. */
1502
+ /** Permanently deletes a soft-deleted record. Only visible when the record is deleted. */
1506
1503
  export declare class ForceDeleteAction {
1507
1504
  static make(): Action;
1508
1505
  }
1509
- /** Suppression groupée des enregistrements sélectionnés dans une table (port de DeleteBulkAction). */
1506
+ /** Deletes the records selected in a table. */
1510
1507
  export declare class DeleteBulkAction {
1511
1508
  static make(): Action;
1512
1509
  }
1513
- /** Page d'édition d'un enregistrement (port de EditRecord). */
1510
+ /** Record edit page. */
1514
1511
  export declare class EditRecord extends ResourceFormPage {
1515
1512
  static callable: string[];
1516
1513
  recordKey: string;
1517
- /** Onglet de relation manager actif (indice dans `Resource.relations`). */
1514
+ /** Active relation manager tab (index in `Resource.relations`). */
1518
1515
  activeRelationManager: string;
1519
1516
  /**
1520
- * Page précédente (équivalent de `url()->previous()`), retenue au premier affichage. Elle vient de l'en-tête Referer :
1521
- * seule une adresse de ce même site est acceptée, et elle n'est plus modifiable ensuite.
1517
+ * Previous page, captured on first display from the Referer header: only a same-site URL is accepted,
1518
+ * and it cannot be changed afterwards.
1522
1519
  */
1523
1520
  previousUrl: string;
1524
1521
  protected getCancelUrl(): string;
@@ -1526,13 +1523,13 @@ export declare class EditRecord extends ResourceFormPage {
1526
1523
  static locked: string[];
1527
1524
  _record: any;
1528
1525
  mount(params: Record<string, unknown>): Promise<void>;
1529
- /** L'enregistrement est relu à chaque requête, comme dans Filament (pas de liaison de route). */
1526
+ /** The record is reloaded on every request (no route model binding). */
1530
1527
  hydrate(): Promise<void>;
1531
1528
  protected getRecord(): unknown;
1532
1529
  getRecordKey(): string | null;
1533
1530
  getActionMountContext(): Record<string, unknown>;
1534
1531
  protected getActionRecord(): unknown;
1535
- /** Comme une page générée par Filament : suppression, plus restauration et suppression définitive si le modèle a la suppression douce. */
1532
+ /** Delete, plus restore and force-delete when the model uses soft deletes. */
1536
1533
  getHeaderActions(): Action[];
1537
1534
  getOperation(): 'edit';
1538
1535
  getSubmitMethod(): string;
@@ -1544,41 +1541,41 @@ export declare class EditRecord extends ResourceFormPage {
1544
1541
  getSubNavigation(): SubNavigationItem[];
1545
1542
  getPageClasses(): string[];
1546
1543
  getFormActions(): Action[];
1547
- /** Transforme les valeurs de l'enregistrement avant de remplir le formulaire. */
1544
+ /** Transforms the record's values before filling the form. */
1548
1545
  protected mutateFormDataBeforeFill(data: Record<string, unknown>): Record<string, unknown> | Promise<Record<string, unknown>>;
1549
- /** Transforme les données validées avant l'enregistrement. */
1546
+ /** Transforms validated data before saving. */
1550
1547
  protected mutateFormDataBeforeSave(data: Record<string, unknown>): Record<string, unknown> | Promise<Record<string, unknown>>;
1551
- /** Juste avant l'enregistrement ; lever une erreur l'annule. */
1548
+ /** Right before saving; throwing cancels it. */
1552
1549
  protected beforeSave(_data: Record<string, unknown>): void | Promise<void>;
1553
- /** L'enregistrement lui-même : par défaut, l'adaptateur de la resource. */
1550
+ /** The save itself; defaults to the resource's data adapter. */
1554
1551
  protected handleRecordUpdate(record: any, data: Record<string, unknown>): Promise<any>;
1555
- /** Après l'enregistrement. */
1552
+ /** After saving. */
1556
1553
  protected afterSave(_record: any): void | Promise<void>;
1557
- /** Adresse où aller après l'enregistrement ; `null` (défaut) : rester sur la page. */
1554
+ /** URL to go to after saving; `null` (default) stays on the page. */
1558
1555
  protected getRedirectUrl(_record: any): string | null;
1559
- /** Titre de la notification de succès ; `null` pour ne rien afficher. */
1556
+ /** Success notification title; `null` to show nothing. */
1560
1557
  protected getSavedNotificationTitle(): string | null;
1561
1558
  save(): Promise<void>;
1562
1559
  }
1563
- /** Page de consultation d'un enregistrement (port de ViewRecord) : le schéma `infolist()` de la resource, en lecture seule. */
1560
+ /** Record view page: the resource's read-only `infolist()` schema. */
1564
1561
  export declare class ViewRecord extends Page {
1565
1562
  static resource: typeof Resource;
1566
1563
  static locked: string[];
1567
1564
  recordKey: string;
1568
- /** Onglet de relation manager actif (indice dans `Resource.relations`). */
1565
+ /** Active relation manager tab (index in `Resource.relations`). */
1569
1566
  activeRelationManager: string;
1570
1567
  _record: any;
1571
1568
  get resource(): typeof Resource;
1572
1569
  getDataAdapter(): DataAdapter;
1573
1570
  mount(params: Record<string, unknown>): Promise<void>;
1574
- /** L'enregistrement est relu à chaque requête, comme sur la page d'édition. */
1571
+ /** The record is reloaded on every request, as on the edit page. */
1575
1572
  hydrate(): Promise<void>;
1576
1573
  getRecordKey(): string | null;
1577
1574
  getActionMountContext(): Record<string, unknown>;
1578
1575
  protected getActionRecord(): unknown;
1579
1576
  infolistSchema(schema: Schema): Schema;
1580
1577
  contentSchema(schema: Schema): Schema;
1581
- /** Par défaut : le lien vers la page d'édition (EditAction d'une page « View »). */
1578
+ /** Defaults to a link to the edit page. */
1582
1579
  getHeaderActions(): Action[];
1583
1580
  protected editAction(): Action;
1584
1581
  getTitle(): string;
@@ -1589,18 +1586,18 @@ export declare class ViewRecord extends Page {
1589
1586
  getSubNavigation(): SubNavigationItem[];
1590
1587
  getPageClasses(): string[];
1591
1588
  }
1592
- /** Sidebar : logo, menu du locataire, recherche, navigation, et — sans barre du haut — cloche et menu utilisateur. */
1589
+ /** Sidebar: logo, tenant menu, search, navigation and, without a topbar, the bell and user menu. */
1593
1590
  export declare class Sidebar extends Component {
1594
1591
  static callable: string[];
1595
1592
  currentPath: string;
1596
1593
  static locked: string[];
1597
1594
  mount(params: Record<string, unknown>): void;
1598
- /** Un élément de resource reste actif sur ses pages de création et d'édition. */
1595
+ /** A resource item stays active on its create and edit pages. */
1599
1596
  render(): Promise<string>;
1600
- /** Choix d'un thème par l'utilisateur : seul un thème déclaré par le panel est accepté ; la page est rechargée pour l'appliquer. */
1597
+ /** Theme choice by the user: only a theme declared by the panel is accepted; the page reloads to apply it. */
1601
1598
  setTheme(id: unknown): void;
1602
1599
  }
1603
- /** Barre du haut (port de Filament\Livewire\Topbar) : logo, navigation éventuelle, recherche, cloche, menu utilisateur. */
1600
+ /** Topbar: logo, optional navigation, search, bell, user menu. */
1604
1601
  export declare class Topbar extends Component {
1605
1602
  static callable: string[];
1606
1603
  currentPath: string;
@@ -1609,11 +1606,19 @@ export declare class Topbar extends Component {
1609
1606
  render(): Promise<string>;
1610
1607
  setTheme(id: unknown): void;
1611
1608
  }
1612
- /** Menu utilisateur des pages simples d'un utilisateur connecté (port de SimpleUserMenu). */
1609
+ /** User menu on simple pages for a signed-in user. */
1613
1610
  export declare class SimpleUserMenu extends Component {
1614
1611
  static callable: string[];
1615
1612
  render(): Promise<string>;
1616
1613
  setTheme(id: unknown): void;
1617
1614
  }
1618
- /** Routeur Express d'un panel : assets, endpoint du runtime, authentification, locataires, pages protégées. */
1615
+ /** Resources defined in a folder: `.resources(await discoverResources(new URL('./resources/', import.meta.url)))`. New files are picked up on the next start. */
1616
+ export declare const discoverResources: (directory: string | URL) => Promise<(typeof Resource)[]>;
1617
+ /** Custom pages (and dashboards) defined in a folder. Resource and authentication pages are excluded. */
1618
+ export declare const discoverPages: (directory: string | URL) => Promise<(typeof Page)[]>;
1619
+ /** Widgets defined in a folder. */
1620
+ export declare const discoverWidgets: (directory: string | URL) => Promise<(typeof Widget)[]>;
1621
+ /** Panels default-exported (`export default Panel.make()…`) by a folder's modules. */
1622
+ export declare function discoverPanels(directory: string | URL): Promise<Panel[]>;
1623
+ /** Express router for a panel: assets, runtime endpoint, authentication, tenants, protected pages. */
1619
1624
  export declare function panelRouter(panel: Panel, runtime: WireRuntime): Router;