Skip to content

Commit

Permalink
add support for filament
Browse files Browse the repository at this point in the history
  • Loading branch information
mozex committed Feb 29, 2024
1 parent 0149f83 commit 8f13cff
Show file tree
Hide file tree
Showing 44 changed files with 900 additions and 30 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"spatie/regex": "^3.1"
},
"require-dev": {
"filament/filament": "^3.2",
"larastan/larastan": "^2.0.1",
"laravel/pint": "^1.0",
"livewire/livewire": "^3.4",
Expand Down
28 changes: 26 additions & 2 deletions config/modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,37 @@
'namespace' => 'Policies\\',
],
AssetType::LivewireComponents->value => [
'active' => false,
'active' => true,
'patterns' => [
'*/Livewire',
],
],
AssetType::FilamentResources->value => [
'active' => true,
'patterns' => [
'*/Filament/*/Resources',
],
],
AssetType::FilamentPages->value => [
'active' => true,
'patterns' => [
'*/Filament/*/Pages',
],
],
AssetType::FilamentWidgets->value => [
'active' => true,
'patterns' => [
'*/Filament/*/Widgets',
],
],
AssetType::FilamentClusters->value => [
'active' => true,
'patterns' => [
'*/Filament/*/Clusters',
],
],
AssetType::NovaResources->value => [
'active' => false,
'active' => true,
'patterns' => [
'*/Nova',
],
Expand Down
4 changes: 4 additions & 0 deletions src/Contracts/BaseScout.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ public function transform(array $result): array
: [
'module' => Modules::moduleNameFromPath($item),
'path' => realpath($item),
'namespace' => str(is_dir($item) ? $item : dirname($item))
->after(Modules::basePath())
->replace(['\\', '/'], ['/', '\\'])
->toString(),
]
)
->sortBy(
Expand Down
40 changes: 40 additions & 0 deletions src/Contracts/FilamentScout.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Mozex\Modules\Contracts;

use Exception;
use Spatie\Regex\Regex;

abstract class FilamentScout extends ModuleDirectoryScout
{
public function transform(array $result): array
{
return collect(parent::transform($result))
->map(function (array $item) {
$panel = null;

foreach ($this->asset()->patterns() as $pattern) {
$panel ??= Regex::match(
pattern: str($pattern)
->replace('*', '(.*?)')
->replace('/', '\/')
->prepend('/')
->append('/')
->toString(),
subject: str(realpath($item['path']))
->replace('\\', '/')
)->groupOr(2, '');
}

if (empty($panel)) {
throw new Exception("Panel not found for {$item['path']}");
}

return [
...$item,
'panel' => strtolower($panel),
];
})
->toArray();
}
}
12 changes: 12 additions & 0 deletions src/Enums/AssetType.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
use Mozex\Modules\Scouts\BladeComponentsScout;
use Mozex\Modules\Scouts\CommandsScout;
use Mozex\Modules\Scouts\ConfigsScout;
use Mozex\Modules\Scouts\FilamentClustersScout;
use Mozex\Modules\Scouts\FilamentPagesScout;
use Mozex\Modules\Scouts\FilamentResourcesScout;
use Mozex\Modules\Scouts\FilamentWidgetsScout;
use Mozex\Modules\Scouts\HelpersScout;
use Mozex\Modules\Scouts\ListenersScout;
use Mozex\Modules\Scouts\LivewireComponentsScout;
Expand Down Expand Up @@ -38,6 +42,10 @@ enum AssetType: string
case Policies = 'policies';
case Models = 'models';
case Listeners = 'listeners';
case FilamentResources = 'filament-resources';
case FilamentPages = 'filament-pages';
case FilamentWidgets = 'filament-widgets';
case FilamentClusters = 'filament-clusters';

public function scout(): ?BaseScout
{
Expand All @@ -56,6 +64,10 @@ public function scout(): ?BaseScout
self::LivewireComponents => LivewireComponentsScout::create(),
self::NovaResources => NovaResourcesScout::create(),
self::Listeners => ListenersScout::create(),
self::FilamentResources => FilamentResourcesScout::create(),
self::FilamentPages => FilamentPagesScout::create(),
self::FilamentWidgets => FilamentWidgetsScout::create(),
self::FilamentClusters => FilamentClustersScout::create(),
default => null,
};
}
Expand Down
56 changes: 54 additions & 2 deletions src/ModulesServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Mozex\Modules;

