1
+ <?php
2
+
3
+ namespace App \Filament \Resources ;
4
+
5
+ use App \Modules \ModuleManager ;
6
+ use Filament \Forms ;
7
+ use Filament \Forms \Form ;
8
+ use Filament \Resources \Resource ;
9
+ use Filament \Tables ;
10
+ use Filament \Tables \Table ;
11
+ use Illuminate \Database \Eloquent \Builder ;
12
+ use Illuminate \Database \Eloquent \SoftDeletingScope ;
13
+
14
+ class ModuleResource extends Resource
15
+ {
16
+ protected static ?string $ model = null ;
17
+
18
+ protected static ?string $ navigationIcon = 'heroicon-o-puzzle-piece ' ;
19
+
20
+ protected static ?string $ navigationGroup = 'System ' ;
21
+
22
+ protected static ?string $ navigationLabel = 'Modules ' ;
23
+
24
+ public static function form (Form $ form ): Form
25
+ {
26
+ return $ form
27
+ ->schema ([
28
+ Forms \Components \TextInput::make ('name ' )
29
+ ->required ()
30
+ ->disabled (),
31
+ Forms \Components \TextInput::make ('version ' )
32
+ ->disabled (),
33
+ Forms \Components \Textarea::make ('description ' )
34
+ ->disabled (),
35
+ Forms \Components \Toggle::make ('enabled ' )
36
+ ->required (),
37
+ ]);
38
+ }
39
+
40
+ public static function table (Table $ table ): Table
41
+ {
42
+ return $ table
43
+ ->query (static ::getEloquentQuery ())
44
+ ->columns ([
45
+ Tables \Columns \TextColumn::make ('name ' )
46
+ ->searchable ()
47
+ ->sortable (),
48
+ Tables \Columns \TextColumn::make ('version ' )
49
+ ->sortable (),
50
+ Tables \Columns \TextColumn::make ('description ' )
51
+ ->limit (50 ),
52
+ Tables \Columns \IconColumn::make ('enabled ' )
53
+ ->boolean ()
54
+ ->trueIcon ('heroicon-o-check-circle ' )
55
+ ->falseIcon ('heroicon-o-x-circle ' )
56
+ ->trueColor ('success ' )
57
+ ->falseColor ('danger ' ),
58
+ Tables \Columns \TextColumn::make ('dependencies ' )
59
+ ->formatStateUsing (fn ($ state ) => is_array ($ state ) ? implode (', ' , $ state ) : $ state )
60
+ ->limit (30 ),
61
+ ])
62
+ ->filters ([
63
+ Tables \Filters \TernaryFilter::make ('enabled ' )
64
+ ->label ('Status ' )
65
+ ->trueLabel ('Enabled ' )
66
+ ->falseLabel ('Disabled ' )
67
+ ->queries (
68
+ true: fn (Builder $ query ) => $ query ->where ('enabled ' , true ),
69
+ false: fn (Builder $ query ) => $ query ->where ('enabled ' , false ),
70
+ ),
71
+ ])
72
+ ->actions ([
73
+ Tables \Actions \Action::make ('toggle ' )
74
+ ->label (fn ($ record ) => $ record ->enabled ? 'Disable ' : 'Enable ' )
75
+ ->icon (fn ($ record ) => $ record ->enabled ? 'heroicon-o-x-circle ' : 'heroicon-o-check-circle ' )
76
+ ->color (fn ($ record ) => $ record ->enabled ? 'danger ' : 'success ' )
77
+ ->action (function ($ record ) {
78
+ $ moduleManager = app (ModuleManager::class);
79
+
80
+ if ($ record ->enabled ) {
81
+ $ moduleManager ->disable ($ record ->name );
82
+ } else {
83
+ $ moduleManager ->enable ($ record ->name );
84
+ }
85
+ })
86
+ ->requiresConfirmation (),
87
+ Tables \Actions \Action::make ('install ' )
88
+ ->label ('Install ' )
89
+ ->icon ('heroicon-o-arrow-down-tray ' )
90
+ ->color ('info ' )
91
+ ->action (function ($ record ) {
92
+ $ moduleManager = app (ModuleManager::class);
93
+ $ moduleManager ->install ($ record ->name );
94
+ })
95
+ ->visible (fn ($ record ) => !$ record ->enabled )
96
+ ->requiresConfirmation (),
97
+ Tables \Actions \Action::make ('uninstall ' )
98
+ ->label ('Uninstall ' )
99
+ ->icon ('heroicon-o-trash ' )
100
+ ->color ('danger ' )
101
+ ->action (function ($ record ) {
102
+ $ moduleManager = app (ModuleManager::class);
103
+ $ moduleManager ->uninstall ($ record ->name );
104
+ })
105
+ ->visible (fn ($ record ) => $ record ->enabled )
106
+ ->requiresConfirmation (),
107
+ Tables \Actions \ViewAction::make (),
108
+ ])
109
+ ->bulkActions ([
110
+ Tables \Actions \BulkActionGroup::make ([
111
+ Tables \Actions \BulkAction::make ('enable ' )
112
+ ->label ('Enable Selected ' )
113
+ ->icon ('heroicon-o-check-circle ' )
114
+ ->color ('success ' )
115
+ ->action (function ($ records ) {
116
+ $ moduleManager = app (ModuleManager::class);
117
+ foreach ($ records as $ record ) {
118
+ $ moduleManager ->enable ($ record ->name );
119
+ }
120
+ })
121
+ ->requiresConfirmation (),
122
+ Tables \Actions \BulkAction::make ('disable ' )
123
+ ->label ('Disable Selected ' )
124
+ ->icon ('heroicon-o-x-circle ' )
125
+ ->color ('danger ' )
126
+ ->action (function ($ records ) {
127
+ $ moduleManager = app (ModuleManager::class);
128
+ foreach ($ records as $ record ) {
129
+ $ moduleManager ->disable ($ record ->name );
130
+ }
131
+ })
132
+ ->requiresConfirmation (),
133
+ ]),
134
+ ]);
135
+ }
136
+
137
+ public static function getEloquentQuery (): Builder
138
+ {
139
+ $ moduleManager = app (ModuleManager::class);
140
+ $ modules = $ moduleManager ->getAllModulesInfo ();
141
+
142
+ // Convert modules array to a collection that can be used with Filament
143
+ $ query = new class extends Builder {
144
+ protected $ modules ;
145
+
146
+ public function __construct ($ modules )
147
+ {
148
+ $ this ->modules = collect ($ modules );
149
+ }
150
+
151
+ public function get ($ columns = ['* ' ])
152
+ {
153
+ return $ this ->modules ->map (function ($ module ) {
154
+ return (object ) $ module ;
155
+ });
156
+ }
157
+
158
+ public function paginate ($ perPage = 15 , $ columns = ['* ' ], $ pageName = 'page ' , $ page = null )
159
+ {
160
+ return $ this ->modules ->map (function ($ module ) {
161
+ return (object ) $ module ;
162
+ });
163
+ }
164
+
165
+ public function where ($ column , $ operator = null , $ value = null , $ boolean = 'and ' )
166
+ {
167
+ if ($ column === 'enabled ' ) {
168
+ $ this ->modules = $ this ->modules ->filter (function ($ module ) use ($ value ) {
169
+ return $ module ['enabled ' ] === $ value ;
170
+ });
171
+ }
172
+ return $ this ;
173
+ }
174
+ };
175
+
176
+ return new $ query ($ modules );
177
+ }
178
+
179
+ public static function getPages (): array
180
+ {
181
+ return [
182
+ 'index ' => Pages \ListModules::route ('/ ' ),
183
+ 'view ' => Pages \ViewModule::route ('/{record} ' ),
184
+ ];
185
+ }
186
+ }
0 commit comments