Skip to content

Commit b69fd86

Browse files
simonhampclaude
andauthored
Remove GitHub/Packagist links and hide grant action for free plugins (#357)
* Remove admin plugin links and hide grant action for free plugins - Remove "View on GitHub" and "View on Packagist" actions from the edit page menu - Hide "Grant to User" action for free plugins on both list and edit pages - Add tests for grant action visibility Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Remove viewGithub tests for removed action Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Rework admin plugin edit: status badge in header, reorder fields, remove rejection reason - Show status as a Filament badge in the page subheading using matching index colors - Reorder form: display name, description, type, tier, composer link, repo URL, license - Remove status and rejection_reason fields from the form - Add tests for status badge, removed fields Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add featured and active toggles to admin plugin edit screen Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 061691d commit b69fd86

6 files changed

Lines changed: 127 additions & 60 deletions

File tree

app/Filament/Resources/PluginResource.php

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,17 @@ public static function form(Schema $schema): Schema
5959
Forms\Components\TextInput::make('display_name')
6060
->label('Display Name'),
6161

62+
Forms\Components\Textarea::make('description')
63+
->label('Description'),
64+
65+
Forms\Components\Select::make('type')
66+
->options(PluginType::class),
67+
68+
Forms\Components\Select::make('tier')
69+
->options(PluginTier::class)
70+
->placeholder('No tier')
71+
->helperText('Set pricing tier for paid plugins'),
72+
6273
Forms\Components\Placeholder::make('name')
6374
->label('Composer Package Name')
6475
->content(function (?Plugin $record) {
@@ -73,14 +84,6 @@ public static function form(Schema $schema): Schema
7384
return $record->name;
7485
}),
7586

76-
Forms\Components\Select::make('type')
77-
->options(PluginType::class),
78-
79-
Forms\Components\Select::make('tier')
80-
->options(PluginTier::class)
81-
->placeholder('No tier')
82-
->helperText('Set pricing tier for paid plugins'),
83-
8487
Forms\Components\Placeholder::make('repository_url')
8588
->label('Repository URL')
8689
->content(fn (?Plugin $record) => $record?->repository_url
@@ -109,22 +112,14 @@ public static function form(Schema $schema): Schema
109112
})
110113
->visible(fn (?Plugin $record) => $record !== null),
111114

112-
Forms\Components\Select::make('status')
113-
->options(PluginStatus::class)
114-
->disabled()
115-
->helperText('Use the Approve/Reject actions to change status'),
116-
117115
Forms\Components\Toggle::make('is_official')
118116
->label('Official (First-Party)')
119117
->helperText('Official plugins are free for Ultra subscribers'),
120118

121-
Forms\Components\Textarea::make('description')
122-
->label('Description'),
123-
124-
Forms\Components\Textarea::make('rejection_reason')
125-
->label('Rejection Reason')
119+
Forms\Components\Toggle::make('featured'),
126120

127-
->visible(fn (?Plugin $record) => $record?->isRejected()),
121+
Forms\Components\Toggle::make('is_active')
122+
->label('Active'),
128123
]),
129124