use Filament\Facades\Filament;
use Filament\Panel;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Contracts\Auth\Access\Gate as GateInstance;
use Illuminate\Contracts\Foundation\CachesConfiguration;
Expand Down Expand Up @@ -49,6 +51,7 @@ public function packageBooted(): void
$this->bootSchedules();
$this->bootListeners();
$this->bootLivewire();
$this->bootFilament();
$this->bootNova();
}

Expand Down Expand Up @@ -351,6 +354,52 @@ protected function bootLivewire(): void
});
}

protected function bootFilament(): void
{
if (! class_exists(Filament::class)) {
return;
}

collect(Filament::getPanels())
->each(function (Panel $panel): void {
if (AssetType::FilamentResources->isActive()) {
AssetType::FilamentResources->scout()->collect()
->where('panel', strtolower($panel->getId()))
->each(fn (array $asset) => $panel->discoverResources(
in: $asset['path'],
for: $asset['namespace']
));
}

if (AssetType::FilamentPages->isActive()) {
AssetType::FilamentPages->scout()->collect()
->where('panel', strtolower($panel->getId()))
->each(fn (array $asset) => $panel->discoverPages(
in: $asset['path'],
for: $asset['namespace']
));
}

if (AssetType::FilamentWidgets->isActive()) {
AssetType::FilamentWidgets->scout()->collect()
->where('panel', strtolower($panel->getId()))
->each(fn (array $asset) => $panel->discoverWidgets(
in: $asset['path'],
for: $asset['namespace']
));
}

if (AssetType::FilamentClusters->isActive()) {
AssetType::FilamentClusters->scout()->collect()
->where('panel', strtolower($panel->getId()))
->each(fn (array $asset) => $panel->discoverClusters(
in: $asset['path'],
for: $asset['namespace']
));
}
});
}

