Configuration and navigation
How OddenPlugin decides what to register, the navigation groups it uses, and the URLs and route names of its resources and pages.
OddenPlugin has no config file and no environment variables. What it registers depends on which Odden packages are installed, plus the fluent options in Customizing and extending for turning modules off or swapping classes. You change the rest (the panel path, how navigation groups are ordered, colors and so on) on the Filament panel itself.
Plugin API
Odden\Filament\OddenPlugin implements Filament\Contracts\Plugin and exposes only:
| Method | Description |
|---|---|
OddenPlugin::make(): static |
Resolves the plugin from the container. |
getId(): string |
Returns 'odden'. |
register(Panel $panel): void |
Adds the resources and pages described below to the panel. |
boot(Panel $panel): void |
Does nothing. |
There are no methods for turning individual modules, resources or pages on or off. If you need a smaller panel, register the resources yourself instead of using the plugin. See Customizing and extending.
How modules are detected
When the panel is registered, OddenPlugin::register() checks whether Sales is installed, and registers whatever the paid add-ons have added to Modules:
| Module | Detected by | Registers |
|---|---|---|
| Core (always) | — | ContactResource, CompanyResource, CrmListResource, PropertyDefinitionResource; pages ExecutiveOverview, DataQuality |
| Sales | class_exists(Odden\Sales\Models\Deal::class) |
DealResource, PipelineResource, QuoteResource, SalesQuotaResource, SalesEmailTemplateResource, SalesSequenceResource, SalesPlaybookResource, SalesMeetingLinkResource, LeadRoutingRuleResource; page SalesCockpit |
| Marketing and Service (paid add-ons) | They register themselves with Modules when installed |
Their own resources and pages, in the Marketing and Service groups |
Core and Sales resources live in Odden\Filament\Resources and pages in Odden\Filament\Pages. A paid add-on's screens live in its own namespace (for example Odden\Marketing\Filament).
The check only asks whether the package's code is autoloadable. It doesn't check that the module's service provider booted or that its migrations ran, so run each module's migrations as soon as you install it. Otherwise its pages fail with missing-table errors.
The same checks apply inside the core resources:
- The contact and company Associated Deals relation managers only appear when sales is installed.
- The contact Sales Sequences & Cadences relation manager only appears when sales is installed.
- Marketing adds its contact tabs and the company Recalculate Intent action through
Modules, so they only appear when Marketing is installed. - The contact Playbook and Auto-Route actions only appear when sales is installed.
- The Executive Overview shows zeros for the sales metrics when Sales is not installed, and shows the summary cards only of the paid add-ons that are installed.
Navigation groups
The plugin uses plain string navigation groups:
| Group | Contents |
|---|---|
Executive |
Executive Overview |
CRM |
Contacts, Companies, Lists, Data Quality |
Sales |
Sales Cockpit, Deals, Quotes, Sales Quotas, Email Templates, Sales Cadences, Sales Playbooks, Meeting Links, Lead Routing Rules |
Settings |
Custom Properties, Pipelines |
The paid add-ons add their own groups (Service and Marketing).
Ordering the groups
To control the order of the groups in the sidebar, list them on the panel with Filament's navigationGroups(). The labels must match exactly:
use Odden\Filament\OddenPlugin;
return $panel
// ...
->plugins([
OddenPlugin::make(),
])
->navigationGroups([
'Executive',
'CRM',
'Sales',
'Service',
'Marketing',
'Settings',
]);You can also pass Filament\Navigation\NavigationGroup objects with the same labels to make groups collapsible or give them icons. Item order within a group comes from each resource's or page's $navigationSort, which the plugin hard-codes. To change it, see Customizing and extending.
URLs and route names
Resource and page URLs sit under your panel's path. With a panel whose ID and path are both admin:
| Class | URL | Route name |
|---|---|---|
ContactResource |
/admin/contacts |
filament.admin.resources.contacts.index |
CompanyResource |
/admin/companies |
filament.admin.resources.companies.index |
CrmListResource |
/admin/crm-lists |
filament.admin.resources.crm-lists.index |
PropertyDefinitionResource |
/admin/property-definitions |
filament.admin.resources.property-definitions.index |
DealResource |
/admin/deals, board at /admin/deals/board |
filament.admin.resources.deals.index, ...deals.board |
PipelineResource |
/admin/pipelines |
filament.admin.resources.pipelines.index |
QuoteResource |
/admin/quotes |
filament.admin.resources.quotes.index |
SalesQuotaResource |
/admin/sales-quotas |
filament.admin.resources.sales-quotas.index |
SalesEmailTemplateResource |
/admin/sales-email-templates |
filament.admin.resources.sales-email-templates.index |
SalesSequenceResource |
/admin/sales-sequences |
filament.admin.resources.sales-sequences.index |
SalesPlaybookResource |
/admin/sales-playbooks |
filament.admin.resources.sales-playbooks.index |
SalesMeetingLinkResource |
/admin/sales-meeting-links |
filament.admin.resources.sales-meeting-links.index |
LeadRoutingRuleResource |
/admin/lead-routing-rules |
filament.admin.resources.lead-routing-rules.index |
Resources also have create, edit and, where they exist, view routes (/admin/contacts/create, /admin/contacts/{record}/edit, /admin/contacts/{record}). Resources lists which pages each resource has.
Pages use filament.admin.pages.{slug}:
| Page | URL |
|---|---|
ExecutiveOverview |
/admin/executive-overview |
DataQuality |
/admin/data-quality |
SalesCockpit |
/admin/sales-cockpit |
To build URLs in code, use Filament's helpers rather than hard-coding paths:
use Odden\Filament\Pages\SalesCockpit;
use Odden\Filament\Resources\DealResource;
$board = DealResource::getUrl('board');
$deal = DealResource::getUrl('view', ['record' => $deal]);
$cockpit = SalesCockpit::getUrl();Using more than one panel
You can register OddenPlugin::make() on several panels. Each panel gets its own copy of the resources and pages under its own path and route prefix (filament.{panel-id}.…).