Skip to content

Commit

Permalink
Merge pull request #35 from bezhanSalleh/feature/deprecate-excludes
Browse files Browse the repository at this point in the history
Feature/deprecate excludes
  • Loading branch information
bezhanSalleh authored Oct 10, 2024
2 parents f89558f + 94afc1d commit ff16445
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 12 deletions.
1 change: 0 additions & 1 deletion .phpunit.cache/test-results

This file was deleted.

46 changes: 40 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@
<a href="#who-can-switch-panels">Who Can Switch Panels?</a>
</li>
<li>
<a href="#panel-exclusion">Panel Exclusion</a>
<a href="#panels">Panel [New 1.0.7]</a>
</li>
<a href="#sort-order">Sort Order [New 1.0.7]</a>
</li>
<li>
<a href="#placement">Placement</a>
Expand All @@ -63,6 +65,8 @@
<li>
<a href="#theming">Theming</a>
</li>
<a href="#panel-exclusion">Panel Exclusion [@deprecated]</a>
</li>
<li>
<a href="#testing">Testing</a>
</li>
Expand Down Expand Up @@ -237,16 +241,33 @@ PanelSwitch::configureUsing(function (PanelSwitch $panelSwitch) {
});
```

### Panel Exclusion
By default all the panels available will be listed in the panel switch menu. But you can exclude some of them by using the `excludes()` method.
### Panels `New(1.0.7)`
By default all the panels available will be listed in the panel switch menu. But by providing an array of panel ids to the `panels()` method you can limit the panels that will be listed.

```php
PanelSwitch::configureUsing(function (PanelSwitch $panelSwitch) {
$panelSwitch->excludes([
'saas'
$panelSwitch->panels([
'admin',
'dev',
'app'
]);
});
```
Then `panels()` method also accepts a closure that returns an array of panel ids. This is useful when you want to dynamically determine the panels that will be listed. The plugin will also validate the panels to ensure that they are valid filament panels. If any of the panels provided are invalid, the plugin will throw an `InvalidArgumentException`.

### Sort Order `New(1.0.7)`
By default the panels will be listed in the order they were registered in `config/app.php`'s `providers` array or in the order they are provided through the `panels()` method. But you can opt-in to sort the panels either in `asc` or `desc` order via `sort()` method.
```php
PanelSwitch::configureUsing(function (PanelSwitch $panelSwitch) {
$panelSwitch
...
->panels(['admin', 'dev', 'app']) // default order if `sort()` method not used
->sort() // ['admin', 'app', 'dev']
// ->sort(order: 'desc') // ['dev', 'app', 'admin']
...
;
});
```

### Placement
You can choose where the panel switch menu should be placed. By default panel switch menu is rendered via 'panels::global-search.before' `Hook`. But you can change it to anyone of the other available Filament [Render Hooks](https://filamentphp.com/docs/3.x/support/render-hooks#available-render-hooks).
Expand All @@ -266,6 +287,7 @@ use BezhanSalleh\PanelSwitch\PanelSwitch;

PanelSwitch::configureUsing(function (PanelSwitch $panelSwitch) {
$panelSwitch
->panels(['admin', 'app', 'dev'])
->heading('Available Panels')
->modalWidth('sm')
->slideOver()
Expand All @@ -281,6 +303,7 @@ PanelSwitch::configureUsing(function (PanelSwitch $panelSwitch) {

});
```

### Theming
By default the plugin uses the default filament theme, but you can customize it by adding the view path into the `content` array of your `panels'` `tailwind.config.js` file:

Expand All @@ -294,6 +317,17 @@ export default {
}
```

### Panel Exclusion
**`@deprecated`** use **`panels()`** method instead.
By default all the panels available will be listed in the panel switch menu. But you can exclude some of them by using the excludes() method.
```php
PanelSwitch::configureUsing(function (PanelSwitch $panelSwitch) {
$panelSwitch->excludes([
'saas'
]);
});
```

Optionally, you can publish the views using

```bash
Expand Down Expand Up @@ -344,4 +378,4 @@ Please review [our security policy](../../security/policy) on how to report secu

## License

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
23 changes: 23 additions & 0 deletions src/Concerns/HasPanelValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace BezhanSalleh\PanelSwitch\Concerns;

use Filament\Facades\Filament;
use InvalidArgumentException;

trait HasPanelValidator
{
/**
* @throws InvalidArgumentException
*/
public function areUserProvidedPanelsValid(array $panelIds): void
{
$validated = collect($panelIds)->diff(collect(Filament::getPanels())->keys()->toArray());

if ($validated->isNotEmpty()) {
throw new InvalidArgumentException("Invalid Filament Panel. Make sure the panel ids passed to the `Panel Switch`, are valid and do exist. [`{$validated->implode(', ')}`]");
}
}
}
64 changes: 59 additions & 5 deletions src/PanelSwitch.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

class PanelSwitch extends Component
{
use Concerns\HasPanelValidator;

protected array | Closure $excludes = [];

protected bool | Closure | null $visible = null;
Expand All @@ -28,30 +30,38 @@ class PanelSwitch extends Component

protected array | Closure $labels = [];

protected array | Closure | null $panels = null;

protected bool $renderIconAsImage = false;

protected string | Closure $modalHeading = 'Switch Panels';

protected string $renderHook = 'panels::global-search.before';

protected ?string $sortOrder = null;

public static function make(): static
{
$static = app(static::class);

$static->visible(function () {
$static->visible(function () use ($static) {
if (($user = auth()->user()) === null) {
return false;
}

if (method_exists($user, 'canAccessPanel')) {
return $user->canAccessPanel(Filament::getCurrentPanel() ?? Filament::getDefaultPanel());
return $user->canAccessPanel($static->getCurrentPanel());
}

return true;
});

$static->configure();

if (count($static->getPanels()) < 2) {
$static->visible(false);
}

return $static;
}

Expand Down Expand Up @@ -90,6 +100,9 @@ public function canSwitchPanels(bool | Closure $condition): static
return $this;
}

/**
* @deprecated Use `panels()` instead.
*/
public function excludes(array | Closure $panelIds): static
{
$this->excludes = $panelIds;
Expand Down Expand Up @@ -142,6 +155,13 @@ public function modalWidth(string | Closure | null $width = null): static
return $this;
}

public function panels(array | Closure | null $panels = null): static
{
$this->panels = $panels;

return $this;
}

public function renderHook(string $hook): static
{
$this->renderHook = $hook;
Expand All @@ -163,6 +183,19 @@ public function simple(bool | Closure $condition = true): static
return $this;
}

/**
* Whether to sort the panels by their order or not.
* 1. null - Default order, provided by the user through the `panels` method.
* 2. 'asc' - Ascending order
* 3. 'desc' - Descending order
*/
public function sort(string $order = 'asc'): static
{
$this->sortOrder = $order;

return $this;
}

public function visible(bool | Closure $visible): static
{
$this->visible = $visible;
Expand Down Expand Up @@ -228,14 +261,35 @@ public function isVisible(): bool
return (bool) $this->evaluate($this->visible);
}

/**
* @return array<string, Panel>
*/
public function getSortOrder(): ?string
{
return $this->evaluate($this->sortOrder);
}

public function getPanels(): array
{
$panelIds = (array) $this->evaluate($this->panels);

return collect(Filament::getPanels())
->reject(fn (Panel $panel) => in_array($panel->getId(), $this->getExcludes()))
->when(
value: filled($panelIds),
callback: function ($panelCollection) use ($panelIds) {
$this->areUserProvidedPanelsValid($panelIds);

$withDefaultOrder = $panelCollection->only($panelIds);

return collect($panelIds)
->map(fn (string $id) => $withDefaultOrder[$id])
->filter();
},
default: fn ($panelCollection) => $panelCollection
)
->mapWithKeys(fn (Panel $panel) => [$panel->getId() => $this->isAbleToSwitchPanels() ? url($panel->getPath()) : null])
->when(
value: filled($this->getSortOrder()),
callback: fn ($panelCollection) => $panelCollection->sortKeys(descending: $this->getSortOrder() === 'desc')
)
->toArray();
}

Expand Down

0 comments on commit ff16445

Please sign in to comment.