# Sidebar Menu / Navigation System

## Overview
This project uses **Filament PHP** as the admin panel. The sidebar navigation is built using Filament's navigation system with `NavigationGroup` and `NavigationItem`.

## Where Navigation is Defined

### 1. Main Sidebar (AdminPanelProvider)
**File:** `app/Providers/Filament/AdminPanelProvider.php`

This is the **primary** place for sidebar navigation. It defines:
- All `NavigationGroup` (top-level categories)
- All `NavigationItem` that should appear in the sidebar

```php
NavigationGroup::make()
    ->label(__('admin.navigation.dashboard'))
    ->icon('heroicon-o-home'),
```

### 2. Plugin-Based Navigation Items
**Files:** `plugins/webkul/*/src/*Plugin.php`

Plugins can add their own navigation items via the `register()` method:

```php
$panel->when($panel->getId() == 'admin', function (Panel $panel) {
    $panel->navigationItems([
        NavigationItem::make('unique-key-name')  // MUST be unique, not 'settings'
            ->label(fn () => __('some::app.navigation.settings.some_page'))
            ->url(fn () => SomePage::getUrl())
            ->group('Settings')  // Use 'Settings' to group under Settings nav
            ->sort(1)
            ->visible(fn () => SomePage::canAccess()),
    ]);
});
```

## Key Classes

| Class | Purpose |
|-------|---------|
| `NavigationGroup` | Groups navigation items under a heading |
| `NavigationItem` | Individual menu links |
| `Cluster` | Groups pages under a shared URL prefix (e.g., `/settings/*`) |

## Common Issues

### Duplicate Navigation Keys
**Problem:** Multiple plugins used `NavigationItem::make('settings')` with the **same key** `'settings'`.

**Symptom:** Only one settings link appeared, or unpredictable behavior.

**Solution:**
- Use **unique keys** for each NavigationItem (e.g., `'inventory-operations'`, `'sale-products'`)
- Group them under `'Settings'` to appear in the Settings section
- Translation keys go in each plugin's `resources/lang/en/app.php`

**Files that had this issue:** `InventoryPlugin.php`, `InvoicePlugin.php`, `SalePlugin.php`, `PurchasePlugin.php`, `ProjectPlugin.php`

### Pages Not Appearing in Sidebar
**Problem:** Settings pages have `$shouldRegisterNavigation = false`.

**Solution:** Add a `NavigationItem` in the plugin's `register()` method pointing to the page URL.

## Adding Settings Pages to Sidebar

1. Add translation keys to `plugins/webkul/[plugin]/resources/lang/en/app.php`:
```php
'navigation' => [
    'settings' => [
        'label' => 'Settings',
        'some_page' => 'Some Page Name',
    ],
],
```

2. Add NavigationItem to the plugin's `*Plugin.php`:
```php
NavigationItem::make('plugin-some-page')
    ->label(fn () => __('plugin::app.navigation.settings.some_page'))
    ->url(fn () => SomePage::getUrl())
    ->group('Settings')
    ->sort(1)
    ->visible(fn () => SomePage::canAccess()),
```

## Translation Keys (Main)
Location: `lang/en/admin.php`

```php
'navigation' => [
    'dashboard'  => 'Dashboard',
    'channel'    => 'Channel',
    'settings'   => 'Settings',
    'suppliers'  => 'Connectors',  // used for supplier/external system connectors (Allmakes PSP etc.)
    // ...
]
```

## Removing Sub-Menu Items (Cluster Sub-Navigation)

### How Sub-Items Are Generated
Filament automatically creates sub-menu entries in the sidebar for every resource inside a **Cluster**. The cluster itself creates an expandable group, and each resource within it becomes a sub-item underneath.

### To Remove a Specific Sub-Item (resource)
Add this property to the resource class (`src/Filament/Resources/SomeResource.php`):
```php
protected static bool $shouldRegisterNavigation = false;
```
This hides the resource from the sidebar without breaking its pages or routes.

### To Remove All Sub-Items and Show a Single Direct Link Instead
Use this 3-step pattern (as done for Channel Orders):

**Step 1** — Suppress the cluster's sidebar entry (`src/Filament/Clusters/SomeCluster.php`).

> ⚠️ **Important:** In Filament 4, `$shouldRegisterNavigation = false` alone is NOT enough on clusters — `discoverClusters()` bypasses it. You MUST also override `getNavigationItems()`:

```php
protected static bool $shouldRegisterNavigation = false;

public static function getNavigationItems(): array
{
    return [];
}
```

**Step 2** — Suppress the resource's sidebar entry (`src/Filament/Resources/SomeResource.php`):
```php
protected static bool $shouldRegisterNavigation = false;
```

**Step 3** — Register a direct `NavigationItem` in the plugin file (`src/SomePlugin.php`):
```php
use Webkul\SomePlugin\Filament\Resources\SomeResource\Pages\ListRecords;

// Inside register() → $panel->when('admin', ...) block:
->navigationItems([
    NavigationItem::make('unique-key')
        ->label('Display Label')
        ->url(fn () => ListRecords::getUrl())
        ->group('Navigation Group Name')  // must match AdminPanelProvider group label
        ->icon('heroicon-o-some-icon')
        ->sort(1)
        ->isActiveWhen(fn () => str_starts_with(request()->route()?->getName() ?? '', 'filament.admin.route-prefix'))
        ->visible(fn () => ListRecords::canAccess()),
])
```

The cluster is still used internally for breadcrumbs and page URLs — only the sidebar entry changes.

### Real Example: Channel Orders
- Cluster: `plugins/webkul/channel-orders/src/Filament/Clusters/ChannelOrders.php` → `$shouldRegisterNavigation = false`
- Resource: `plugins/webkul/channel-orders/src/Filament/Resources/OrderResource.php` → `$shouldRegisterNavigation = false`
- Plugin: `plugins/webkul/channel-orders/src/ChannelOrdersPlugin.php` → manual `NavigationItem` pointing to `ListOrders::getUrl()` in group `'Channel Orders'`

### Finding Which Resources Are in a Cluster
Search for the cluster class name in resource files:
```
protected static ?string $cluster = SomeCluster::class;
```
Every resource with this line will have contributed a sub-item to the sidebar.

## Current Settings Structure
All settings pages use `group('Settings')` and are sorted:
- Inventory: Operations (1), Products (2), Warehouses (3), Traceability (4), Logistics (5)
- Invoices: Products (6)
- Project: Tasks (7), Time (8)
- Sales: Products (9), Pricing (10), Invoice (11), Quotation & Order (12)
- Purchase: Products (13), Orders (14)