protected function bootNova(): void
{
if (! class_exists(Nova::class)) {
Expand Down Expand Up @@ -402,9 +451,12 @@ protected function getViewName(array $asset, AssetType $type): string
->replace('\\', '/')
->replaceFirst('/', '')
->replaceMatches(
'/'.str($pattern)
str($pattern)
->replaceFirst('*', '.*?')
->replace('/', '\/').'\//',
->replace('/', '\/')
->prepend('/')
->append('\//')
->toString(),
''
)
->before('.php')
Expand Down
14 changes: 14 additions & 0 deletions src/Scouts/FilamentClustersScout.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Mozex\Modules\Scouts;

use Mozex\Modules\Contracts\FilamentScout;
use Mozex\Modules\Enums\AssetType;

class FilamentClustersScout extends FilamentScout
{
public function asset(): AssetType
{
return AssetType::FilamentClusters;
}
}
14 changes: 14 additions & 0 deletions src/Scouts/FilamentPagesScout.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Mozex\Modules\Scouts;

use Mozex\Modules\Contracts\FilamentScout;
use Mozex\Modules\Enums\AssetType;

class FilamentPagesScout extends FilamentScout
{
public function asset(): AssetType
{
return AssetType::FilamentPages;
}
}
14 changes: 14 additions & 0 deletions src/Scouts/FilamentResourcesScout.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Mozex\Modules\Scouts;

use Mozex\Modules\Contracts\FilamentScout;
use Mozex\Modules\Enums\AssetType;

class FilamentResourcesScout extends FilamentScout
{
public function asset(): AssetType
{
return AssetType::FilamentResources;
}
}
14 changes: 14 additions & 0 deletions src/Scouts/FilamentWidgetsScout.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Mozex\Modules\Scouts;

use Mozex\Modules\Contracts\FilamentScout;
use Mozex\Modules\Enums\AssetType;

class FilamentWidgetsScout extends FilamentScout
{
public function asset(): AssetType
{
return AssetType::FilamentWidgets;
}
}
3 changes: 3 additions & 0 deletions testbench.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
providers:
- Livewire\LivewireServiceProvider
- Filament\FilamentServiceProvider
- App\Providers\WorkbenchServiceProvider
- App\Providers\Filament\AdminPanelProvider
- App\Providers\Filament\DashboardPanelProvider
- Mozex\Modules\ModulesServiceProvider
- App\Providers\EventServiceProvider
- Mozex\Modules\ModulesEventServiceProvider
Expand Down
3 changes: 1 addition & 2 deletions tests/Feature/ConfigsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@
$collection = $discoverer->collect();

expect($collection)
->each->toHaveKeys(['module', 'path'])
->not->toHaveKey('namespace')
->each->toHaveKeys(['module', 'path', 'namespace'])
->and($collection->pluck('path'))
->toContain(realpath(Modules::modulesPath('First/Config/first.php')))
->toContain(realpath(Modules::modulesPath('Second/Config/test.php')));
Expand Down
99 changes: 99 additions & 0 deletions tests/Feature/FilamentClustersTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php

use App\Filament\Dashboard\Clusters\Test;
use Filament\Facades\Filament;
use Modules\First\Filament\Admin\Resources\UserResource;
use Modules\First\Filament\Dashboard\Clusters\Users;
use Modules\First\Filament\Dashboard\Resources\NestedUserResource;
use Mozex\Modules\Enums\AssetType;
use Mozex\Modules\Facades\Modules;
use Mozex\Modules\Scouts\FilamentClustersScout;

test('scout will not collect when disabled', function () {
config()->set(
'modules.'.AssetType::FilamentClusters->value.'.active',
false
);

$discoverer = FilamentClustersScout::create();

expect($discoverer->get())->toHaveCount(0);

$discoverer->cache();

expect($discoverer->get())->toHaveCount(0);

$discoverer->clear();
});

test('discovering will work', function (bool $cache) {
$discoverer = FilamentClustersScout::create();

if ($cache) {
$discoverer->cache();
}

$collection = $discoverer->collect();

expect($collection)
->each->toHaveKeys(['module', 'path', 'namespace', 'panel'])
->and($collection->pluck('path'))
->not->toContain(realpath(Modules::modulesPath('First/Filament/Admin/Clusters')))
->toContain(realpath(Modules::modulesPath('First/Filament/Dashboard/Clusters')))
->toContain(realpath(Modules::modulesPath('Second/Filament/Admin/Clusters')))
->toContain(realpath(Modules::modulesPath('Second/Filament/Dashboard/Clusters')))
->and($collection->pluck('panel')->unique())
->toContain('admin')
->toContain('dashboard');

if ($cache) {
$discoverer->clear();
}
})->with([
'without cache' => false,
'with cache' => true,
]);

it('can register filament resources', function (bool $cache) {
$discoverer = FilamentClustersScout::create();

if ($cache) {
$discoverer->cache();
}

expect(Filament::getPanel('admin')->getClusterDirectories())
->toHaveCount(2)
->toContain(Modules::basePath('app/Filament/Admin/Clusters'))
->toContain(realpath(Modules::modulesPath('Second/Filament/Admin/Clusters')))
->and(Filament::getPanel('admin')->getClusteredComponents())
->toHaveCount(1)
->toHaveKey(Test::class)
->and(array_values(Filament::getPanel('admin')->getClusteredComponents())[0])
->toContain(UserResource::class)
->and(Filament::getPanel('admin')->getClusterNamespaces())
->toHaveCount(2)
->toContain('App\\Filament\\Admin\\Clusters')
->toContain('Modules\\Second\\Filament\\Admin\\Clusters')
->and(Filament::getPanel('dashboard')->getClusterDirectories())
->toHaveCount(3)
->toContain(Modules::basePath('app/Filament/Dashboard/Clusters'))
->toContain(realpath(Modules::modulesPath('Second/Filament/Dashboard/Clusters')))
->toContain(realpath(Modules::modulesPath('First/Filament/Dashboard/Clusters')))
->and(Filament::getPanel('dashboard')->getClusteredComponents())
->toHaveCount(1)
->toHaveKey(Users::class)
->and(array_values(Filament::getPanel('dashboard')->getClusteredComponents())[0])
->toContain(NestedUserResource::class)
->and(Filament::getPanel('dashboard')->getClusterNamespaces())
->toHaveCount(3)
->toContain('App\\Filament\\Dashboard\\Clusters')
->toContain('Modules\\Second\\Filament\\Dashboard\\Clusters')
->toContain('Modules\\First\\Filament\\Dashboard\\Clusters');

if ($cache) {
$discoverer->clear();
}
})->with([
'without cache' => false,
'with cache' => true,
]);

0 comments on commit 8f13cff

Please sign in to comment.