130125
Schemas\Components\Section::make('Review Checks')
@@ -371,6 +366,7 @@ public static function table(Table $table): Table
371366
->label('Grant to User')
372367
->icon('heroicon-o-gift')
373368
->color('success')
369+
->visible(fn (Plugin $record): bool => ! $record->isFree())
374370
->form([
375371
Forms\Components\Select::make('user_id')
376372
->label('User')

app/Filament/Resources/PluginResource/Pages/EditPlugin.php

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace App\Filament\Resources\PluginResource\Pages;
44

5+
use App\Enums\PluginStatus;
56
use App\Enums\PluginTier;
67
use App\Enums\PluginType;
78
use App\Filament\Resources\PluginResource;
@@ -15,12 +16,30 @@
1516
use Filament\Forms;
1617
use Filament\Notifications\Notification;
1718
use Filament\Resources\Pages\EditRecord;
19+
use Illuminate\Support\Facades\Blade;
1820
use Illuminate\Support\HtmlString;
1921

2022
class EditPlugin extends EditRecord
2123
{
2224
protected static string $resource = PluginResource::class;
2325

26+
public function getSubheading(): string|HtmlString|null
27+
{
28+
$color = match ($this->record->status) {
29+
PluginStatus::Draft => 'gray',
30+
PluginStatus::Pending => 'warning',
31+
PluginStatus::Approved => 'success',
32+
PluginStatus::Rejected => 'danger',
33+
};
34+
35+
return new HtmlString(
36+
Blade::render('<x-filament::badge :color="$color">{{ $label }}</x-filament::badge>', [
37+
'color' => $color,
38+
'label' => $this->record->status->label(),
39+
])
40+
);
41+
}
42+
2443
protected function getHeaderActions(): array
2544
{
2645
return [
@@ -106,7 +125,7 @@ protected function getHeaderActions(): array
106125
->label('Grant to User')
107126
->icon('heroicon-o-gift')
108127
->color('success')
109-
->visible(fn () => $this->record->isApproved())
128+
->visible(fn () => $this->record->isApproved() && ! $this->record->isFree())
110129
->form([
111130
Forms\Components\Select::make('user_id')
112131
->label('User')
@@ -159,14 +178,6 @@ protected function getHeaderActions(): array
159178
->modalDescription(fn () => "Grant '{$this->record->name}' to a user for free.")
160179
->modalSubmitActionLabel('Grant'),
161180

162-
Actions\Action::make('viewPackagist')
163-
->label('View on Packagist')
164-
->icon('heroicon-o-arrow-top-right-on-square')
165-
->color('gray')
166-
->url(fn () => $this->record->getPackagistUrl())
167-
->openUrlInNewTab()
168-
->visible(fn () => $this->record->isFree()),
169-
170181
Actions\Action::make('runReviewChecks')
171182
->label('Run Review Checks')
172183
->icon('heroicon-o-clipboard-document-check')
@@ -245,14 +256,6 @@ protected function getHeaderActions(): array
245256
->send();
246257
}),
247258

248-
Actions\Action::make('viewGithub')
249-
->label('View on GitHub')
250-
->icon('heroicon-o-arrow-top-right-on-square')
251-
->color('gray')
252-
->visible(fn () => $this->record->repository_url !== null)
253-
->url(fn () => $this->record->getGithubUrl())
254-
->openUrlInNewTab(),
255-
256259
Actions\Action::make('viewListing')
257260
->label('View Listing Page')
258261
->icon('heroicon-o-eye')

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
namespace Tests\Feature\Filament;
4+
5+
use App\Filament\Resources\PluginResource\Pages\EditPlugin;
6+
use App\Filament\Resources\PluginResource\Pages\ListPlugins;
7+
use App\Models\Plugin;
8+
use App\Models\User;
9+
use Illuminate\Foundation\Testing\RefreshDatabase;
10+
use Livewire\Livewire;
11+
use Tests\TestCase;
12+
13+
class GrantPluginToUserActionTest extends TestCase
14+
{
15+
use RefreshDatabase;
16+
17+
private User $admin;
18+
19+
protected function setUp(): void
20+
{
21+
parent::setUp();
22+
23+
$this->admin = User::factory()->create(['email' => 'admin@test.com']);
24+
config(['filament.users' => ['admin@test.com']]);
25+
}
26+
27+
public function test_grant_to_user_action_is_hidden_for_free_plugins_on_list(): void
28+
{
29+
$plugin = Plugin::factory()->free()->approved()->create();
30+
31+
Livewire::actingAs($this->admin)
32+
->test(ListPlugins::class)
33+
->assertTableActionHidden('grantToUser', $plugin);
34+
}
35+
36+
public function test_grant_to_user_action_is_visible_for_paid_plugins_on_list(): void
37+
{
38+
$plugin = Plugin::factory()->paid()->approved()->create();
39+
40+
Livewire::actingAs($this->admin)
41+
->test(ListPlugins::class)
42+
->assertTableActionVisible('grantToUser', $plugin);
43+
}
44+
45+
public function test_grant_to_user_action_is_hidden_for_free_plugins_on_edit(): void
46+
{
47+
$plugin = Plugin::factory()->free()->approved()->create();
48+
49+
Livewire::actingAs($this->admin)
50+
->test(EditPlugin::class, ['record' => $plugin->getRouteKey()])
51+
->assertActionHidden('grantToUser');
52+
}
53+
54+
public function test_grant_to_user_action_is_visible_for_paid_plugins_on_edit(): void
55+
{
56+
$plugin = Plugin::factory()->paid()->approved()->create();
57+
58+
Livewire::actingAs($this->admin)
59+
->test(EditPlugin::class, ['record' => $plugin->getRouteKey()])
60+
->assertActionVisible('grantToUser');
61+
}
62+
}

tests/Feature/Filament/PluginEditFormTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,33 @@ public function test_approve_action_is_hidden_for_approved_plugin(): void
105105
->test(EditPlugin::class, ['record' => $plugin->getRouteKey()])
106106
->assertActionHidden('approve');
107107
}
108+
109+
public function test_status_is_shown_as_badge_in_subheading(): void
110+
{
111+
$plugin = Plugin::factory()->approved()->create();
112+
113+
Livewire::actingAs($this->admin)
114+
->test(EditPlugin::class, ['record' => $plugin->getRouteKey()])
115+
->assertSee('Approved');
116+
}
117+
118+
public function test_status_field_is_not_in_form(): void
119+
{
120+
$plugin = Plugin::factory()->approved()->create();
121+
122+
Livewire::actingAs($this->admin)
123+
->test(EditPlugin::class, ['record' => $plugin->getRouteKey()])
124+
->assertFormFieldDoesNotExist('status');
125+
}
126+
127+
public function test_rejection_reason_field_is_not_in_form(): void
128+
{
129+
$plugin = Plugin::factory()->rejected()->create([
130+
'rejection_reason' => 'Missing license',
131+
]);
132+
133+
Livewire::actingAs($this->admin)
134+
->test(EditPlugin::class, ['record' => $plugin->getRouteKey()])
135+
->assertFormFieldDoesNotExist('rejection_reason');
136+
}
108137
}

tests/Feature/Filament/ResyncPluginActionTest.php

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -64,27 +64,4 @@ public function test_resync_action_hidden_when_no_repository_url(): void
6464
->test(EditPlugin::class, ['record' => $plugin->getRouteKey()])
6565
->assertActionHidden('resync');
6666
}
67-
68-
public function test_view_github_action_uses_repository_url(): void
69-
{
70-
$plugin = Plugin::factory()->free()->approved()->create([
71-
'repository_url' => 'https://github.com/acme/test-plugin',
72-
]);
73-
74-
Livewire::actingAs($this->admin)
75-
->test(EditPlugin::class, ['record' => $plugin->getRouteKey()])
76-
->assertActionVisible('viewGithub')
77-
->assertActionHasUrl('viewGithub', 'https://github.com/acme/test-plugin');
78-
}
79-
80-
public function test_view_github_action_hidden_when_no_repository_url(): void
81-
{
82-
$plugin = Plugin::factory()->free()->approved()->create([
83-
'repository_url' => null,
84-
]);
85-
86-
Livewire::actingAs($this->admin)
87-
->test(EditPlugin::class, ['record' => $plugin->getRouteKey()])
88-
->assertActionHidden('viewGithub');
89-
}
9067
}

0 commit comments

Comments
 (0)