Compare commits

..

68 Commits

Author SHA1 Message Date
Boy132
e35ce1e79d Use folder name as id when having id mismatch to allow deletion (#2263) 2026-02-23 20:25:19 +01:00
Charles
42c127c004 Fix invisible force delete button (#2262) 2026-02-23 13:41:15 -05:00
Boy132
593f209142 Fix stock egg UUID migration (#2259) 2026-02-22 17:23:51 +01:00
Boy132
9bf5b2cf0a Do not throw error when checking for egg updates (#2256) 2026-02-22 17:23:09 +01:00
Lance Pioch
f76e864a30 Laravel 12.52.0 Shift (#2247)
Co-authored-by: Shift <shift@laravelshift.com>
2026-02-22 11:11:18 -05:00
Boy132
01cfa31ee1 Limit activity logs on profile page (#2253) 2026-02-19 14:57:48 +01:00
Boy132
dead664e4d Make plugin id in artisan commands also case insensitive (#2252) 2026-02-19 14:57:19 +01:00
Charles
1bbbcd0e25 Update server/egg icon url supported file types (#2249) 2026-02-18 16:30:24 -05:00
Michael (Parker) Parker
677d2f742c docker env fixes (#2234)
Co-authored-by: Charles <charles@pelican.dev>
Co-authored-by: Boy132 <Boy132@users.noreply.github.com>
2026-02-18 14:40:46 -05:00
Charles
650fb16d2d exclude bulk actions in list eggs (#2239) 2026-02-17 06:17:28 -05:00
Boy132
58814ea782 Allow to delete errored plugins (#2246) 2026-02-17 11:52:25 +01:00
hallo123wert
0918ed308b exclude bulk actions (#2240) 2026-02-16 06:34:14 -05:00
Lance Pioch
85d5f2ec3f Fix alert banners (#1492) (#2177) 2026-02-15 15:34:09 -05:00
Lance Pioch
810f237547 Remove ignition, just use new default error handler (#2241) 2026-02-15 15:03:55 -05:00
Lance Pioch
8f191890a1 Fix null backup limit exception (#2242) 2026-02-15 15:03:37 -05:00
Boy132
160e0e54f5 More action fixes (#2237)
Co-authored-by: notCharles <charles@pelican.dev>
2026-02-15 17:31:50 +01:00
Charles
fdcfbb00ca Revert "Fix UTF double encoding in file editor" (#2236) 2026-02-15 11:08:01 -05:00
Lance Pioch
44f6cf8928 Fix UTF double encoding in file editor (#2199) 2026-02-14 10:33:35 -05:00
Boy132
cf2a26bbf0 Improve plugin loading (#2233) 2026-02-14 14:06:50 +01:00
gOOvER
adb6678eee Convert YAML boolean defaults to strings (#2232) 2026-02-13 18:12:44 -05:00
Lance Pioch
9539e21b39 Handle invalid svg icon in generic-oidc provider gracefully (#2216) 2026-02-13 10:06:07 -05:00
Charles
33660f635f Fix yet another action (#2230) 2026-02-12 21:00:26 -05:00
Lance Pioch
8c475ed95f Add “reachable” column for Client -> Wings connections for Nodes (#2200) 2026-02-12 17:06:38 -05:00
Lance Pioch
d43cb1d180 Fix empty egg config_files causing fatal 500 error (#2195) (#2197) 2026-02-12 17:06:19 -05:00
Lance Pioch
fe55dbd200 Ignore oauth redirects for spa (#2224) 2026-02-12 16:31:35 -05:00
Charles
0bb4503c2b fix unsuspend button (#2227) 2026-02-12 16:31:20 -05:00
Lance Pioch
3c1168beb5 Update job runners (#2225) 2026-02-12 10:29:33 -05:00
Quinten
1a092aedc8 Docker: chown composer.json and composer.lock for plugins (#2220) 2026-02-12 10:02:12 -05:00
Charles
8c99a8030f Fix more actions (#2208) 2026-02-12 09:56:56 -05:00
Lance Pioch
6e53b1cd7d Allow custom ips to still be entered (#2223) 2026-02-12 09:49:54 -05:00
Charles
4042e0416b Revert toolbar change (#2218) 2026-02-11 17:54:58 -05:00
Lance Pioch
cc8973cf00 Laravel 12.51.0 Shift (#2213)
Co-authored-by: Shift <shift@laravelshift.com>
2026-02-11 11:18:33 -05:00
Quinten
8ebe75b947 fix: composer not been installed in the docker image (#2211) 2026-02-10 16:00:18 -05:00
Hythera
f8144407d1 fix: composer content hash (#2209) 2026-02-09 22:26:01 -05:00
Charles
e431ccb66a add rounding to list-files header (#2207) 2026-02-09 22:19:10 -05:00
Lance Pioch
9291bb4477 Fix webhook processing for event objects (#2198) 2026-02-09 08:47:09 -05:00
Lance Pioch
e8c80ae420 Fix SFTP access denied for subuser when view role is assigned (#2196) 2026-02-09 08:46:47 -05:00
stdpi
f1be003276 Change file browser sticky header again... (#2203) 2026-02-08 15:17:48 -05:00
Charles
e532a9a180 composer upgrade (#2167)
Co-authored-by: Lance Pioch <git@lance.sh>
2026-02-07 14:33:51 -05:00
Charles
41fdd7bc8e Exclude create client api key button (#2169) 2026-02-07 14:33:32 -05:00
Lance Pioch
9b01203b7c Add per-user toggle to redirect admins to /admin after login (#2191) 2026-02-07 13:21:14 -05:00
Lance Pioch
ab4eadec32 Fix Exporting an egg in yaml format (#2172) 2026-02-07 08:10:00 -05:00
Lance Pioch
789c4c7284 Localize email notifications (#2043) (#2178) 2026-02-06 10:37:15 -05:00
Lance Pioch
b1a39f1724 Handle X-Forwarded-Proto in .htaccess for SSL-terminating proxies (#2171) 2026-02-06 09:54:24 -05:00
Lance Pioch
6a548c09a0 Clarify OAuth error when provider account has no linked email (#2179) 2026-02-06 07:50:37 -05:00
Lance Pioch
55bda569cc Implement flexible caching for node statuses (#2174) 2026-02-06 07:50:20 -05:00
Lance Pioch
adf1249086 Fix Egg Feature modals not working (#2175) 2026-02-06 07:49:56 -05:00
Lance Pioch
dbf77bf146 Implement single file move to support Unix mv semantics (#1984) (#2176) 2026-02-06 07:49:40 -05:00
Frogperson
a34bf9fd49 Add Daemon Base Directory field (#2151)
Co-authored-by: Boy132 <mail@boy132.de>
2026-02-05 08:00:25 -05:00
Boy132
7a9deba0e1 Fix notifications for DeleteAction on EditEgg page (#2165) 2026-02-04 22:20:22 +01:00
Charles
159bfe2210 exclude node actions (#2164) 2026-02-04 06:48:13 -05:00
stdpi
a821db8aae Improve file browser UI (#2086) 2026-02-04 05:40:45 -05:00
Lance Pioch
1556f8efb8 Allow all permissions to be toggled at once for api tokens (#2154) 2026-02-02 08:41:10 -05:00
Lance Pioch
57c2aa6f21 Fix the tabbing for username to password on login (#2155)
Co-authored-by: notCharles <charles@pelican.dev>
2026-02-02 08:40:55 -05:00
Charles
36de4c3786 composer update (#2161) 2026-01-31 19:37:54 -05:00
Boy132
26312e3897 Add basic api for plugins (#2146) 2026-02-01 00:10:57 +01:00
Boy132
a477c89025 Move username sanitization to model and make it less strict (#2150) 2026-02-01 00:07:26 +01:00
Boy132
93e81c26a9 Send server id to wings (#2157) 2026-01-31 22:54:06 +01:00
Boy132
23e91e8df3 Fix "visit website" button being invisible (#2158) 2026-01-31 22:53:56 +01:00
Boy132
833294bfaf Invisible button and tooltip fixes (#2149) 2026-01-29 15:37:05 +01:00
Lance Pioch
abaeeff86d Laravel 12.49.0 Shift (#2145)
Co-authored-by: Shift <shift@laravelshift.com>
2026-01-27 23:40:20 -05:00
Charles
dd77555c42 Add tooltips to actions across admin area (#2134)
Co-authored-by: Boy132 <mail@boy132.de>
2026-01-27 20:07:18 -05:00
Boy132
297ecb544d Replace icon strings with enum (#2113) 2026-01-27 11:36:07 +01:00
Boy132
e14bb7d030 Fix oauth provider "enabled" checks (#2142) 2026-01-27 11:27:19 +01:00
Boy132
c770937880 Migration to convert former stock egg uuids (#2108) 2026-01-23 16:40:24 +01:00
Boy132
426643eaa6 Add allocation to role permission models & make sure user can target node of allocation (#2124) 2026-01-23 16:37:01 +01:00
Boy132
3ca0f64e6e Set failed plugin installs to "not_installed" instead of errored (#2129) 2026-01-23 16:36:38 +01:00
Michael (Parker) Parker
8e8ce3b50f fix plugins in entrypoint (#2122) 2026-01-19 09:15:18 -05:00
219 changed files with 9082 additions and 2211 deletions

View File

@@ -26,7 +26,7 @@ jobs:
strategy:
fail-fast: true
matrix:
php: [8.2, 8.3, 8.4, 8.5]
php: [8.3, 8.4, 8.5]
env:
DB_CONNECTION: sqlite
DB_DATABASE: testing.sqlite
@@ -79,8 +79,8 @@ jobs:
strategy:
fail-fast: true
matrix:
php: [8.2, 8.3, 8.4, 8.5]
database: ["mysql:8"]
php: [8.5]
database: ["mysql:8.4", "mysql:9.6"]
services:
database:
image: ${{ matrix.database }}
@@ -147,8 +147,8 @@ jobs:
strategy:
fail-fast: true
matrix:
php: [8.2, 8.3, 8.4, 8.5]
database: ["mariadb:10.6", "mariadb:10.11", "mariadb:11.4"]
php: [8.5]
database: ["mariadb:10.11", "mariadb:11.4"]
services:
database:
image: ${{ matrix.database }}
@@ -215,8 +215,8 @@ jobs:
strategy:
fail-fast: true
matrix:
php: [8.2, 8.3, 8.4, 8.5]
database: ["postgres:14"]
php: [8.5]
database: ["postgres:17", "postgres:18"]
services:
database:
image: ${{ matrix.database }}

View File

@@ -68,6 +68,8 @@ RUN apk add --no-cache \
# required for installing plugins. Pulled from https://github.com/pelican-dev/panel/pull/2034
zip unzip 7zip bzip2-dev yarn git
# Copy composer binary for runtime plugin dependency management
COPY --from=composer /usr/local/bin/composer /usr/local/bin/composer
COPY --chown=root:www-data --chmod=770 --from=composerbuild /build .
COPY --chown=root:www-data --chmod=770 --from=yarnbuild /build/public ./public
@@ -83,8 +85,7 @@ RUN mkdir -p /pelican-data/storage /pelican-data/plugins /var/run/supervisord \
# Allow www-data write permissions where necessary
&& chown -R www-data: /pelican-data .env ./storage ./plugins ./bootstrap/cache /var/run/supervisord /var/www/html/public/storage \
&& chmod -R 770 /pelican-data ./storage ./bootstrap/cache /var/run/supervisord \
&& chown -R www-data: /usr/local/etc/php/ /usr/local/etc/php-fpm.d/
&& chown -R www-data: /usr/local/etc/php/ /usr/local/etc/php-fpm.d/ /var/www/html/composer.json /var/www/html/composer.lock
# Configure Supervisor
COPY docker/supervisord.conf /etc/supervisord.conf
COPY docker/Caddyfile /etc/caddy/Caddyfile

View File

@@ -73,6 +73,8 @@ RUN apk add --no-cache \
# required for installing plugins. Pulled from https://github.com/pelican-dev/panel/pull/2034
zip unzip 7zip bzip2-dev yarn git
# Copy composer binary for runtime plugin dependency management
COPY --from=composer /usr/local/bin/composer /usr/local/bin/composer
COPY --chown=root:www-data --chmod=770 --from=composerbuild /build .
COPY --chown=root:www-data --chmod=770 --from=yarnbuild /build/public ./public
@@ -88,7 +90,7 @@ RUN mkdir -p /pelican-data/storage /pelican-data/plugins /var/run/supervisord \
# Allow www-data write permissions where necessary
&& chown -R www-data: /pelican-data .env ./storage ./plugins ./bootstrap/cache /var/run/supervisord /var/www/html/public/storage \
&& chmod -R 770 /pelican-data ./storage ./bootstrap/cache /var/run/supervisord \
&& chown -R www-data: /usr/local/etc/php/ /usr/local/etc/php-fpm.d/
&& chown -R www-data: /usr/local/etc/php/ /usr/local/etc/php-fpm.d/ /var/www/html/composer.json /var/www/html/composer.lock
# Configure Supervisor
COPY docker/supervisord.conf /etc/supervisord.conf

View File

@@ -0,0 +1,48 @@
<?php
namespace App\Console\Commands\Dev;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
class GenerateTablerIconsEnum extends Command
{
protected $signature = 'dev:generate-tabler-icons-enum';
protected $description = 'Generate an enum for tabler icons based on the secondnetwork/blade-tabler-icons svgs';
public function handle(): void
{
$files = File::files(base_path('vendor/secondnetwork/blade-tabler-icons/resources/svg'));
$files = array_filter($files, fn ($file) => $file->getExtension() === 'svg');
$enumContent = "<?php\n\n";
$enumContent .= "namespace App\\Enums;\n\n";
$enumContent .= "enum TablerIcon: string\n{\n";
foreach ($files as $file) {
$filename = pathinfo($file->getFilename(), PATHINFO_FILENAME);
// Letter V is duplicate, as "letter-v" and "letter-letter-v"
if (str($filename)->contains('letter-letter')) {
continue;
}
// Filled icons exist with "-f" and "-filled", we only want the later
if (str($filename)->endsWith('-f') && file_exists(base_path("vendor/secondnetwork/blade-tabler-icons/resources/svg/{$filename}illed.svg"))) {
continue;
}
$caseName = str($filename)->title()->replace('-', '');
$value = str($filename)->slug()->prepend('tabler-');
$enumContent .= " case $caseName = '$value';\n";
}
$enumContent .= "}\n";
File::put(base_path('app/Enums/TablerIcon.php'), $enumContent);
$this->info('Enum generated');
}
}

View File

@@ -8,7 +8,6 @@ use App\Services\Eggs\Sharing\EggExporterService;
use Exception;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Http;
use JsonException;
use Symfony\Component\Yaml\Yaml;
class CheckEggUpdatesCommand extends Command
@@ -22,14 +21,12 @@ class CheckEggUpdatesCommand extends Command
try {
$this->check($egg, $exporterService);
} catch (Exception $exception) {
$this->error("{$egg->name}: Error ({$exception->getMessage()})");
$this->error("$egg->name: Error ({$exception->getMessage()})");
}
}
}
/**
* @throws JsonException
*/
/** @throws Exception */
private function check(Egg $egg, EggExporterService $exporterService): void
{
if (is_null($egg->update_url)) {
@@ -45,7 +42,13 @@ class CheckEggUpdatesCommand extends Command
? Yaml::parse($exporterService->handle($egg->id, EggFormat::YAML))
: json_decode($exporterService->handle($egg->id, EggFormat::JSON), true);
$remote = Http::timeout(5)->connectTimeout(1)->get($egg->update_url)->throw()->body();
$remote = Http::timeout(5)->connectTimeout(1)->get($egg->update_url);
if ($remote->failed()) {
throw new Exception("HTTP request returned status code {$remote->status()}");
}
$remote = $remote->body();
$remote = $isYaml ? Yaml::parse($remote) : json_decode($remote, true);
unset($local['exported_at'], $remote['exported_at']);

View File

@@ -16,7 +16,7 @@ class DisablePluginCommand extends Command
{
$id = $this->argument('id') ?? $this->choice('Plugin', Plugin::pluck('name', 'id')->toArray());
$plugin = Plugin::find($id);
$plugin = Plugin::find(str($id)->lower()->toString());
if (!$plugin) {
$this->error('Plugin does not exist!');

View File

@@ -18,7 +18,7 @@ class InstallPluginCommand extends Command
{
$id = $this->argument('id') ?? $this->choice('Plugin', Plugin::pluck('name', 'id')->toArray());
$plugin = Plugin::find($id);
$plugin = Plugin::find(str($id)->lower()->toString());
if (!$plugin) {
$this->error('Plugin does not exist!');

View File

@@ -18,7 +18,7 @@ class UninstallPluginCommand extends Command
{
$id = $this->argument('id') ?? $this->choice('Plugin', Plugin::pluck('name', 'id')->toArray());
$plugin = Plugin::find($id);
$plugin = Plugin::find(str($id)->lower()->toString());
if (!$plugin) {
$this->error('Plugin does not exist!');

View File

@@ -17,7 +17,7 @@ class UpdatePluginCommand extends Command
{
$id = $this->argument('id') ?? $this->choice('Plugin', Plugin::pluck('name', 'id')->toArray());
$plugin = Plugin::find($id);
$plugin = Plugin::find(str($id)->lower()->toString());
if (!$plugin) {
$this->error('Plugin does not exist!');

View File

@@ -2,6 +2,7 @@
namespace App\Enums;
use BackedEnum;
use Filament\Support\Contracts\HasColor;
use Filament\Support\Contracts\HasIcon;
use Filament\Support\Contracts\HasLabel;
@@ -12,12 +13,12 @@ enum BackupStatus: string implements HasColor, HasIcon, HasLabel
case Successful = 'successful';
case Failed = 'failed';
public function getIcon(): string
public function getIcon(): BackedEnum
{
return match ($this) {
self::InProgress => 'tabler-circle-dashed',
self::Successful => 'tabler-circle-check',
self::Failed => 'tabler-circle-x',
self::InProgress => TablerIcon::CircleDashed,
self::Successful => TablerIcon::CircleCheck,
self::Failed => TablerIcon::CircleX,
};
}

View File

@@ -2,6 +2,7 @@
namespace App\Enums;
use BackedEnum;
use Filament\Support\Contracts\HasColor;
use Filament\Support\Contracts\HasIcon;
use Filament\Support\Contracts\HasLabel;
@@ -23,20 +24,20 @@ enum ContainerStatus: string implements HasColor, HasIcon, HasLabel
// HTTP Based
case Missing = 'missing';
public function getIcon(): string
public function getIcon(): BackedEnum
{
return match ($this) {
self::Created => 'tabler-heart-plus',
self::Starting => 'tabler-heart-up',
self::Running => 'tabler-heartbeat',
self::Restarting => 'tabler-heart-bolt',
self::Exited => 'tabler-heart-exclamation',
self::Paused => 'tabler-heart-pause',
self::Dead, self::Offline => 'tabler-heart-x',
self::Removing => 'tabler-heart-down',
self::Missing => 'tabler-heart-search',
self::Stopping => 'tabler-heart-minus',
self::Created => TablerIcon::HeartPlus,
self::Starting => TablerIcon::HeartUp,
self::Running => TablerIcon::Heartbeat,
self::Restarting => TablerIcon::HeartBolt,
self::Exited => TablerIcon::HeartExclamation,
self::Paused => TablerIcon::HeartPause,
self::Dead, self::Offline => TablerIcon::HeartX,
self::Removing => TablerIcon::HeartDown,
self::Missing => TablerIcon::HeartSearch,
self::Stopping => TablerIcon::HeartMinus,
};
}

View File

@@ -11,6 +11,9 @@ enum CustomizationKey: string
case TopNavigation = 'top_navigation';
case DashboardLayout = 'dashboard_layout';
case ButtonStyle = 'button_style';
case RedirectToAdmin = 'redirect_to_admin';
public function getDefaultValue(): string|int|bool
{
return match ($this) {
@@ -20,6 +23,8 @@ enum CustomizationKey: string
self::ConsoleGraphPeriod => 30,
self::TopNavigation => config('panel.filament.default-navigation', 'sidebar'),
self::DashboardLayout => 'grid',
self::ButtonStyle => true,
self::RedirectToAdmin => false,
};
}

View File

@@ -2,6 +2,7 @@
namespace App\Enums;
use BackedEnum;
use Filament\Support\Contracts\HasIcon;
use Filament\Support\Contracts\HasLabel;
@@ -11,12 +12,12 @@ enum PluginCategory: string implements HasIcon, HasLabel
case Theme = 'theme';
case Language = 'language';
public function getIcon(): string
public function getIcon(): BackedEnum
{
return match ($this) {
self::Plugin => 'tabler-package',
self::Theme => 'tabler-palette',
self::Language => 'tabler-language',
self::Plugin => TablerIcon::Package,
self::Theme => TablerIcon::Palette,
self::Language => TablerIcon::Language,
};
}

View File

@@ -2,6 +2,7 @@
namespace App\Enums;
use BackedEnum;
use Filament\Support\Contracts\HasColor;
use Filament\Support\Contracts\HasIcon;
use Filament\Support\Contracts\HasLabel;
@@ -14,14 +15,14 @@ enum PluginStatus: string implements HasColor, HasIcon, HasLabel
case Errored = 'errored';
case Incompatible = 'incompatible';
public function getIcon(): string
public function getIcon(): BackedEnum
{
return match ($this) {
self::NotInstalled => 'tabler-heart-off',
self::Disabled => 'tabler-heart-x',
self::Enabled => 'tabler-heart-check',
self::Errored => 'tabler-heart-broken',
self::Incompatible => 'tabler-heart-cancel',
self::NotInstalled => TablerIcon::HeartOff,
self::Disabled => TablerIcon::HeartX,
self::Enabled => TablerIcon::HeartCheck,
self::Errored => TablerIcon::HeartBroken,
self::Incompatible => TablerIcon::HeartCancel,
};
}

View File

@@ -5,6 +5,7 @@ namespace App\Enums;
enum RolePermissionModels: string
{
case ApiKey = 'apiKey';
case Allocation = 'allocation';
case DatabaseHost = 'databaseHost';
case Database = 'database';
case Egg = 'egg';
@@ -34,4 +35,9 @@ enum RolePermissionModels: string
{
return RolePermissionPrefixes::Update->value . ' ' . $this->value;
}
public function delete(): string
{
return RolePermissionPrefixes::Delete->value . ' ' . $this->value;
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Enums;
use BackedEnum;
use Filament\Support\Contracts\HasColor;
use Filament\Support\Contracts\HasIcon;
use Filament\Support\Contracts\HasLabel;
@@ -14,14 +15,13 @@ enum ServerState: string implements HasColor, HasIcon, HasLabel
case Suspended = 'suspended';
case RestoringBackup = 'restoring_backup';
public function getIcon(): string
public function getIcon(): BackedEnum
{
return match ($this) {
self::Installing => 'tabler-heart-bolt',
self::InstallFailed => 'tabler-heart-x',
self::ReinstallFailed => 'tabler-heart-x',
self::Suspended => 'tabler-heart-cancel',
self::RestoringBackup => 'tabler-heart-up',
self::Installing => TablerIcon::HeartBolt,
self::InstallFailed, self::ReinstallFailed => TablerIcon::HeartX,
self::Suspended => TablerIcon::HeartCancel,
self::RestoringBackup => TablerIcon::HeartUp,
};
}

View File

@@ -2,6 +2,8 @@
namespace App\Enums;
use BackedEnum;
enum SubuserPermission: string
{
case WebsocketConnect = 'websocket.connect';
@@ -67,21 +69,21 @@ enum SubuserPermission: string
return $this === self::WebsocketConnect;
}
public function getIcon(): ?string
public function getIcon(): ?BackedEnum
{
[$group, $permission] = $this->split();
return match ($group) {
'control' => 'tabler-terminal-2',
'user' => 'tabler-users',
'file' => 'tabler-files',
'backup' => 'tabler-file-zip',
'allocation' => 'tabler-network',
'startup' => 'tabler-player-play',
'database' => 'tabler-database',
'schedule' => 'tabler-clock',
'settings' => 'tabler-settings',
'activity' => 'tabler-stack',
'control' => TablerIcon::Terminal2,
'user' => TablerIcon::Users,
'file' => TablerIcon::Files,
'backup' => TablerIcon::FileZip,
'allocation' => TablerIcon::Network,
'startup' => TablerIcon::PlayerPlay,
'database' => TablerIcon::Database,
'schedule' => TablerIcon::Clock,
'settings' => TablerIcon::Settings,
'activity' => TablerIcon::Stack,
default => null,
};
}

5997
app/Enums/TablerIcon.php Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,7 @@
namespace App\Enums;
use BackedEnum;
use Filament\Support\Contracts\HasColor;
use Filament\Support\Contracts\HasIcon;
use Filament\Support\Contracts\HasLabel;
@@ -24,11 +25,11 @@ enum WebhookType: string implements HasColor, HasIcon, HasLabel
};
}
public function getIcon(): string
public function getIcon(): BackedEnum
{
return match ($this) {
self::Regular => 'tabler-world-www',
self::Discord => 'tabler-brand-discord',
self::Regular => TablerIcon::WorldWww,
self::Discord => TablerIcon::BrandDiscord,
};
}
}

View File

@@ -1,16 +0,0 @@
<?php
namespace App\Exceptions;
use App\Exceptions\Solutions\ManifestDoesNotExistSolution;
use Exception;
use Spatie\Ignition\Contracts\ProvidesSolution;
use Spatie\Ignition\Contracts\Solution;
class ManifestDoesNotExistException extends Exception implements ProvidesSolution
{
public function getSolution(): Solution
{
return new ManifestDoesNotExistSolution();
}
}

View File

@@ -0,0 +1,7 @@
<?php
namespace App\Exceptions;
use Exception;
class PluginIdMismatchException extends Exception {}

View File

@@ -1,25 +0,0 @@
<?php
namespace App\Exceptions\Solutions;
use Spatie\Ignition\Contracts\Solution;
class ManifestDoesNotExistSolution implements Solution
{
public function getSolutionTitle(): string
{
return "The manifest.json file hasn't been generated yet";
}
public function getSolutionDescription(): string
{
return 'Run yarn run build:production to build the frontend first.';
}
public function getDocumentationLinks(): array
{
return [
'Docs' => 'https://github.com/pelican/panel/blob/master/package.json',
];
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Extensions\Captcha\Schemas;
use BackedEnum;
use Filament\Schemas\Components\Component;
interface CaptchaSchemaInterface
@@ -24,7 +25,7 @@ interface CaptchaSchemaInterface
*/
public function getSettingsForm(): array;
public function getIcon(): ?string;
public function getIcon(): null|string|BackedEnum;
public function validateResponse(?string $captchaResponse = null): void;
}

View File

@@ -2,8 +2,10 @@
namespace App\Extensions\Captcha\Schemas\Turnstile;
use App\Enums\TablerIcon;
use App\Extensions\Captcha\Schemas\BaseSchema;
use App\Extensions\Captcha\Schemas\CaptchaSchemaInterface;
use BackedEnum;
use Exception;
use Filament\Forms\Components\Toggle;
use Filament\Infolists\Components\TextEntry;
@@ -49,8 +51,8 @@ class TurnstileSchema extends BaseSchema implements CaptchaSchemaInterface
->label(trans('admin/setting.captcha.verify'))
->columnSpan(2)
->inline(false)
->onIcon('tabler-check')
->offIcon('tabler-x')
->onIcon(TablerIcon::Check)
->offIcon(TablerIcon::X)
->onColor('success')
->offColor('danger')
->default(env('CAPTCHA_TURNSTILE_VERIFY_DOMAIN', true)),
@@ -61,9 +63,9 @@ class TurnstileSchema extends BaseSchema implements CaptchaSchemaInterface
]);
}
public function getIcon(): ?string
public function getIcon(): BackedEnum
{
return 'tabler-brand-cloudflare';
return TablerIcon::BrandCloudflare;
}
/**

View File

@@ -3,6 +3,7 @@
namespace App\Extensions\Features\Schemas;
use App\Enums\SubuserPermission;
use App\Enums\TablerIcon;
use App\Extensions\Features\FeatureSchemaInterface;
use App\Facades\Activity;
use App\Models\Server;
@@ -73,7 +74,7 @@ class GSLTokenSchema implements FeatureSchemaInterface
}
},
])
->hintIcon('tabler-code', fn () => implode('|', $serverVariable->variable->rules))
->hintIcon(TablerIcon::Code, fn () => implode('|', $serverVariable->variable->rules))
->label(fn () => $serverVariable->variable->name)
->prefix(fn () => '{{' . $serverVariable->variable->env_variable . '}}')
->helperText(fn () => empty($serverVariable->variable->description) ? '—' : $serverVariable->variable->description),

View File

@@ -2,6 +2,7 @@
namespace App\Extensions\Features\Schemas;
use App\Enums\TablerIcon;
use App\Extensions\Features\FeatureSchemaInterface;
use Filament\Actions\Action;
use Illuminate\Support\Facades\Blade;
@@ -31,7 +32,7 @@ class PIDLimitSchema implements FeatureSchemaInterface
{
return Action::make($this->getId())
->requiresConfirmation()
->icon('tabler-alert-triangle')
->icon(TablerIcon::AlertTriangle)
->modalHeading(fn () => user()?->isAdmin() ? 'Memory or process limit reached...' : 'Possible resource limit reached...')
->modalDescription(new HtmlString(Blade::render(
user()?->isAdmin() ? <<<'HTML'

View File

@@ -3,6 +3,7 @@
namespace App\Extensions\OAuth;
use App\Models\User;
use BackedEnum;
use Filament\Schemas\Components\Component;
use Filament\Schemas\Components\Wizard\Step;
use Laravel\Socialite\Contracts\User as OAuthUser;
@@ -29,7 +30,7 @@ interface OAuthSchemaInterface
/** @return Step[] */
public function getSetupSteps(): array;
public function getIcon(): ?string;
public function getIcon(): null|string|BackedEnum;
public function getHexColor(): ?string;

View File

@@ -2,6 +2,8 @@
namespace App\Extensions\OAuth\Schemas;
use App\Enums\TablerIcon;
use BackedEnum;
use Filament\Forms\Components\TextInput;
use Filament\Infolists\Components\TextEntry;
use Filament\Schemas\Components\Wizard\Step;
@@ -33,9 +35,9 @@ final class BitbucketSchema extends OAuthSchema
], parent::getSetupSteps());
}
public function getIcon(): string
public function getIcon(): BackedEnum
{
return 'tabler-brand-bitbucket-f';
return TablerIcon::BrandBitbucketFilled;
}
public function getHexColor(): string

View File

@@ -2,13 +2,15 @@
namespace App\Extensions\OAuth\Schemas;
use BackedEnum;
final class CommonSchema extends OAuthSchema
{
public function __construct(
private readonly string $id,
private readonly ?string $name = null,
private readonly ?string $configName = null,
private readonly ?string $icon = null,
private readonly null|string|BackedEnum $icon = null,
private readonly ?string $hexColor = null,
) {}
@@ -27,7 +29,7 @@ final class CommonSchema extends OAuthSchema
return $this->configName ?? parent::getConfigKey();
}
public function getIcon(): ?string
public function getIcon(): null|string|BackedEnum
{
return $this->icon;
}

View File

@@ -2,6 +2,8 @@
namespace App\Extensions\OAuth\Schemas;
use App\Enums\TablerIcon;
use BackedEnum;
use Filament\Forms\Components\TextInput;
use Filament\Infolists\Components\TextEntry;
use Filament\Schemas\Components\Wizard\Step;
@@ -42,9 +44,9 @@ final class DiscordSchema extends OAuthSchema
], parent::getSetupSteps());
}
public function getIcon(): string
public function getIcon(): BackedEnum
{
return 'tabler-brand-discord-f';
return TablerIcon::BrandDiscordFilled;
}
public function getHexColor(): string

View File

@@ -2,6 +2,8 @@
namespace App\Extensions\OAuth\Schemas;
use App\Enums\TablerIcon;
use BackedEnum;
use Filament\Forms\Components\TextInput;
use Filament\Infolists\Components\TextEntry;
use Filament\Schemas\Components\Wizard\Step;
@@ -36,9 +38,9 @@ final class FacebookSchema extends OAuthSchema
], parent::getSetupSteps());
}
public function getIcon(): string
public function getIcon(): BackedEnum
{
return 'tabler-brand-facebook-f';
return TablerIcon::BrandFacebookFilled;
}
public function getHexColor(): string

View File

@@ -2,6 +2,8 @@
namespace App\Extensions\OAuth\Schemas;
use App\Enums\TablerIcon;
use BackedEnum;
use Filament\Forms\Components\TextInput;
use Filament\Infolists\Components\TextEntry;
use Filament\Schemas\Components\Wizard\Step;
@@ -42,9 +44,9 @@ final class GithubSchema extends OAuthSchema
], parent::getSetupSteps());
}
public function getIcon(): string
public function getIcon(): BackedEnum
{
return 'tabler-brand-github-f';
return TablerIcon::BrandGithubFilled;
}
public function getHexColor(): string

View File

@@ -2,6 +2,8 @@
namespace App\Extensions\OAuth\Schemas;
use App\Enums\TablerIcon;
use BackedEnum;
use Filament\Forms\Components\TextInput;
use Filament\Infolists\Components\TextEntry;
use Filament\Schemas\Components\Wizard\Step;
@@ -53,9 +55,9 @@ final class GitlabSchema extends OAuthSchema
], parent::getSetupSteps());
}
public function getIcon(): string
public function getIcon(): BackedEnum
{
return 'tabler-brand-gitlab';
return TablerIcon::BrandGitlab;
}
public function getHexColor(): string

View File

@@ -2,6 +2,8 @@
namespace App\Extensions\OAuth\Schemas;
use App\Enums\TablerIcon;
use BackedEnum;
use Filament\Forms\Components\TextInput;
use Filament\Infolists\Components\TextEntry;
use Filament\Schemas\Components\Wizard\Step;
@@ -42,9 +44,9 @@ final class GoogleSchema extends OAuthSchema
], parent::getSetupSteps());
}
public function getIcon(): string
public function getIcon(): BackedEnum
{
return 'tabler-brand-google-f';
return TablerIcon::BrandGoogleFilled;
}
public function getHexColor(): string

View File

@@ -2,6 +2,8 @@
namespace App\Extensions\OAuth\Schemas;
use App\Enums\TablerIcon;
use BackedEnum;
use Filament\Forms\Components\TextInput;
use Filament\Infolists\Components\TextEntry;
use Filament\Schemas\Components\Wizard\Step;
@@ -33,9 +35,9 @@ final class LinkedinSchema extends OAuthSchema
], parent::getSetupSteps());
}
public function getIcon(): string
public function getIcon(): BackedEnum
{
return 'tabler-brand-linkedin-f';
return TablerIcon::BrandLinkedinFilled;
}
public function getHexColor(): string

View File

@@ -2,8 +2,10 @@
namespace App\Extensions\OAuth\Schemas;
use App\Enums\TablerIcon;
use App\Extensions\OAuth\OAuthSchemaInterface;
use App\Models\User;
use BackedEnum;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Schemas\Components\Component;
@@ -61,8 +63,8 @@ abstract class OAuthSchema implements OAuthSchemaInterface
->label(trans('admin/setting.oauth.create_missing_users'))
->columnSpan(2)
->inline(false)
->onIcon('tabler-check')
->offIcon('tabler-x')
->onIcon(TablerIcon::Check)
->offIcon(TablerIcon::X)
->onColor('success')
->offColor('danger')
->formatStateUsing(fn ($state) => (bool) $state)
@@ -72,8 +74,8 @@ abstract class OAuthSchema implements OAuthSchemaInterface
->label(trans('admin/setting.oauth.link_missing_users'))
->columnSpan(2)
->inline(false)
->onIcon('tabler-check')
->offIcon('tabler-x')
->onIcon(TablerIcon::Check)
->offIcon(TablerIcon::X)
->onColor('success')
->offColor('danger')
->formatStateUsing(fn ($state) => (bool) $state)
@@ -106,7 +108,7 @@ abstract class OAuthSchema implements OAuthSchemaInterface
return "OAUTH_{$id}_ENABLED";
}
public function getIcon(): ?string
public function getIcon(): null|string|BackedEnum
{
return null;
}
@@ -118,9 +120,7 @@ abstract class OAuthSchema implements OAuthSchemaInterface
public function isEnabled(): bool
{
$id = Str::upper($this->getId());
return env("OAUTH_{$id}_ENABLED", false);
return env($this->getConfigKey(), false);
}
public function shouldCreateMissingUser(OAuthUser $user): bool

View File

@@ -2,6 +2,8 @@
namespace App\Extensions\OAuth\Schemas;
use App\Enums\TablerIcon;
use BackedEnum;
use Filament\Forms\Components\TextInput;
use Filament\Infolists\Components\TextEntry;
use Filament\Schemas\Components\Wizard\Step;
@@ -33,9 +35,9 @@ final class SlackSchema extends OAuthSchema
], parent::getSetupSteps());
}
public function getIcon(): string
public function getIcon(): BackedEnum
{
return 'tabler-brand-slack';
return TablerIcon::BrandSlack;
}
public function getHexColor(): string

View File

@@ -2,6 +2,8 @@
namespace App\Extensions\OAuth\Schemas;
use App\Enums\TablerIcon;
use BackedEnum;
use Filament\Forms\Components\TextInput;
use Filament\Infolists\Components\TextEntry;
use Filament\Schemas\Components\Wizard\Step;
@@ -59,9 +61,9 @@ final class SteamSchema extends OAuthSchema
], parent::getSetupSteps());
}
public function getIcon(): string
public function getIcon(): BackedEnum
{
return 'tabler-brand-steam-f';
return TablerIcon::BrandSteamFilled;
}
public function getHexColor(): string

View File

@@ -2,6 +2,8 @@
namespace App\Extensions\OAuth\Schemas;
use App\Enums\TablerIcon;
use BackedEnum;
use Filament\Forms\Components\TextInput;
use Filament\Infolists\Components\TextEntry;
use Filament\Schemas\Components\Wizard\Step;
@@ -42,9 +44,9 @@ final class XSchema extends OAuthSchema
], parent::getSetupSteps());
}
public function getIcon(): string
public function getIcon(): BackedEnum
{
return 'tabler-brand-x';
return TablerIcon::BrandX;
}
public function getHexColor(): string

View File

@@ -2,12 +2,14 @@
namespace App\Filament\Admin\Pages;
use App\Enums\TablerIcon;
use App\Services\Helpers\SoftwareVersionService;
use BackedEnum;
use Filament\Pages\Dashboard as BaseDashboard;
class Dashboard extends BaseDashboard
{
protected static string|\BackedEnum|null $navigationIcon = 'tabler-layout-dashboard';
protected static string|BackedEnum|null $navigationIcon = TablerIcon::LayoutDashboard;
private SoftwareVersionService $softwareVersionService;

View File

@@ -2,11 +2,12 @@
namespace App\Filament\Admin\Pages;
use App\Enums\TablerIcon;
use BackedEnum;
use Carbon\Carbon;
use Filament\Actions\Action;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Filament\Support\Enums\IconSize;
use Illuminate\Support\Facades\Artisan;
use Spatie\Health\Commands\RunHealthChecksCommand;
use Spatie\Health\Enums\Status;
@@ -14,7 +15,7 @@ use Spatie\Health\ResultStores\ResultStore;
class Health extends Page
{
protected static string|\BackedEnum|null $navigationIcon = 'tabler-heart';
protected static string|BackedEnum|null $navigationIcon = TablerIcon::Heart;
protected string $view = 'filament.pages.health';
@@ -47,9 +48,9 @@ class Health extends Page
{
return [
Action::make('refresh')
->label(trans('admin/health.refresh'))
->iconButton()->iconSize(IconSize::ExtraLarge)
->icon('tabler-refresh')
->hiddenLabel()
->tooltip(trans('admin/health.refresh'))
->icon(TablerIcon::Refresh)
->action('refresh'),
];
}
@@ -128,16 +129,16 @@ class Health extends Page
return trans('admin/health.checks.failed', ['checks' => implode(', ', $failedNames)]);
}
public static function getNavigationIcon(): string
public static function getNavigationIcon(): BackedEnum
{
// @phpstan-ignore myCustomRules.forbiddenGlobalFunctions
$results = app(ResultStore::class)->latestResults();
if ($results === null) {
return 'tabler-heart-question';
return TablerIcon::HeartQuestion;
}
return $results->containsFailingCheck() ? 'tabler-heart-exclamation' : 'tabler-heart-check';
return $results->containsFailingCheck() ? TablerIcon::HeartExclamation : TablerIcon::HeartCheck;
}
public function backgroundColor(string $str): string
@@ -162,14 +163,14 @@ class Health extends Page
};
}
public function icon(string $str): string
public function icon(string $str): BackedEnum
{
return match ($str) {
Status::ok()->value => 'tabler-circle-check',
Status::warning()->value => 'tabler-exclamation-circle',
Status::skipped()->value => 'tabler-circle-chevron-right',
Status::failed()->value, Status::crashed()->value => 'tabler-circle-x',
default => 'tabler-help-circle'
Status::ok()->value => TablerIcon::CircleCheck,
Status::warning()->value => TablerIcon::ExclamationCircle,
Status::skipped()->value => TablerIcon::CircleChevronRight,
Status::failed()->value, Status::crashed()->value => TablerIcon::CircleX,
default => TablerIcon::HelpCircle
};
}
}

View File

@@ -2,16 +2,17 @@
namespace App\Filament\Admin\Pages;
use App\Enums\TablerIcon;
use Boquizo\FilamentLogViewer\Actions\DeleteAction;
use Boquizo\FilamentLogViewer\Actions\DownloadAction;
use Boquizo\FilamentLogViewer\Actions\ViewLogAction;
use Boquizo\FilamentLogViewer\Pages\ListLogs as BaseListLogs;
use Boquizo\FilamentLogViewer\Tables\Columns\LevelColumn;
use Boquizo\FilamentLogViewer\Tables\Columns\NameColumn;
use Boquizo\FilamentLogViewer\UseCases\ParseDateUseCase;
use Boquizo\FilamentLogViewer\Utils\Level;
use Filament\Actions\Action;
use Filament\Notifications\Notification;
use Filament\Support\Enums\IconSize;
use Filament\Tables\Table;
use Illuminate\Support\Facades\Http;
@@ -28,7 +29,7 @@ class ListLogs extends BaseListLogs
{
return parent::table($table)
->emptyStateHeading(trans('admin/log.empty_table'))
->emptyStateIcon('tabler-check')
->emptyStateIcon(TablerIcon::Check)
->columns([
NameColumn::make('date'),
LevelColumn::make(Level::ALL)
@@ -46,12 +47,14 @@ class ListLogs extends BaseListLogs
])
->recordActions([
ViewLogAction::make()
->icon('tabler-file-description')->iconSize(IconSize::Large)->iconButton(),
->icon(TablerIcon::FileDescription)->iconButton(),
DownloadAction::make()
->icon('tabler-file-download')->iconSize(IconSize::Large)->iconButton(),
->tooltip(fn ($record) => trans('filament-log-viewer::log.table.actions.download.label', ['log' => ParseDateUseCase::execute($record['date'])]))
->icon(TablerIcon::FileDownload)->iconButton(),
Action::make('uploadLogs')
->hiddenLabel()
->icon('tabler-world-upload')->iconSize(IconSize::Large)->iconButton()
->tooltip(trans('admin/log.actions.upload_tooltip', ['url' => 'logs.pelican.dev']))
->icon(TablerIcon::WorldUpload)
->requiresConfirmation()
->modalHeading(trans('admin/log.actions.upload_logs'))
->modalDescription(fn ($record) => trans('admin/log.actions.upload_logs_description', ['file' => $record['date'], 'url' => 'https://logs.pelican.dev']))
@@ -100,7 +103,7 @@ class ListLogs extends BaseListLogs
->body("{$url}")
->success()
->actions([
Action::make('viewLogs')
Action::make('exclude_viewLogs')
->label(trans('admin/log.actions.view_logs'))
->url($url)
->openUrlInNewTab(true),
@@ -119,7 +122,7 @@ class ListLogs extends BaseListLogs
}
}),
DeleteAction::make()
->iconSize(IconSize::Medium)->iconButton(),
->icon(TablerIcon::Trash)->iconButton(),
]);
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Pages;
use App\Enums\TablerIcon;
use App\Extensions\Avatar\AvatarService;
use App\Extensions\Captcha\CaptchaService;
use App\Extensions\OAuth\OAuthService;
@@ -12,6 +13,8 @@ use App\Traits\Filament\CanCustomizeHeaderActions;
use App\Traits\Filament\CanCustomizeHeaderWidgets;
use App\Traits\Filament\CanCustomizeTabs;
use BackedEnum;
use BladeUI\Icons\Exceptions\SvgNotFound;
use BladeUI\Icons\Factory as IconFactory;
use Exception;
use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
@@ -37,7 +40,6 @@ use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Components\Utilities\Set;
use Filament\Schemas\Contracts\HasSchemas;
use Filament\Schemas\Schema;
use Filament\Support\Enums\IconSize;
use Filament\Support\Enums\Width;
use Illuminate\Http\Client\Factory;
use Illuminate\Support\Arr;
@@ -58,7 +60,7 @@ class Settings extends Page implements HasSchemas
use EnvironmentWriterTrait;
use InteractsWithForms;
protected static string|\BackedEnum|null $navigationIcon = 'tabler-settings';
protected static string|BackedEnum|null $navigationIcon = TablerIcon::Settings;
protected string $view = 'filament.pages.settings';
@@ -68,6 +70,8 @@ class Settings extends Page implements HasSchemas
protected CaptchaService $captchaService;
protected IconFactory $iconFactory;
/** @var array<mixed>|null */
public ?array $data = [];
@@ -76,11 +80,12 @@ class Settings extends Page implements HasSchemas
$this->form->fill();
}
public function boot(OAuthService $oauthService, AvatarService $avatarService, CaptchaService $captchaService): void
public function boot(OAuthService $oauthService, AvatarService $avatarService, CaptchaService $captchaService, IconFactory $iconFactory): void
{
$this->oauthService = $oauthService;
$this->avatarService = $avatarService;
$this->captchaService = $captchaService;
$this->iconFactory = $iconFactory;
}
public static function canAccess(): bool
@@ -120,29 +125,29 @@ class Settings extends Page implements HasSchemas
return [
Tab::make('general')
->label(trans('admin/setting.navigation.general'))
->icon('tabler-home')
->icon(TablerIcon::Home)
->schema($this->generalSettings()),
Tab::make('captcha')
->label(trans('admin/setting.navigation.captcha'))
->icon('tabler-shield')
->icon(TablerIcon::Shield)
->schema($this->captchaSettings())
->columns(1),
Tab::make('mail')
->label(trans('admin/setting.navigation.mail'))
->icon('tabler-mail')
->icon(TablerIcon::Mail)
->schema($this->mailSettings()),
Tab::make('backup')
->label(trans('admin/setting.navigation.backup'))
->icon('tabler-box')
->icon(TablerIcon::Box)
->schema($this->backupSettings()),
Tab::make('oauth')
->label(trans('admin/setting.navigation.oauth'))
->icon('tabler-brand-oauth')
->icon(TablerIcon::BrandOauth)
->schema($this->oauthSettings())
->columns(1),
Tab::make('misc')
->label(trans('admin/setting.navigation.misc'))
->icon('tabler-tool')
->icon(TablerIcon::Tool)
->schema($this->miscSettings()),
];
}
@@ -162,12 +167,12 @@ class Settings extends Page implements HasSchemas
->schema([
TextInput::make('APP_LOGO')
->label(trans('admin/setting.general.app_logo'))
->hintIcon('tabler-question-mark', trans('admin/setting.general.app_logo_help'))
->hintIcon(TablerIcon::QuestionMark, trans('admin/setting.general.app_logo_help'))
->default(env('APP_LOGO'))
->placeholder('/pelican.svg'),
TextInput::make('APP_FAVICON')
->label(trans('admin/setting.general.app_favicon'))
->hintIcon('tabler-question-mark', trans('admin/setting.general.app_favicon_help'))
->hintIcon(TablerIcon::QuestionMark, trans('admin/setting.general.app_favicon_help'))
->required()
->default(env('APP_FAVICON', '/pelican.ico'))
->placeholder('/pelican.ico'),
@@ -178,8 +183,8 @@ class Settings extends Page implements HasSchemas
Toggle::make('APP_DEBUG')
->label(trans('admin/setting.general.debug_mode'))
->inline(false)
->onIcon('tabler-check')
->offIcon('tabler-x')
->onIcon(TablerIcon::Check)
->offIcon(TablerIcon::X)
->onColor('success')
->offColor('danger')
->stateCast(new BooleanStateCast(false))
@@ -196,8 +201,8 @@ class Settings extends Page implements HasSchemas
Toggle::make('FILAMENT_UPLOADABLE_AVATARS')
->label(trans('admin/setting.general.uploadable_avatars'))
->inline(false)
->onIcon('tabler-check')
->offIcon('tabler-x')
->onIcon(TablerIcon::Check)
->offIcon(TablerIcon::X)
->onColor('success')
->offColor('danger')
->stateCast(new BooleanStateCast(false))
@@ -244,16 +249,16 @@ class Settings extends Page implements HasSchemas
->placeholder(trans('admin/setting.general.trusted_proxies_help'))
->default(env('TRUSTED_PROXIES', implode(',', Arr::wrap(config('trustedproxy.proxies')))))
->hintActions([
Action::make('clear')
Action::make('hint_clear')
->label(trans('admin/setting.general.clear'))
->color('danger')
->icon('tabler-trash')
->icon(TablerIcon::Trash)
->requiresConfirmation()
->authorize(fn () => user()?->can('update settings'))
->action(fn (Set $set) => $set('TRUSTED_PROXIES', [])),
Action::make('cloudflare')
Action::make('hint_cloudflare')
->label(trans('admin/setting.general.set_to_cf'))
->icon('tabler-brand-cloudflare')
->icon(TablerIcon::BrandCloudflare)
->authorize(fn () => user()?->can('update settings'))
->action(function (Factory $client, Set $set) {
$ips = collect();
@@ -295,7 +300,7 @@ class Settings extends Page implements HasSchemas
$formFields[] = Section::make($schema->getName())
->columns(5)
->icon($schema->getIcon() ?? 'tabler-shield')
->icon($schema->getIcon() ?? TablerIcon::Shield)
->collapsed(fn () => !$schema->isEnabled())
->collapsible()
->schema([
@@ -349,9 +354,9 @@ class Settings extends Page implements HasSchemas
->live()
->default(env('MAIL_MAILER', config('mail.default')))
->hintAction(
Action::make('test')
Action::make('hint_test')
->label(trans('admin/setting.mail.test_mail'))
->icon('tabler-send')
->icon(TablerIcon::Send)
->hidden(fn (Get $get) => $get('MAIL_MAILER') === 'log')
->authorize(fn () => user()?->can('update settings'))
->action(function (Get $get) {
@@ -541,8 +546,8 @@ class Settings extends Page implements HasSchemas
Toggle::make('AWS_USE_PATH_STYLE_ENDPOINT')
->label(trans('admin/setting.backup.s3.use_path_style_endpoint'))
->inline(false)
->onIcon('tabler-check')
->offIcon('tabler-x')
->onIcon(TablerIcon::Check)
->offIcon(TablerIcon::X)
->onColor('success')
->offColor('danger')
->live()
@@ -563,26 +568,34 @@ class Settings extends Page implements HasSchemas
$oauthSchemas = $this->oauthService->getAll();
foreach ($oauthSchemas as $schema) {
$id = Str::upper($schema->getId());
$key = $schema->getConfigKey();
$icon = $schema->getIcon();
if (is_string($icon)) {
try {
$this->iconFactory->svg($icon);
} catch (SvgNotFound) {
$icon = null;
}
}
$formFields[] = Section::make($schema->getName())
->columns(5)
->icon($schema->getIcon() ?? 'tabler-brand-oauth')
->collapsed(fn () => !env($key, false))
->icon($icon ?? TablerIcon::BrandOauth)
->collapsed(fn () => !$schema->isEnabled())
->collapsible()
->schema([
Hidden::make($key)
->live()
->default(env($key)),
->default($schema->isEnabled()),
Actions::make([
Action::make("disable_oauth_$id")
Action::make('disable_oauth_' . $schema->getId())
->visible(fn (Get $get) => $get($key))
->disabled(fn () => !user()?->can('update settings'))
->label(trans('admin/setting.oauth.disable'))
->color('danger')
->action(fn (Set $set) => $set($key, false)),
Action::make("enable_oauth_$id")
Action::make('enable_oauth_' . $schema->getId())
->visible(fn (Get $get) => !$get($key))
->disabled(fn () => !user()?->can('update settings'))
->label(trans('admin/setting.oauth.enable'))
@@ -627,8 +640,8 @@ class Settings extends Page implements HasSchemas
->schema([
Toggle::make('PANEL_CLIENT_ALLOCATIONS_ENABLED')
->label(trans('admin/setting.misc.auto_allocation.question'))
->onIcon('tabler-check')
->offIcon('tabler-x')
->onIcon(TablerIcon::Check)
->offIcon(TablerIcon::X)
->onColor('success')
->offColor('danger')
->live()
@@ -638,8 +651,8 @@ class Settings extends Page implements HasSchemas
Toggle::make('PANEL_CLIENT_ALLOCATIONS_CREATE_NEW')
->label(trans('admin/setting.misc.auto_allocation.create_new'))
->helperText(trans('admin/setting.misc.auto_allocation.create_new_help'))
->onIcon('tabler-check')
->offIcon('tabler-x')
->onIcon(TablerIcon::Check)
->offIcon(TablerIcon::X)
->onColor('success')
->offColor('danger')
->live()
@@ -672,8 +685,8 @@ class Settings extends Page implements HasSchemas
->schema([
Toggle::make('PANEL_SEND_INSTALL_NOTIFICATION')
->label(trans('admin/setting.misc.mail_notifications.server_installed'))
->onIcon('tabler-check')
->offIcon('tabler-x')
->onIcon(TablerIcon::Check)
->offIcon(TablerIcon::X)
->onColor('success')
->offColor('danger')
->live()
@@ -682,8 +695,8 @@ class Settings extends Page implements HasSchemas
->default(env('PANEL_SEND_INSTALL_NOTIFICATION', config('panel.email.send_install_notification'))),
Toggle::make('PANEL_SEND_REINSTALL_NOTIFICATION')
->label(trans('admin/setting.misc.mail_notifications.server_reinstalled'))
->onIcon('tabler-check')
->offIcon('tabler-x')
->onIcon(TablerIcon::Check)
->offIcon(TablerIcon::X)
->onColor('success')
->offColor('danger')
->live()
@@ -731,8 +744,8 @@ class Settings extends Page implements HasSchemas
Toggle::make('APP_ACTIVITY_HIDE_ADMIN')
->label(trans('admin/setting.misc.activity_log.log_admin'))
->inline(false)
->onIcon('tabler-check')
->offIcon('tabler-x')
->onIcon(TablerIcon::Check)
->offIcon(TablerIcon::X)
->onColor('success')
->offColor('danger')
->live()
@@ -768,8 +781,8 @@ class Settings extends Page implements HasSchemas
->schema([
Toggle::make('PANEL_EDITABLE_SERVER_DESCRIPTIONS')
->label(trans('admin/setting.misc.server.edit_server_desc'))
->onIcon('tabler-check')
->offIcon('tabler-x')
->onIcon(TablerIcon::Check)
->offIcon(TablerIcon::X)
->onColor('success')
->offColor('danger')
->live()
@@ -853,9 +866,10 @@ class Settings extends Page implements HasSchemas
{
return [
Action::make('save')
->iconButton()->iconSize(IconSize::ExtraLarge)
->icon('tabler-device-floppy')
->hiddenLabel()
->icon(TablerIcon::DeviceFloppy)
->action('save')
->tooltip(trans('filament-panels::resources/pages/edit-record.form.actions.save.label'))
->authorize(fn () => user()?->can('update settings'))
->keyBindings(['mod+s']),
];

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Pages;
use App\Enums\TablerIcon;
use App\Traits\ResolvesRecordDate;
use Boquizo\FilamentLogViewer\Actions\BackAction;
use Boquizo\FilamentLogViewer\Actions\DeleteAction;
@@ -9,7 +10,6 @@ use Boquizo\FilamentLogViewer\Actions\DownloadAction;
use Boquizo\FilamentLogViewer\Pages\ViewLog as BaseViewLog;
use Filament\Actions\Action;
use Filament\Notifications\Notification;
use Filament\Support\Enums\IconSize;
use Illuminate\Support\Facades\Http;
class ViewLogs extends BaseViewLog
@@ -20,14 +20,15 @@ class ViewLogs extends BaseViewLog
{
return [
BackAction::make()
->icon('tabler-arrow-left')->iconSize(IconSize::ExtraLarge)->iconButton(),
->tooltip(trans('filament-log-viewer::log.table.actions.close.label'))
->icon(TablerIcon::ArrowLeft)->iconButton(),
DeleteAction::make(withTooltip: true)
->iconSize(IconSize::ExtraLarge)->iconButton(),
->icon(TablerIcon::Trash)->iconButton(),
DownloadAction::make(withTooltip: true)
->icon('tabler-file-download')->iconSize(IconSize::ExtraLarge)->iconButton(),
->icon(TablerIcon::FileDownload)->iconButton(),
Action::make('uploadLogs')
->hiddenLabel()
->icon('tabler-world-upload')->iconSize(IconSize::ExtraLarge)->iconButton()
->icon(TablerIcon::WorldUpload)
->requiresConfirmation()
->tooltip(trans('admin/log.actions.upload_tooltip', ['url' => 'logs.pelican.dev']))
->modalHeading(trans('admin/log.actions.upload_logs'))
@@ -77,7 +78,7 @@ class ViewLogs extends BaseViewLog
->body("{$url}")
->success()
->actions([
Action::make('viewLogs')
Action::make('exclude_viewLogs')
->label(trans('admin/log.actions.view_logs'))
->url($url)
->openUrlInNewTab(true),

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Resources\ApiKeys;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\ApiKeys\Pages\CreateApiKey;
use App\Filament\Admin\Resources\ApiKeys\Pages\ListApiKeys;
use App\Filament\Admin\Resources\Users\Pages\EditUser;
@@ -11,7 +12,9 @@ use App\Traits\Filament\CanCustomizePages;
use App\Traits\Filament\CanCustomizeRelations;
use App\Traits\Filament\CanModifyForm;
use App\Traits\Filament\CanModifyTable;
use BackedEnum;
use Exception;
use Filament\Actions\CreateAction;
use Filament\Actions\DeleteAction;
use Filament\Forms\Components\TagsInput;
use Filament\Forms\Components\Textarea;
@@ -19,8 +22,8 @@ use Filament\Forms\Components\ToggleButtons;
use Filament\Resources\Pages\PageRegistration;
use Filament\Resources\Resource;
use Filament\Schemas\Components\Fieldset;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;
use Filament\Support\Enums\IconSize;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
@@ -34,7 +37,7 @@ class ApiKeyResource extends Resource
protected static ?string $model = ApiKey::class;
protected static string|\BackedEnum|null $navigationIcon = 'tabler-key';
protected static string|BackedEnum|null $navigationIcon = TablerIcon::Key;
public static function getNavigationLabel(): string
{
@@ -77,7 +80,7 @@ class ApiKeyResource extends Resource
->columns([
TextColumn::make('key')
->label(trans('admin/apikey.table.key'))
->icon('tabler-clipboard-text')
->icon(TablerIcon::ClipboardText)
->state(fn (ApiKey $key) => $key->identifier . $key->token)
->copyable(),
TextColumn::make('memo')
@@ -96,10 +99,12 @@ class ApiKeyResource extends Resource
->url(fn (ApiKey $apiKey) => user()?->can('update', $apiKey->user) ? EditUser::getUrl(['record' => $apiKey->user]) : null),
])
->recordActions([
DeleteAction::make()
->iconButton()->iconSize(IconSize::ExtraLarge),
DeleteAction::make(),
])
->emptyStateIcon('tabler-key')
->toolbarActions([
CreateAction::make(),
])
->emptyStateIcon(TablerIcon::Key)
->emptyStateDescription('')
->emptyStateHeading(trans('admin/apikey.empty'));
}
@@ -109,12 +114,44 @@ class ApiKeyResource extends Resource
*/
public static function defaultForm(Schema $schema): Schema
{
$permissionList = ApiKey::getPermissionList();
return $schema
->components([
Section::make(trans('admin/apikey.permissions.all'))
->description(trans('admin/apikey.permissions.all_description'))
->columnSpanFull()
->schema([
ToggleButtons::make('permissions_all')
->hiddenLabel()
->inline()
->options([
0 => trans('admin/apikey.permissions.none'),
1 => trans('admin/apikey.permissions.read'),
3 => trans('admin/apikey.permissions.read_write'),
])
->icons([
0 => TablerIcon::BookOff,
1 => TablerIcon::Book,
3 => TablerIcon::Writing,
])
->colors([
0 => 'success',
1 => 'warning',
3 => 'danger',
])
->live()
->afterStateUpdated(function ($state, callable $set) use ($permissionList) {
foreach ($permissionList as $resource) {
$set('permissions_' . $resource, $state);
}
})
->default(0),
]),
Fieldset::make('Permissions')
->columnSpanFull()
->schema(
collect(ApiKey::getPermissionList())->map(fn ($resource) => ToggleButtons::make('permissions_' . $resource)
collect($permissionList)->map(fn ($resource) => ToggleButtons::make('permissions_' . $resource)
->label(str($resource)->replace('_', ' ')->title())->inline()
->options([
0 => trans('admin/apikey.permissions.none'),
@@ -122,9 +159,9 @@ class ApiKeyResource extends Resource
3 => trans('admin/apikey.permissions.read_write'),
])
->icons([
0 => 'tabler-book-off',
1 => 'tabler-book',
3 => 'tabler-writing',
0 => TablerIcon::BookOff,
1 => TablerIcon::Book,
3 => TablerIcon::Writing,
])
->colors([
0 => 'success',

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Resources\ApiKeys\Pages;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\ApiKeys\ApiKeyResource;
use App\Models\ApiKey;
use App\Traits\Filament\CanCustomizeHeaderActions;
@@ -9,7 +10,6 @@ use App\Traits\Filament\CanCustomizeHeaderWidgets;
use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Resources\Pages\CreateRecord;
use Filament\Support\Enums\IconSize;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
@@ -26,9 +26,12 @@ class CreateApiKey extends CreateRecord
protected function getDefaultHeaderActions(): array
{
return [
$this->getCreateFormAction()->formId('form')
->iconButton()->iconSize(IconSize::ExtraLarge)
->icon('tabler-file-plus'),
Action::make('create')
->hiddenLabel()
->action('create')
->keyBindings(['mod+s'])
->tooltip(trans('filament-panels::resources/pages/create-record.form.actions.create.label'))
->icon(TablerIcon::FilePlus),
];
}

View File

@@ -5,11 +5,7 @@ namespace App\Filament\Admin\Resources\ApiKeys\Pages;
use App\Filament\Admin\Resources\ApiKeys\ApiKeyResource;
use App\Traits\Filament\CanCustomizeHeaderActions;
use App\Traits\Filament\CanCustomizeHeaderWidgets;
use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Actions\CreateAction;
use Filament\Resources\Pages\ListRecords;
use Filament\Support\Enums\IconSize;
class ListApiKeys extends ListRecords
{
@@ -17,14 +13,4 @@ class ListApiKeys extends ListRecords
use CanCustomizeHeaderWidgets;
protected static string $resource = ApiKeyResource::class;
/** @return array<Action|ActionGroup> */
protected function getDefaultHeaderActions(): array
{
return [
CreateAction::make()
->iconButton()->iconSize(IconSize::ExtraLarge)
->icon('tabler-file-plus'),
];
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Resources\DatabaseHosts;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\DatabaseHosts\Pages\CreateDatabaseHost;
use App\Filament\Admin\Resources\DatabaseHosts\Pages\EditDatabaseHost;
use App\Filament\Admin\Resources\DatabaseHosts\Pages\ListDatabaseHosts;
@@ -12,7 +13,10 @@ use App\Traits\Filament\CanCustomizePages;
use App\Traits\Filament\CanCustomizeRelations;
use App\Traits\Filament\CanModifyForm;
use App\Traits\Filament\CanModifyTable;
use BackedEnum;
use Exception;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\CreateAction;
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction;
use Filament\Actions\ViewAction;
@@ -37,7 +41,7 @@ class DatabaseHostResource extends Resource
protected static ?string $model = DatabaseHost::class;
protected static string|\BackedEnum|null $navigationIcon = 'tabler-database';
protected static string|BackedEnum|null $navigationIcon = TablerIcon::Database;
protected static ?string $recordTitleAttribute = 'name';
@@ -94,10 +98,13 @@ class DatabaseHostResource extends Resource
->hidden(fn ($record) => static::getEditAuthorizationResponse($record)->allowed()),
EditAction::make(),
])
->groupedBulkActions([
DeleteBulkAction::make(),
->toolbarActions([
CreateAction::make(),
BulkActionGroup::make([
DeleteBulkAction::make('exclude_bulk_delete'),
]),
])
->emptyStateIcon('tabler-database')
->emptyStateIcon(TablerIcon::Database)
->emptyStateDescription('')
->emptyStateHeading(trans('admin/databasehost.no_database_hosts'));
}

View File

@@ -2,11 +2,13 @@
namespace App\Filament\Admin\Resources\DatabaseHosts\Pages;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\DatabaseHosts\DatabaseHostResource;
use App\Services\Databases\Hosts\HostCreationService;
use App\Traits\Filament\CanCustomizeHeaderActions;
use App\Traits\Filament\CanCustomizeHeaderWidgets;
use Exception;
use Filament\Actions\Action;
use Filament\Forms\Components\Hidden;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
@@ -44,6 +46,17 @@ class CreateDatabaseHost extends CreateRecord
$this->service = $service;
}
protected function getCreateFormAction(): Action
{
$hasFormWrapper = $this->hasFormWrapper();
return Action::make('exclude_create')
->label(trans('filament-panels::resources/pages/create-record.form.actions.create.label'))
->submit($hasFormWrapper ? $this->getSubmitFormLivewireMethodName() : null)
->action($hasFormWrapper ? null : $this->getSubmitFormLivewireMethodName())
->keyBindings(['mod+s']);
}
/** @return Step[]
* @throws Exception
*/
@@ -175,7 +188,7 @@ class CreateDatabaseHost extends CreateRecord
->title(trans('admin/databasehost.error'))
->body($exception->getMessage())
->color('danger')
->icon('tabler-database')
->icon(TablerIcon::Database)
->danger()
->send();

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Resources\DatabaseHosts\Pages;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\DatabaseHosts\DatabaseHostResource;
use App\Models\DatabaseHost;
use App\Services\Databases\Hosts\HostUpdateService;
@@ -12,7 +13,6 @@ use Filament\Actions\ActionGroup;
use Filament\Actions\DeleteAction;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\EditRecord;
use Filament\Support\Enums\IconSize;
use Filament\Support\Exceptions\Halt;
use Illuminate\Database\Eloquent\Model;
use PDOException;
@@ -36,12 +36,14 @@ class EditDatabaseHost extends EditRecord
{
return [
DeleteAction::make()
->label(fn (DatabaseHost $databaseHost) => $databaseHost->databases()->count() > 0 ? trans('admin/databasehost.delete_help') : trans('filament-actions::delete.single.modal.actions.delete.label'))
->disabled(fn (DatabaseHost $databaseHost) => $databaseHost->databases()->count() > 0)
->iconButton()->iconSize(IconSize::ExtraLarge),
$this->getSaveFormAction()->formId('form')
->iconButton()->iconSize(IconSize::ExtraLarge)
->icon('tabler-device-floppy'),
->tooltip(fn (DatabaseHost $databaseHost) => $databaseHost->databases()->count() > 0 ? trans('admin/databasehost.delete_help') : trans('filament-actions::delete.single.modal.actions.delete.label'))
->disabled(fn (DatabaseHost $databaseHost) => $databaseHost->databases()->count() > 0),
Action::make('save')
->hiddenLabel()
->action('save')
->keyBindings(['mod+s'])
->tooltip(trans('filament-panels::resources/pages/edit-record.form.actions.save.label'))
->icon(TablerIcon::DeviceFloppy),
];
}
@@ -63,7 +65,7 @@ class EditDatabaseHost extends EditRecord
->title(trans('admin/databasehost.error'))
->body($exception->getMessage())
->color('danger')
->icon('tabler-database')
->icon(TablerIcon::Database)
->danger()
->send();

View File

@@ -5,11 +5,7 @@ namespace App\Filament\Admin\Resources\DatabaseHosts\Pages;
use App\Filament\Admin\Resources\DatabaseHosts\DatabaseHostResource;
use App\Traits\Filament\CanCustomizeHeaderActions;
use App\Traits\Filament\CanCustomizeHeaderWidgets;
use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Actions\CreateAction;
use Filament\Resources\Pages\ListRecords;
use Filament\Support\Enums\IconSize;
class ListDatabaseHosts extends ListRecords
{
@@ -17,14 +13,4 @@ class ListDatabaseHosts extends ListRecords
use CanCustomizeHeaderWidgets;
protected static string $resource = DatabaseHostResource::class;
/** @return array<Action|ActionGroup> */
protected function getDefaultHeaderActions(): array
{
return [
CreateAction::make()
->iconButton()->iconSize(IconSize::ExtraLarge)
->icon('tabler-file-plus'),
];
}
}

View File

@@ -9,7 +9,6 @@ use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Actions\EditAction;
use Filament\Resources\Pages\ViewRecord;
use Filament\Support\Enums\IconSize;
class ViewDatabaseHost extends ViewRecord
{
@@ -22,8 +21,7 @@ class ViewDatabaseHost extends ViewRecord
protected function getDefaultHeaderActions(): array
{
return [
EditAction::make()
->iconButton()->iconSize(IconSize::ExtraLarge),
EditAction::make(),
];
}
}

View File

@@ -10,7 +10,6 @@ use Filament\Actions\ViewAction;
use Filament\Forms\Components\TextInput;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Schemas\Schema;
use Filament\Support\Enums\IconSize;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
@@ -70,8 +69,7 @@ class DatabasesRelationManager extends RelationManager
->recordActions([
ViewAction::make()
->color('primary'),
DeleteAction::make()
->iconButton()->iconSize(IconSize::ExtraLarge),
DeleteAction::make(),
]);
}
}

View File

@@ -3,6 +3,7 @@
namespace App\Filament\Admin\Resources\Eggs;
use App\Enums\CustomizationKey;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\Eggs\Pages\CreateEgg;
use App\Filament\Admin\Resources\Eggs\Pages\EditEgg;
use App\Filament\Admin\Resources\Eggs\Pages\ListEggs;
@@ -10,6 +11,7 @@ use App\Filament\Admin\Resources\Eggs\RelationManagers\ServersRelationManager;
use App\Models\Egg;
use App\Traits\Filament\CanCustomizePages;
use App\Traits\Filament\CanCustomizeRelations;
use BackedEnum;
use Filament\Resources\Pages\PageRegistration;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Resources\Resource;
@@ -21,7 +23,7 @@ class EggResource extends Resource
protected static ?string $model = Egg::class;
protected static string|\BackedEnum|null $navigationIcon = 'tabler-eggs';
protected static string|BackedEnum|null $navigationIcon = TablerIcon::Eggs;
protected static ?string $recordTitleAttribute = 'name';

View File

@@ -3,6 +3,7 @@
namespace App\Filament\Admin\Resources\Eggs\Pages;
use App\Enums\EditorLanguages;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\Eggs\EggResource;
use App\Filament\Components\Forms\Fields\CopyFrom;
use App\Filament\Components\Forms\Fields\MonacoEditor;
@@ -28,7 +29,6 @@ use Filament\Schemas\Components\Tabs\Tab;
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Components\Utilities\Set;
use Filament\Schemas\Schema;
use Filament\Support\Enums\IconSize;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
use Illuminate\Validation\Rules\Unique;
@@ -47,9 +47,12 @@ class CreateEgg extends CreateRecord
protected function getDefaultHeaderActions(): array
{
return [
$this->getCreateFormAction()->formId('form')
->iconButton()->iconSize(IconSize::ExtraLarge)
->icon('tabler-file-plus'),
Action::make('create')
->hiddenLabel()
->action('create')
->keyBindings(['mod+s'])
->tooltip(trans('filament-panels::resources/pages/create-record.form.actions.create.label'))
->icon(TablerIcon::FilePlus),
];
}
@@ -116,7 +119,7 @@ class CreateEgg extends CreateRecord
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 1, 'lg' => 1]),
Toggle::make('force_outgoing_ip')
->label(trans('admin/egg.force_ip'))
->hintIcon('tabler-question-mark', trans('admin/egg.force_ip_help')),
->hintIcon(TablerIcon::QuestionMark, trans('admin/egg.force_ip_help')),
Hidden::make('script_is_privileged')
->default(1),
TagsInput::make('tags')
@@ -124,7 +127,7 @@ class CreateEgg extends CreateRecord
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 2]),
TextInput::make('update_url')
->label(trans('admin/egg.update_url'))
->hintIcon('tabler-question-mark', trans('admin/egg.update_url_help'))
->hintIcon(TablerIcon::QuestionMark, trans('admin/egg.update_url_help'))
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 2])
->url(),
KeyValue::make('docker_images')
@@ -172,7 +175,8 @@ class CreateEgg extends CreateRecord
->addActionLabel(trans('admin/egg.add_new_variable'))
->grid()
->relationship('variables')
->reorderable()->orderColumn()
->orderColumn()
->reorderAction(fn (Action $action) => $action->hiddenLabel()->tooltip(fn () => $action->getLabel()))
->collapsible()->collapsed()
->columnSpan(2)
->defaultItems(0)
@@ -214,7 +218,7 @@ class CreateEgg extends CreateRecord
->maxLength(255)
->prefix('{{')
->suffix('}}')
->hintIcon('tabler-code', fn ($state) => "{{{$state}}}")
->hintIcon(TablerIcon::Code, fn ($state) => "{{{$state}}}")
->unique(modifyRuleUsing: fn (Unique $rule, Get $get) => $rule->where('egg_id', $get('../../id')))
->rules(EggVariable::getRulesForField('env_variable'))
->validationMessages([

View File

@@ -3,6 +3,7 @@
namespace App\Filament\Admin\Resources\Eggs\Pages;
use App\Enums\EditorLanguages;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\Eggs\EggResource;
use App\Filament\Components\Actions\ExportEggAction;
use App\Filament\Components\Actions\ImportEggAction;
@@ -70,7 +71,7 @@ class EditEgg extends EditRecord
Tab::make('configuration')
->label(trans('admin/egg.tabs.configuration'))
->columns(['default' => 2, 'sm' => 2, 'md' => 4, 'lg' => 6])
->icon('tabler-egg')
->icon(TablerIcon::Egg)
->schema([
Grid::make(2)
->columnSpan(1)
@@ -84,9 +85,10 @@ class EditEgg extends EditRecord
->columnSpanFull(),
Flex::make([
Action::make('uploadImage')
->iconButton()
->hiddenLabel()
->tooltip(trans('admin/egg.import.import_image'))
->iconSize(IconSize::Large)
->icon('tabler-photo-up')
->icon(TablerIcon::PhotoUp)
->modal()
->modalHeading('')
->modalSubmitActionLabel(trans('admin/egg.import.import_image'))
@@ -209,8 +211,8 @@ class EditEgg extends EditRecord
Action::make('delete_image')
->visible(fn ($record) => $record->image)
->hiddenLabel()
->icon('tabler-trash')
->iconButton()
->tooltip(trans('admin/egg.import.delete_image'))
->icon(TablerIcon::Trash)
->iconSize(IconSize::Large)
->color('danger')
->action(function ($record) {
@@ -262,7 +264,7 @@ class EditEgg extends EditRecord
->inline(false)
->label(trans('admin/egg.force_ip'))
->columnSpan(1)
->hintIcon('tabler-question-mark', trans('admin/egg.force_ip_help')),
->hintIcon(TablerIcon::QuestionMark, trans('admin/egg.force_ip_help')),
KeyValue::make('startup_commands')
->label(trans('admin/egg.startup_commands'))
->live()
@@ -280,7 +282,7 @@ class EditEgg extends EditRecord
TextInput::make('update_url')
->label(trans('admin/egg.update_url'))
->url()
->hintIcon('tabler-question-mark', trans('admin/egg.update_url_help'))
->hintIcon(TablerIcon::QuestionMark, trans('admin/egg.update_url_help'))
->columnSpan(['default' => 2, 'sm' => 2, 'md' => 2, 'lg' => 3]),
TagsInput::make('features')
->label(trans('admin/egg.features'))
@@ -303,7 +305,7 @@ class EditEgg extends EditRecord
Tab::make('process_management')
->label(trans('admin/egg.tabs.process_management'))
->columns()
->icon('tabler-server-cog')
->icon(TablerIcon::ServerCog)
->schema([
CopyFrom::make('copy_process_from')
->process(),
@@ -316,6 +318,7 @@ class EditEgg extends EditRecord
->helperText(trans('admin/egg.start_config_help')),
Textarea::make('config_files')->rows(10)->json()
->label(trans('admin/egg.config_files'))
->dehydrateStateUsing(fn ($state) => blank($state) ? '{}' : $state)
->helperText(trans('admin/egg.config_files_help')),
Textarea::make('config_logs')->rows(10)->json()
->label(trans('admin/egg.log_config'))
@@ -324,15 +327,15 @@ class EditEgg extends EditRecord
Tab::make('egg_variables')
->label(trans('admin/egg.tabs.egg_variables'))
->columnSpanFull()
->icon('tabler-variable')
->icon(TablerIcon::Variable)
->schema([
Repeater::make('variables')
->hiddenLabel()
->grid()
->relationship('variables')
->reorderable()
->collapsible()->collapsed()
->orderColumn()
->reorderAction(fn (Action $action) => $action->hiddenLabel()->tooltip(fn () => $action->getLabel()))
->collapsible()->collapsed()
->addActionLabel(trans('admin/egg.add_new_variable'))
->itemLabel(fn (array $state) => $state['name'])
->mutateRelationshipDataBeforeCreateUsing(function (array $data): array {
@@ -372,7 +375,7 @@ class EditEgg extends EditRecord
->maxLength(255)
->prefix('{{')
->suffix('}}')
->hintIcon('tabler-code', fn ($state) => "{{{$state}}}")
->hintIcon(TablerIcon::Code, fn ($state) => "{{{$state}}}")
->unique(modifyRuleUsing: fn (Unique $rule, Get $get) => $rule->where('egg_id', $get('../../id')))
->rules(EggVariable::getRulesForField('env_variable'))
->validationMessages([
@@ -416,7 +419,7 @@ class EditEgg extends EditRecord
Tab::make('install_script')
->label(trans('admin/egg.tabs.install_script'))
->columns(3)
->icon('tabler-file-download')
->icon(TablerIcon::FileDownload)
->schema([
CopyFrom::make('copy_script_from')
->script(),
@@ -448,24 +451,16 @@ class EditEgg extends EditRecord
return [
DeleteAction::make()
->disabled(fn (Egg $egg): bool => $egg->servers()->count() > 0)
->label(fn (Egg $egg): string => $egg->servers()->count() <= 0 ? trans('filament-actions::delete.single.label') : trans('admin/egg.in_use'))
->successNotification(fn (Egg $egg) => Notification::make()
->success()
->title(trans('admin/egg.delete_success'))
->body(trans('admin/egg.deleted', ['egg' => $egg->name]))
)
->failureNotification(fn (Egg $egg) => Notification::make()
->danger()
->title(trans('admin/egg.delete_failed'))
->body(trans('admin/egg.could_not_delete', ['egg' => $egg->name]))
)
->iconButton()->iconSize(IconSize::ExtraLarge),
->tooltip(fn (Egg $egg): string => $egg->servers()->count() <= 0 ? trans('filament-actions::delete.single.label') : trans('admin/egg.in_use')),
ExportEggAction::make(),
ImportEggAction::make()
->multiple(false),
$this->getSaveFormAction()->formId('form')
->iconButton()->iconSize(IconSize::ExtraLarge)
->icon('tabler-device-floppy'),
Action::make('save')
->hiddenLabel()
->action('save')
->keyBindings(['mod+s'])
->tooltip(trans('filament-panels::resources/pages/edit-record.form.actions.save.label'))
->icon(TablerIcon::DeviceFloppy),
];
}
@@ -490,18 +485,20 @@ class EditEgg extends EditRecord
],
]);
$normalizedExtension = match ($extension) {
'svg+xml', 'svg' => 'svg',
'jpeg', 'jpg' => 'jpg',
'png' => 'png',
'webp' => 'webp',
default => throw new Exception(trans('admin/egg.import.unknown_extension')),
};
$data = @file_get_contents($imageUrl, false, $context, 0, 1048576); // 1024KB
if (empty($data)) {
throw new Exception(trans('admin/egg.import.invalid_url'));
}
$normalizedExtension = match ($extension) {
'svg+xml' => 'svg',
'jpeg' => 'jpg',
default => $extension,
};
Storage::disk('public')->put(Egg::ICON_STORAGE_PATH . "/$egg->uuid.$normalizedExtension", $data);
}

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Resources\Eggs\Pages;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\Eggs\EggResource;
use App\Filament\Components\Actions\ExportEggAction;
use App\Filament\Components\Actions\ImportEggAction;
@@ -12,15 +13,13 @@ use App\Models\Egg;
use App\Traits\Filament\CanCustomizeHeaderActions;
use App\Traits\Filament\CanCustomizeHeaderWidgets;
use Exception;
use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\CreateAction;
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction;
use Filament\Actions\ReplicateAction;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\ListRecords;
use Filament\Support\Enums\IconSize;
use Filament\Tables\Columns\ImageColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
@@ -65,19 +64,13 @@ class ListEggs extends ListRecords
])
->recordActions([
EditAction::make()
->iconButton()
->tooltip(trans('filament-actions::edit.single.label'))
->iconSize(IconSize::Large),
->tooltip(trans('filament-actions::edit.single.label')),
ExportEggAction::make()
->tooltip(trans('filament-actions::export.modal.actions.export.label'))
->iconSize(IconSize::Large),
->tooltip(trans('filament-actions::export.modal.actions.export.label')),
UpdateEggAction::make()
->tooltip(trans_choice('admin/egg.update', 1))
->iconSize(IconSize::Large),
->tooltip(trans_choice('admin/egg.update', 1)),
ReplicateAction::make()
->iconButton()
->tooltip(trans('filament-actions::replicate.single.label'))
->iconSize(IconSize::Large)
->modal(false)
->excludeAttributes(['author', 'uuid', 'update_url', 'servers_count', 'created_at', 'updated_at'])
->beforeReplicaSaved(function (Egg $replica) {
@@ -88,49 +81,54 @@ class ListEggs extends ListRecords
->after(fn (Egg $record, Egg $replica) => $record->variables->each(fn ($variable) => $variable->replicate()->fill(['egg_id' => $replica->id])->save()))
->successRedirectUrl(fn (Egg $replica) => EditEgg::getUrl(['record' => $replica])),
])
->groupedBulkActions([
DeleteBulkAction::make()
->before(function (Collection &$records) {
$eggsWithServers = $records->filter(fn (Egg $egg) => $egg->servers_count > 0);
->toolbarActions([
ImportEggAction::make()
->multiple(),
CreateAction::make(),
BulkActionGroup::make([
DeleteBulkAction::make('exclude_bulk_delete')
->before(function (Collection &$records) {
$eggsWithServers = $records->filter(fn (Egg $egg) => $egg->servers_count > 0);
if ($eggsWithServers->isNotEmpty()) {
$eggNames = $eggsWithServers->map(fn (Egg $egg) => sprintf('%s (%d server%s)', $egg->name, $egg->servers_count, $egg->servers_count > 1 ? 's' : ''))
->join(', ');
Notification::make()
->danger()
->title(trans('admin/egg.cannot_delete', ['count' => $eggsWithServers->count()]))
->body(trans('admin/egg.eggs_have_servers', ['eggs' => $eggNames]))
->send();
}
if ($eggsWithServers->isNotEmpty()) {
$eggNames = $eggsWithServers->map(fn (Egg $egg) => sprintf('%s (%d server%s)', $egg->name, $egg->servers_count, $egg->servers_count > 1 ? 's' : ''))
->join(', ');
Notification::make()
->danger()
->title(trans('admin/egg.cannot_delete', ['count' => $eggsWithServers->count()]))
->body(trans('admin/egg.eggs_have_servers', ['eggs' => $eggNames]))
->send();
}
$records = $records->filter(fn (Egg $egg) => $egg->servers_count <= 0);
$records = $records->filter(fn (Egg $egg) => $egg->servers_count <= 0);
if ($records->isEmpty()) {
$this->halt();
}
}),
UpdateEggBulkAction::make()
->before(function (Collection &$records) {
$eggsWithoutUpdateUrl = $records->filter(fn (Egg $egg) => $egg->update_url === null);
if ($records->isEmpty()) {
$this->halt();
}
}),
UpdateEggBulkAction::make('exclude_bulk_update')
->before(function (Collection &$records) {
$eggsWithoutUpdateUrl = $records->filter(fn (Egg $egg) => $egg->update_url === null);
if ($eggsWithoutUpdateUrl->isNotEmpty()) {
$eggNames = $eggsWithoutUpdateUrl->pluck('name')->join(', ');
if ($eggsWithoutUpdateUrl->isNotEmpty()) {
$eggNames = $eggsWithoutUpdateUrl->pluck('name')->join(', ');
Notification::make()
->warning()
->title(trans('admin/egg.cannot_update', ['count' => $eggsWithoutUpdateUrl->count()]))
->body(trans('admin/egg.no_update_url', ['eggs' => $eggNames]))
->send();
}
Notification::make()
->warning()
->title(trans('admin/egg.cannot_update', ['count' => $eggsWithoutUpdateUrl->count()]))
->body(trans('admin/egg.no_update_url', ['eggs' => $eggNames]))
->send();
}
$records = $records->filter(fn (Egg $egg) => $egg->update_url !== null);
$records = $records->filter(fn (Egg $egg) => $egg->update_url !== null);
if ($records->isEmpty()) {
$this->halt();
}
}),
if ($records->isEmpty()) {
$this->halt();
}
}),
]),
])
->emptyStateIcon('tabler-eggs')
->emptyStateIcon(TablerIcon::Eggs)
->emptyStateDescription('')
->emptyStateHeading(trans('admin/egg.no_eggs'))
->filters([
@@ -138,18 +136,4 @@ class ListEggs extends ListRecords
->model(Egg::class),
]);
}
/** @return array<Action|ActionGroup>
* @throws Exception
*/
protected function getDefaultHeaderActions(): array
{
return [
ImportEggAction::make()
->multiple(),
CreateAction::make()
->icon('tabler-file-plus')
->iconButton()->iconSize(IconSize::ExtraLarge),
];
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Resources\Mounts;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\Mounts\Pages\CreateMount;
use App\Filament\Admin\Resources\Mounts\Pages\EditMount;
use App\Filament\Admin\Resources\Mounts\Pages\ListMounts;
@@ -11,7 +12,10 @@ use App\Traits\Filament\CanCustomizePages;
use App\Traits\Filament\CanCustomizeRelations;
use App\Traits\Filament\CanModifyForm;
use App\Traits\Filament\CanModifyTable;
use BackedEnum;
use Exception;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\CreateAction;
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction;
use Filament\Actions\ViewAction;
@@ -37,7 +41,7 @@ class MountResource extends Resource
protected static ?string $model = Mount::class;
protected static string|\BackedEnum|null $navigationIcon = 'tabler-layers-linked';
protected static string|BackedEnum|null $navigationIcon = TablerIcon::LayersLinked;
protected static ?string $recordTitleAttribute = 'name';
@@ -88,7 +92,7 @@ class MountResource extends Resource
TextColumn::make('read_only')
->label(trans('admin/mount.table.read_only'))
->badge()
->icon(fn ($state) => $state ? 'tabler-writing-off' : 'tabler-writing')
->icon(fn ($state) => $state ? TablerIcon::WritingOff : TablerIcon::Writing)
->color(fn ($state) => $state ? 'success' : 'warning')
->formatStateUsing(fn ($state) => $state ? trans('admin/mount.toggles.read_only') : trans('admin/mount.toggles.writable')),
])
@@ -97,10 +101,13 @@ class MountResource extends Resource
->hidden(fn ($record) => static::getEditAuthorizationResponse($record)->allowed()),
EditAction::make(),
])
->groupedBulkActions([
DeleteBulkAction::make(),
->toolbarActions([
CreateAction::make(),
BulkActionGroup::make([
DeleteBulkAction::make('exclude_bulk_delete'),
]),
])
->emptyStateIcon('tabler-layers-linked')
->emptyStateIcon(TablerIcon::LayersLinked)
->emptyStateDescription('')
->emptyStateHeading(trans('admin/mount.no_mounts'));
}
@@ -127,8 +134,8 @@ class MountResource extends Resource
true => trans('admin/mount.toggles.read_only'),
])
->icons([
false => 'tabler-writing',
true => 'tabler-writing-off',
false => TablerIcon::Writing,
true => TablerIcon::WritingOff,
])
->colors([
false => 'warning',

View File

@@ -2,13 +2,13 @@
namespace App\Filament\Admin\Resources\Mounts\Pages;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\Mounts\MountResource;
use App\Traits\Filament\CanCustomizeHeaderActions;
use App\Traits\Filament\CanCustomizeHeaderWidgets;
use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Resources\Pages\CreateRecord;
use Filament\Support\Enums\IconSize;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
@@ -25,9 +25,12 @@ class CreateMount extends CreateRecord
protected function getDefaultHeaderActions(): array
{
return [
$this->getCreateFormAction()->formId('form')
->iconButton()->iconSize(IconSize::ExtraLarge)
->icon('tabler-file-plus'),
Action::make('create')
->hiddenLabel()
->action('create')
->keyBindings(['mod+s'])
->tooltip(trans('filament-panels::resources/pages/create-record.form.actions.create.label'))
->icon(TablerIcon::FilePlus),
];
}

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Resources\Mounts\Pages;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\Mounts\MountResource;
use App\Traits\Filament\CanCustomizeHeaderActions;
use App\Traits\Filament\CanCustomizeHeaderWidgets;
@@ -9,7 +10,6 @@ use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Actions\DeleteAction;
use Filament\Resources\Pages\EditRecord;
use Filament\Support\Enums\IconSize;
class EditMount extends EditRecord
{
@@ -22,11 +22,13 @@ class EditMount extends EditRecord
protected function getDefaultHeaderActions(): array
{
return [
DeleteAction::make()
->iconButton()->iconSize(IconSize::ExtraLarge),
$this->getSaveFormAction()->formId('form')
->iconButton()->iconSize(IconSize::ExtraLarge)
->icon('tabler-device-floppy'),
DeleteAction::make(),
Action::make('save')
->hiddenLabel()
->action('save')
->keyBindings(['mod+s'])
->tooltip(trans('filament-panels::resources/pages/edit-record.form.actions.save.label'))
->icon(TablerIcon::DeviceFloppy),
];
}

View File

@@ -5,11 +5,7 @@ namespace App\Filament\Admin\Resources\Mounts\Pages;
use App\Filament\Admin\Resources\Mounts\MountResource;
use App\Traits\Filament\CanCustomizeHeaderActions;
use App\Traits\Filament\CanCustomizeHeaderWidgets;
use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Actions\CreateAction;
use Filament\Resources\Pages\ListRecords;
use Filament\Support\Enums\IconSize;
class ListMounts extends ListRecords
{
@@ -17,14 +13,4 @@ class ListMounts extends ListRecords
use CanCustomizeHeaderWidgets;
protected static string $resource = MountResource::class;
/** @return array<Action|ActionGroup> */
protected function getDefaultHeaderActions(): array
{
return [
CreateAction::make()
->iconButton()->iconSize(IconSize::ExtraLarge)
->icon('tabler-file-plus'),
];
}
}

View File

@@ -9,7 +9,6 @@ use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Actions\EditAction;
use Filament\Resources\Pages\ViewRecord;
use Filament\Support\Enums\IconSize;
class ViewMount extends ViewRecord
{
@@ -22,9 +21,7 @@ class ViewMount extends ViewRecord
protected function getDefaultHeaderActions(): array
{
return [
EditAction::make()
->iconSize(IconSize::ExtraLarge)
->iconButton(),
EditAction::make(),
];
}
}

View File

@@ -3,6 +3,7 @@
namespace App\Filament\Admin\Resources\Nodes;
use App\Enums\CustomizationKey;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\Nodes\Pages\CreateNode;
use App\Filament\Admin\Resources\Nodes\Pages\EditNode;
use App\Filament\Admin\Resources\Nodes\Pages\ListNodes;
@@ -11,6 +12,7 @@ use App\Filament\Admin\Resources\Nodes\RelationManagers\ServersRelationManager;
use App\Models\Node;
use App\Traits\Filament\CanCustomizePages;
use App\Traits\Filament\CanCustomizeRelations;
use BackedEnum;
use Filament\Resources\Pages\PageRegistration;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Resources\Resource;
@@ -23,7 +25,7 @@ class NodeResource extends Resource
protected static ?string $model = Node::class;
protected static string|\BackedEnum|null $navigationIcon = 'tabler-server-2';
protected static string|BackedEnum|null $navigationIcon = TablerIcon::Server2;
protected static ?string $recordTitleAttribute = 'name';

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Resources\Nodes\Pages;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\Nodes\NodeResource;
use App\Models\Node;
use App\Traits\Filament\CanCustomizeHeaderActions;
@@ -39,13 +40,14 @@ class CreateNode extends CreateRecord
->components([
Wizard::make($this->getSteps())
->columnSpanFull()
->nextAction(fn (Action $action) => $action->iconButton()->iconSize(IconSize::ExtraLarge)->icon('tabler-arrow-right'))
->previousAction(fn (Action $action) => $action->iconButton()->iconSize(IconSize::ExtraLarge)->icon('tabler-arrow-left'))
->nextAction(fn (Action $action) => $action->tooltip(fn () => $action->getLabel())->iconButton()->iconSize(IconSize::ExtraLarge)->icon(TablerIcon::ArrowRight))
->previousAction(fn (Action $action) => $action->tooltip(fn () => $action->getLabel())->iconButton()->iconSize(IconSize::ExtraLarge)->icon(TablerIcon::ArrowLeft))
->submitAction(new HtmlString(Blade::render(<<<'BLADE'
<x-filament::icon-button
type="submit"
iconSize="xl"
icon="tabler-file-plus"
icon="tabler-plus"
tooltip="{{ trans('admin/node.create') }}"
>
{{ trans('admin/node.create') }}
</x-filament::icon-button>
@@ -59,7 +61,7 @@ class CreateNode extends CreateRecord
return [
Step::make('basic')
->label(trans('admin/node.tabs.basic_settings'))
->icon('tabler-server')
->icon(TablerIcon::Server)
->columnSpanFull()
->columns([
'default' => 2,
@@ -203,9 +205,9 @@ class CreateNode extends CreateRecord
'https_proxy' => 'success',
])
->icons([
'http' => 'tabler-lock-open-off',
'https' => 'tabler-lock',
'https_proxy' => 'tabler-shield-lock',
'http' => TablerIcon::LockOpenOff,
'https' => TablerIcon::Lock,
'https_proxy' => TablerIcon::ShieldLock,
])
->default(fn () => request()->isSecure() ? 'https' : 'http')
->live()
@@ -231,7 +233,7 @@ class CreateNode extends CreateRecord
]),
Step::make('advanced')
->label(trans('admin/node.tabs.advanced_settings'))
->icon('tabler-server-cog')
->icon(TablerIcon::ServerCog)
->columnSpanFull()
->columns([
'default' => 2,
@@ -244,7 +246,7 @@ class CreateNode extends CreateRecord
->label(trans('admin/node.maintenance_mode'))->inline()
->columnSpan(1)
->default(false)
->hintIcon('tabler-question-mark', trans('admin/node.maintenance_mode_help'))
->hintIcon(TablerIcon::QuestionMark, trans('admin/node.maintenance_mode_help'))
->options([
true => trans('admin/node.enabled'),
false => trans('admin/node.disabled'),
@@ -270,12 +272,20 @@ class CreateNode extends CreateRecord
->columnSpan(2),
TextInput::make('upload_size')
->label(trans('admin/node.upload_limit'))
->hintIcon('tabler-question-mark', trans('admin/node.upload_limit_help'))
->hintIcon(TablerIcon::QuestionMark, trans('admin/node.upload_limit_help'))
->columnSpan(1)
->numeric()->required()
->default(256)
->minValue(1)
->suffix(config('panel.use_binary_prefix') ? 'MiB' : 'MB'),
TextInput::make('daemon_base')
->label(trans('admin/node.daemon_base'))
->placeholder('/var/lib/pelican/volumes')
->hintIcon(TablerIcon::QuestionMark, trans('admin/node.daemon_base_help'))
->columnSpan(1)
->required()
->default('/var/lib/pelican/volumes')
->rule('regex:/^([\/][\d\w.\-\/]+)$/'),
TextInput::make('daemon_sftp')
->columnSpan(1)
->label(trans('admin/node.sftp_port'))
@@ -285,7 +295,7 @@ class CreateNode extends CreateRecord
->required()
->integer(),
TextInput::make('daemon_sftp_alias')
->columnSpan(2)
->columnSpan(1)
->label(trans('admin/node.sftp_alias'))
->helperText(trans('admin/node.sftp_alias_help')),
Grid::make()

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Resources\Nodes\Pages;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\Nodes\NodeResource;
use App\Models\Node;
use App\Repositories\Daemon\DaemonSystemRepository;
@@ -37,7 +38,6 @@ use Filament\Schemas\Components\Utilities\Set;
use Filament\Schemas\Components\View;
use Filament\Schemas\Schema;
use Filament\Support\Enums\Alignment;
use Filament\Support\Enums\IconSize;
use Filament\Support\RawJs;
use Illuminate\Http\Client\ConnectionException;
use Illuminate\Support\Facades\Http;
@@ -84,7 +84,7 @@ class EditNode extends EditRecord
return [
Tab::make('overview')
->label(trans('admin/node.tabs.overview'))
->icon('tabler-chart-area-line-filled')
->icon(TablerIcon::ChartAreaLineFilled)
->columns([
'default' => 4,
'sm' => 2,
@@ -129,7 +129,7 @@ class EditNode extends EditRecord
]),
Tab::make('basic_settings')
->label(trans('admin/node.tabs.basic_settings'))
->icon('tabler-server')
->icon(TablerIcon::Server)
->schema([
TextInput::make('fqdn')
->columnSpan(2)
@@ -253,9 +253,9 @@ class EditNode extends EditRecord
'https_proxy' => 'success',
])
->icons([
'http' => 'tabler-lock-open-off',
'https' => 'tabler-lock',
'https_proxy' => 'tabler-shield-lock',
'http' => TablerIcon::LockOpenOff,
'https' => TablerIcon::Lock,
'https_proxy' => TablerIcon::ShieldLock,
])
->formatStateUsing(fn (Get $get) => $get('scheme') === 'http' ? 'http' : ($get('behind_proxy') ? 'https_proxy' : 'https'))
->live()
@@ -286,7 +286,7 @@ class EditNode extends EditRecord
'md' => 4,
'lg' => 6,
])
->icon('tabler-server-cog')
->icon(TablerIcon::ServerCog)
->schema([
TextInput::make('id')
->label(trans('admin/node.node_id'))
@@ -314,7 +314,7 @@ class EditNode extends EditRecord
'default' => 1,
'sm' => 1,
'md' => 2,
'lg' => 2,
'lg' => 3,
]),
TextInput::make('upload_size')
->columnSpan([
@@ -324,17 +324,29 @@ class EditNode extends EditRecord
'lg' => 1,
])
->label(trans('admin/node.upload_limit'))
->hintIcon('tabler-question-mark', trans('admin/node.upload_limit_help'))
->hintIcon(TablerIcon::QuestionMark, trans('admin/node.upload_limit_help'))
->numeric()
->required()
->minValue(1)
->suffix(config('panel.use_binary_prefix') ? 'MiB' : 'MB'),
TextInput::make('daemon_base')
->label(trans('admin/node.daemon_base'))
->placeholder('/var/lib/pelican/volumes')
->hintIcon(TablerIcon::QuestionMark, trans('admin/node.daemon_base_help'))
->columnSpan([
'default' => 1,
'sm' => 1,
'md' => 2,
'lg' => 2,
])
->required()
->rule('regex:/^([\/][\d\w.\-\/]+)$/'),
TextInput::make('daemon_sftp')
->columnSpan([
'default' => 1,
'sm' => 1,
'md' => 1,
'lg' => 3,
'md' => 2,
'lg' => 1,
])
->label(trans('admin/node.sftp_port'))
->minValue(1)
@@ -346,8 +358,8 @@ class EditNode extends EditRecord
->columnSpan([
'default' => 1,
'sm' => 1,
'md' => 1,
'lg' => 3,
'md' => 2,
'lg' => 2,
])
->label(trans('admin/node.sftp_alias'))
->helperText(trans('admin/node.sftp_alias_help')),
@@ -356,7 +368,7 @@ class EditNode extends EditRecord
'default' => 1,
'sm' => 1,
'md' => 1,
'lg' => 3,
'lg' => 2,
])
->label(trans('admin/node.use_for_deploy'))
->inline()
@@ -374,11 +386,11 @@ class EditNode extends EditRecord
'default' => 1,
'sm' => 1,
'md' => 1,
'lg' => 3,
'lg' => 2,
])
->label(trans('admin/node.maintenance_mode'))
->inline()
->hintIcon('tabler-question-mark', trans('admin/node.maintenance_mode_help'))
->hintIcon(TablerIcon::QuestionMark, trans('admin/node.maintenance_mode_help'))
->stateCast(new BooleanStateCast(false, true))
->options([
1 => trans('admin/node.enabled'),
@@ -554,7 +566,7 @@ class EditNode extends EditRecord
]),
Tab::make('config_file')
->label(trans('admin/node.tabs.config_file'))
->icon('tabler-code')
->icon(TablerIcon::Code)
->schema([
TextEntry::make('instructions')
->label(trans('admin/node.instructions'))
@@ -572,11 +584,11 @@ class EditNode extends EditRecord
->columnSpanFull()
->schema([
Actions::make([
Action::make('autoDeploy')
Action::make('exclude_autoDeploy')
->label(trans('admin/node.auto_deploy'))
->color('primary')
->modalHeading(trans('admin/node.auto_deploy'))
->icon('tabler-rocket')
->icon(TablerIcon::Rocket)
->modalSubmitAction(false)
->modalCancelAction(false)
->modalFooterActionsAlignment(Alignment::Center)
@@ -610,7 +622,7 @@ class EditNode extends EditRecord
}),
])->fullWidth(),
Actions::make([
Action::make('resetKey')
Action::make('exclude_resetKey')
->label(trans('admin/node.reset_token'))
->color('danger')
->requiresConfirmation()
@@ -624,7 +636,7 @@ class EditNode extends EditRecord
->title(trans('admin/node.error_connecting', ['node' => $node->name]))
->body(trans('admin/node.error_connecting_description'))
->color('warning')
->icon('tabler-database')
->icon(TablerIcon::Database)
->warning()
->send();
@@ -637,7 +649,7 @@ class EditNode extends EditRecord
]),
Tab::make('diagnostics')
->label(trans('admin/node.tabs.diagnostics'))
->icon('tabler-heart-search')
->icon(TablerIcon::HeartSearch)
->schema([
Section::make('diag')
->heading(trans('admin/node.tabs.diagnostics'))
@@ -646,8 +658,8 @@ class EditNode extends EditRecord
->disabled(fn (Get $get) => $get('pulled'))
->headerActions([
Action::make('pull')
->label(trans('admin/node.diagnostics.pull'))
->icon('tabler-cloud-download')->iconButton()->iconSize(IconSize::ExtraLarge)
->tooltip(trans('admin/node.diagnostics.pull'))
->icon(TablerIcon::CloudDownload)
->hidden(fn (Get $get) => $get('pulled'))
->action(function (Get $get, Set $set, Node $node) {
$includeEndpoints = $get('include_endpoints') ?? true;
@@ -684,9 +696,9 @@ class EditNode extends EditRecord
}
}),
Action::make('upload')
->label(trans('admin/node.diagnostics.upload'))
->tooltip(trans('admin/node.diagnostics.upload'))
->visible(fn (Get $get) => $get('pulled') ?? false)
->icon('tabler-cloud-upload')->iconButton()->iconSize(IconSize::ExtraLarge)
->icon(TablerIcon::CloudUpload)
->action(function (Get $get, Set $set) {
try {
$response = Http::asMultipart()
@@ -712,7 +724,7 @@ class EditNode extends EditRecord
->body("{$url}")
->success()
->actions([
Action::make('viewLogs')
Action::make('exclude_viewLogs')
->label(trans('admin/node.diagnostics.view_logs'))
->url($url)
->openUrlInNewTab(true),
@@ -732,9 +744,9 @@ class EditNode extends EditRecord
}
}),
Action::make('clear')
->label(trans('admin/node.diagnostics.clear'))
->tooltip(trans('admin/node.diagnostics.clear'))
->visible(fn (Get $get) => $get('pulled') ?? false)
->icon('tabler-trash')->iconButton()->iconSize(IconSize::ExtraLarge)->color('danger')
->icon(TablerIcon::Trash)->color('danger')
->action(function (Get $get, Set $set) {
$set('pulled', false);
$set('uploaded', false);
@@ -745,13 +757,13 @@ class EditNode extends EditRecord
])
->schema([
ToggleButtons::make('include_endpoints')
->hintIcon('tabler-question-mark')->inline()
->hintIcon(TablerIcon::QuestionMark)->inline()
->hintIconTooltip(trans('admin/node.diagnostics.include_endpoints_hint'))
->formatStateUsing(fn () => 1)
->boolean(),
ToggleButtons::make('include_logs')
->live()
->hintIcon('tabler-question-mark')->inline()
->hintIcon(TablerIcon::QuestionMark)->inline()
->hintIconTooltip(trans('admin/node.diagnostics.include_logs_hint'))
->formatStateUsing(fn () => 1)
->boolean(),
@@ -808,11 +820,13 @@ class EditNode extends EditRecord
return [
DeleteAction::make()
->disabled(fn (Node $node) => $node->servers()->count() > 0)
->label(fn (Node $node) => $node->servers()->count() > 0 ? trans('admin/node.node_has_servers') : trans('filament-actions::delete.single.label'))
->iconButton()->iconSize(IconSize::ExtraLarge),
$this->getSaveFormAction()->formId('form')
->iconButton()->iconSize(IconSize::ExtraLarge)
->icon('tabler-device-floppy'),
->tooltip(fn (Node $node) => $node->servers()->count() > 0 ? trans('admin/node.node_has_servers') : trans('filament-actions::delete.single.label')),
Action::make('save')
->hiddenLabel()
->action('save')
->keyBindings(['mod+s'])
->tooltip(trans('filament-panels::resources/pages/edit-record.form.actions.save.label'))
->icon(TablerIcon::DeviceFloppy),
];
}
@@ -844,7 +858,7 @@ class EditNode extends EditRecord
->title(trans('admin/node.error_connecting', ['node' => $node->name]))
->body(trans('admin/node.error_connecting_description'))
->color('warning')
->icon('tabler-database')
->icon(TablerIcon::Database)
->warning()
->send();
}

View File

@@ -2,18 +2,17 @@
namespace App\Filament\Admin\Resources\Nodes\Pages;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\Nodes\NodeResource;
use App\Filament\Components\Tables\Columns\NodeClientHealthColumn;
use App\Filament\Components\Tables\Columns\NodeHealthColumn;
use App\Filament\Components\Tables\Filters\TagsFilter;
use App\Models\Node;
use App\Traits\Filament\CanCustomizeHeaderActions;
use App\Traits\Filament\CanCustomizeHeaderWidgets;
use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Actions\CreateAction;
use Filament\Actions\EditAction;
use Filament\Resources\Pages\ListRecords;
use Filament\Support\Enums\IconSize;
use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
@@ -36,6 +35,7 @@ class ListNodes extends ListRecords
->searchable()
->hidden(),
NodeHealthColumn::make('health'),
NodeClientHealthColumn::make('reachable'),
TextColumn::make('name')
->label(trans('admin/node.table.name'))
->sortable()
@@ -48,14 +48,14 @@ class ListNodes extends ListRecords
IconColumn::make('scheme')
->visibleFrom('xl')
->label('SSL')
->trueIcon('tabler-lock')
->falseIcon('tabler-lock-open-off')
->trueIcon(TablerIcon::Lock)
->falseIcon(TablerIcon::LockOpenOff)
->state(fn (Node $node) => $node->scheme === 'https'),
IconColumn::make('public')
->label(trans('admin/node.table.public'))
->visibleFrom('lg')
->trueIcon('tabler-eye-check')
->falseIcon('tabler-eye-cancel'),
->trueIcon(TablerIcon::EyeCheck)
->falseIcon(TablerIcon::EyeCancel),
TextColumn::make('servers_count')
->visibleFrom('sm')
->counts('servers')
@@ -65,7 +65,10 @@ class ListNodes extends ListRecords
->recordActions([
EditAction::make(),
])
->emptyStateIcon('tabler-server-2')
->toolbarActions([
CreateAction::make(),
])
->emptyStateIcon(TablerIcon::Server2)
->emptyStateDescription('')
->emptyStateHeading(trans('admin/node.no_nodes'))
->filters([
@@ -73,14 +76,4 @@ class ListNodes extends ListRecords
->model(Node::class),
]);
}
/** @return array<Action|ActionGroup> */
protected function getDefaultHeaderActions(): array
{
return [
CreateAction::make()
->iconButton()->iconSize(IconSize::ExtraLarge)
->icon('tabler-file-plus'),
];
}
}

View File

@@ -2,11 +2,13 @@
namespace App\Filament\Admin\Resources\Nodes\RelationManagers;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\Servers\Pages\CreateServer;
use App\Filament\Components\Actions\UpdateNodeAllocations;
use App\Models\Allocation;
use App\Models\Node;
use App\Services\Allocations\AssignmentService;
use BackedEnum;
use Exception;
use Filament\Actions\Action;
use Filament\Actions\DeleteBulkAction;
@@ -16,7 +18,6 @@ use Filament\Forms\Components\TextInput;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Components\Utilities\Set;
use Filament\Support\Enums\IconSize;
use Filament\Tables\Columns\SelectColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Columns\TextInputColumn;
@@ -29,7 +30,7 @@ class AllocationsRelationManager extends RelationManager
{
protected static string $relationship = 'allocations';
protected static string|\BackedEnum|null $icon = 'tabler-plug-connected';
protected static string|BackedEnum|null $icon = TablerIcon::PlugConnected;
public function setTitle(): string
{
@@ -57,7 +58,7 @@ class AllocationsRelationManager extends RelationManager
->label(trans('admin/node.ports')),
TextColumn::make('server.name')
->label(trans('admin/node.table.servers'))
->icon('tabler-brand-docker')
->icon(TablerIcon::BrandDocker)
->visibleFrom('md')
->searchable()
->url(fn (Allocation $allocation): string => $allocation->server ? route('filament.admin.resources.servers.edit', ['record' => $allocation->server]) : ''),
@@ -86,12 +87,14 @@ class AllocationsRelationManager extends RelationManager
DeleteBulkAction::make()
->authorize(fn () => user()?->can('update', $this->getOwnerRecord())),
Action::make('create new allocation')
->label(trans('admin/node.create_allocation'))
->icon('tabler-world-plus')
->iconButton()->iconSize(IconSize::ExtraLarge)
->tooltip(trans('admin/node.create_allocation'))
->icon(TablerIcon::WorldPlus)
->schema(fn () => [
Select::make('allocation_ip')
->options(fn () => collect($this->getOwnerRecord()->ipAddresses())->mapWithKeys(fn (string $ip) => [$ip => $ip]))
->options(fn (Get $get) => collect($this->getOwnerRecord()->ipAddresses())
->when($get('allocation_ip'), fn ($ips, $current) => $ips->push($current))
->unique()
->mapWithKeys(fn (string $ip) => [$ip => $ip]))
->label(trans('admin/node.ip_address'))
->inlineLabel()
->ip()
@@ -99,14 +102,26 @@ class AllocationsRelationManager extends RelationManager
->afterStateUpdated(fn (Set $set) => $set('allocation_ports', []))
->live()
->hintAction(
Action::make('refresh')
->iconButton()
->icon('tabler-refresh')
Action::make('hint_refresh')
->hiddenLabel()
->icon(TablerIcon::Refresh)
->tooltip(trans('admin/node.refresh'))
->action(function () {
cache()->forget("nodes.{$this->getOwnerRecord()->id}.ips");
})
)
->suffixAction(
Action::make('custom_ip')
->icon(TablerIcon::Keyboard)
->tooltip(trans('admin/node.custom_ip'))
->schema([
TextInput::make('custom_ip')
->label(trans('admin/node.ip_address'))
->ip()
->required(),
])
->action(fn (array $data, Set $set) => $set('allocation_ip', $data['custom_ip']))
)
->required(),
TextInput::make('allocation_alias')
->label(trans('admin/node.table.alias'))

View File

@@ -3,7 +3,9 @@
namespace App\Filament\Admin\Resources\Nodes\RelationManagers;
use App\Enums\ServerResourceType;
use App\Enums\TablerIcon;
use App\Models\Server;
use BackedEnum;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Tables\Columns\SelectColumn;
use Filament\Tables\Columns\TextColumn;
@@ -13,7 +15,7 @@ class ServersRelationManager extends RelationManager
{
protected static string $relationship = 'servers';
protected static string|\BackedEnum|null $icon = 'tabler-brand-docker';
protected static string|BackedEnum|null $icon = TablerIcon::BrandDocker;
public function setTitle(): string
{

View File

@@ -3,9 +3,11 @@
namespace App\Filament\Admin\Resources\Plugins;
use App\Enums\PluginStatus;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\Plugins\Pages\ListPlugins;
use App\Models\Plugin;
use App\Services\Helpers\PluginService;
use BackedEnum;
use Exception;
use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
@@ -14,7 +16,6 @@ use Filament\Forms\Components\TextInput;
use Filament\Infolists\Components\TextEntry;
use Filament\Notifications\Notification;
use Filament\Resources\Resource;
use Filament\Support\Enums\IconSize;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Illuminate\Http\UploadedFile;
@@ -23,7 +24,7 @@ class PluginResource extends Resource
{
protected static ?string $model = Plugin::class;
protected static string|\BackedEnum|null $navigationIcon = 'tabler-packages';
protected static string|BackedEnum|null $navigationIcon = TablerIcon::Packages;
protected static ?string $recordTitleAttribute = 'name';
@@ -59,7 +60,7 @@ class PluginResource extends Resource
TextColumn::make('name')
->label(trans('admin/plugin.name'))
->description(fn (Plugin $plugin) => (strlen($plugin->description) > 80) ? substr($plugin->description, 0, 80).'...' : $plugin->description)
->icon(fn (Plugin $plugin) => $plugin->isUpdateAvailable() ? 'tabler-versions-off' : 'tabler-versions')
->icon(fn (Plugin $plugin) => $plugin->isUpdateAvailable() ? TablerIcon::VersionsOff : TablerIcon::Versions)
->iconColor(fn (Plugin $plugin) => $plugin->isUpdateAvailable() ? 'danger' : 'success')
->tooltip(fn (Plugin $plugin) => $plugin->isUpdateAvailable() ? trans('admin/plugin.update_available') : null)
->sortable()
@@ -82,15 +83,15 @@ class PluginResource extends Resource
->sortable(),
])
->recordActions([
Action::make('view')
Action::make('exclude_view')
->label(trans('filament-actions::view.single.label'))
->icon(fn (Plugin $plugin) => $plugin->getReadme() ? 'tabler-eye' : 'tabler-eye-share')
->icon(fn (Plugin $plugin) => $plugin->getReadme() ? TablerIcon::Eye : TablerIcon::EyeShare)
->color('gray')
->visible(fn (Plugin $plugin) => $plugin->getReadme() || $plugin->url)
->url(fn (Plugin $plugin) => !$plugin->getReadme() ? $plugin->url : null, true)
->slideOver(true)
->modalHeading('Readme')
->modalSubmitAction(fn (Plugin $plugin) => Action::make('visit_website')
->modalSubmitAction(fn (Plugin $plugin) => Action::make('exclude_visit_website')
->label(trans('admin/plugin.visit_website'))
->visible(!is_null($plugin->url))
->url($plugin->url, true)
@@ -102,20 +103,20 @@ class PluginResource extends Resource
->markdown()
->state(fn (Plugin $plugin) => $plugin->getReadme()),
] : null),
Action::make('settings')
Action::make('exclude_settings')
->label(trans('admin/plugin.settings'))
->authorize(fn (Plugin $plugin) => user()?->can('update', $plugin))
->icon('tabler-settings')
->icon(TablerIcon::Settings)
->color('primary')
->visible(fn (Plugin $plugin) => $plugin->status === PluginStatus::Enabled && $plugin->hasSettings())
->schema(fn (Plugin $plugin) => $plugin->getSettingsForm())
->action(fn (array $data, Plugin $plugin) => $plugin->saveSettings($data))
->slideOver(),
ActionGroup::make([
Action::make('install')
Action::make('exclude_install')
->label(trans('admin/plugin.install'))
->authorize(fn (Plugin $plugin) => user()?->can('update', $plugin))
->icon('tabler-terminal')
->icon(TablerIcon::Terminal)
->color('success')
->hidden(fn (Plugin $plugin) => $plugin->status !== PluginStatus::NotInstalled)
->action(function (Plugin $plugin, $livewire, PluginService $pluginService) {
@@ -136,10 +137,10 @@ class PluginResource extends Resource
->send();
}
}),
Action::make('update')
Action::make('exclude_update')
->label(trans('admin/plugin.update'))
->authorize(fn (Plugin $plugin) => user()?->can('update', $plugin))
->icon('tabler-download')
->icon(TablerIcon::Download)
->color('success')
->visible(fn (Plugin $plugin) => $plugin->status !== PluginStatus::NotInstalled && $plugin->isUpdateAvailable())
->action(function (Plugin $plugin, $livewire, PluginService $pluginService) {
@@ -160,10 +161,10 @@ class PluginResource extends Resource
->send();
}
}),
Action::make('enable')
Action::make('exclude_enable')
->label(trans('admin/plugin.enable'))
->authorize(fn (Plugin $plugin) => user()?->can('update', $plugin))
->icon('tabler-check')
->icon(TablerIcon::Check)
->color('success')
->visible(fn (Plugin $plugin) => $plugin->canEnable())
->requiresConfirmation(fn (Plugin $plugin, PluginService $pluginService) => $plugin->isTheme() && $pluginService->hasThemePluginEnabled())
@@ -179,10 +180,10 @@ class PluginResource extends Resource
->title(trans('admin/plugin.notifications.enabled'))
->send();
}),
Action::make('disable')
Action::make('exclude_disable')
->label(trans('admin/plugin.disable'))
->authorize(fn (Plugin $plugin) => user()?->can('update', $plugin))
->icon('tabler-x')
->icon(TablerIcon::X)
->color('warning')
->visible(fn (Plugin $plugin) => $plugin->canDisable())
->action(function (Plugin $plugin, $livewire, PluginService $pluginService) {
@@ -195,13 +196,13 @@ class PluginResource extends Resource
->title(trans('admin/plugin.notifications.disabled'))
->send();
}),
Action::make('delete')
Action::make('exclude_delete')
->label(trans('filament-actions::delete.single.label'))
->authorize(fn (Plugin $plugin) => user()?->can('delete', $plugin))
->icon('tabler-trash')
->icon(TablerIcon::Trash)
->color('danger')
->requiresConfirmation()
->visible(fn (Plugin $plugin) => $plugin->status === PluginStatus::NotInstalled)
->visible(fn (Plugin $plugin) => $plugin->status === PluginStatus::NotInstalled || $plugin->status === PluginStatus::Errored)
->action(function (Plugin $plugin, $livewire, PluginService $pluginService) {
$pluginService->deletePlugin($plugin);
@@ -212,10 +213,10 @@ class PluginResource extends Resource
->title(trans('admin/plugin.notifications.deleted'))
->send();
}),
Action::make('uninstall')
Action::make('exclude_uninstall')
->label(trans('admin/plugin.uninstall'))
->authorize(fn (Plugin $plugin) => user()?->can('update', $plugin))
->icon('tabler-terminal')
->icon(TablerIcon::Terminal)
->color('danger')
->requiresConfirmation()
->hidden(fn (Plugin $plugin) => $plugin->status === PluginStatus::NotInstalled || $plugin->status === PluginStatus::Errored)
@@ -241,11 +242,10 @@ class PluginResource extends Resource
])
->headerActions([
Action::make('import_from_file')
->label(trans('admin/plugin.import_from_file'))
->hiddenLabel()
->tooltip(trans('admin/plugin.import_from_file'))
->authorize(fn () => user()?->can('create', Plugin::class))
->icon('tabler-file-download')
->iconButton()
->iconSize(IconSize::ExtraLarge)
->icon(TablerIcon::FileDownload)
->schema([
// TODO: switch to new file upload
FileUpload::make('file')
@@ -285,11 +285,10 @@ class PluginResource extends Resource
}
}),
Action::make('import_from_url')
->label(trans('admin/plugin.import_from_url'))
->hiddenLabel()
->tooltip(trans('admin/plugin.import_from_url'))
->authorize(fn () => user()?->can('create', Plugin::class))
->icon('tabler-world-download')
->iconButton()
->iconSize(IconSize::ExtraLarge)
->icon(TablerIcon::WorldDownload)
->schema([
TextInput::make('url')
->required()
@@ -323,7 +322,7 @@ class PluginResource extends Resource
}
}),
])
->emptyStateIcon('tabler-packages')
->emptyStateIcon(TablerIcon::Packages)
->emptyStateDescription('')
->emptyStateHeading(trans('admin/plugin.no_plugins'));
}

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Resources\Roles\Pages;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\Roles\RoleResource;
use App\Models\Role;
use App\Traits\Filament\CanCustomizeHeaderActions;
@@ -9,7 +10,6 @@ use App\Traits\Filament\CanCustomizeHeaderWidgets;
use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Resources\Pages\CreateRecord;
use Filament\Support\Enums\IconSize;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Spatie\Permission\Models\Permission;
@@ -32,9 +32,12 @@ class CreateRole extends CreateRecord
protected function getDefaultHeaderActions(): array
{
return [
$this->getCreateFormAction()->formId('form')
->iconButton()->iconSize(IconSize::ExtraLarge)
->icon('tabler-plus'),
Action::make('create')
->hiddenLabel()
->action('create')
->keyBindings(['mod+s'])
->tooltip(trans('filament-panels::resources/pages/create-record.form.actions.create.label'))
->icon(TablerIcon::FilePlus),
];
}

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Resources\Roles\Pages;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\Roles\RoleResource;
use App\Models\Role;
use App\Traits\Filament\CanCustomizeHeaderActions;
@@ -10,7 +11,6 @@ use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Actions\DeleteAction;
use Filament\Resources\Pages\EditRecord;
use Filament\Support\Enums\IconSize;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Spatie\Permission\Models\Permission;
@@ -58,12 +58,14 @@ class EditRole extends EditRecord
{
return [
DeleteAction::make()
->label(fn (Role $role) => $role->isRootAdmin() ? trans('admin/role.root_admin_delete') : ($role->users_count >= 1 ? trans('admin/role.in_use') : trans('filament-actions::delete.single.label')))
->disabled(fn (Role $role) => $role->isRootAdmin() || $role->users_count >= 1)
->iconButton()->iconSize(IconSize::ExtraLarge),
$this->getSaveFormAction()->formId('form')
->iconButton()->iconSize(IconSize::ExtraLarge)
->icon('tabler-device-floppy'),
->tooltip(fn (Role $role) => $role->isRootAdmin() ? trans('admin/role.root_admin_delete') : ($role->users_count >= 1 ? trans('admin/role.in_use') : trans('filament-actions::delete.single.label')))
->disabled(fn (Role $role) => $role->isRootAdmin() || $role->users_count >= 1),
Action::make('save')
->hiddenLabel()
->action('save')
->keyBindings(['mod+s'])
->tooltip(trans('filament-panels::resources/pages/edit-record.form.actions.save.label'))
->icon(TablerIcon::DeviceFloppy),
];
}

View File

@@ -5,11 +5,7 @@ namespace App\Filament\Admin\Resources\Roles\Pages;
use App\Filament\Admin\Resources\Roles\RoleResource;
use App\Traits\Filament\CanCustomizeHeaderActions;
use App\Traits\Filament\CanCustomizeHeaderWidgets;
use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Actions\CreateAction;
use Filament\Resources\Pages\ListRecords;
use Filament\Support\Enums\IconSize;
class ListRoles extends ListRecords
{
@@ -17,14 +13,4 @@ class ListRoles extends ListRecords
use CanCustomizeHeaderWidgets;
protected static string $resource = RoleResource::class;
/** @return array<Action|ActionGroup> */
protected function getDefaultHeaderActions(): array
{
return [
CreateAction::make()
->icon('tabler-file-plus')
->iconButton()->iconSize(IconSize::ExtraLarge),
];
}
}

View File

@@ -9,7 +9,6 @@ use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Actions\EditAction;
use Filament\Resources\Pages\ViewRecord;
use Filament\Support\Enums\IconSize;
class ViewRole extends ViewRecord
{
@@ -22,8 +21,7 @@ class ViewRole extends ViewRecord
protected function getDefaultHeaderActions(): array
{
return [
EditAction::make()
->iconButton()->iconSize(IconSize::ExtraLarge),
EditAction::make(),
];
}
}

View File

@@ -3,6 +3,7 @@
namespace App\Filament\Admin\Resources\Roles;
use App\Enums\CustomizationKey;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\Roles\Pages\CreateRole;
use App\Filament\Admin\Resources\Roles\Pages\EditRole;
use App\Filament\Admin\Resources\Roles\Pages\ListRoles;
@@ -15,6 +16,8 @@ use App\Traits\Filament\CanModifyTable;
use BackedEnum;
use Exception;
use Filament\Actions\Action;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\CreateAction;
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction;
use Filament\Actions\ViewAction;
@@ -43,7 +46,7 @@ class RoleResource extends Resource
protected static ?string $model = Role::class;
protected static string|\BackedEnum|null $navigationIcon = 'tabler-users-group';
protected static string|BackedEnum|null $navigationIcon = TablerIcon::UsersGroup;
protected static ?string $recordTitleAttribute = 'name';
@@ -100,10 +103,13 @@ class RoleResource extends Resource
->hidden(fn ($record) => static::getEditAuthorizationResponse($record)->allowed()),
EditAction::make(),
])
->checkIfRecordIsSelectableUsing(fn (Role $role) => !$role->isRootAdmin() && $role->users_count <= 0)
->groupedBulkActions([
DeleteBulkAction::make(),
]);
->toolbarActions([
CreateAction::make(),
BulkActionGroup::make([
DeleteBulkAction::make('exclude_bulk_delete'),
]),
])
->checkIfRecordIsSelectableUsing(fn (Role $role) => !$role->isRootAdmin() && $role->users_count <= 0);
}
/**

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Resources\Servers\Pages;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\Servers\ServerResource;
use App\Filament\Components\Forms\Fields\StartupVariable;
use App\Models\Allocation;
@@ -70,15 +71,17 @@ class CreateServer extends CreateRecord
->components([
Wizard::make($this->getSteps())
->columnSpanFull()
->nextAction(fn (Action $action) => $action->iconButton()->iconSize(IconSize::ExtraLarge)->icon('tabler-arrow-right'))
->previousAction(fn (Action $action) => $action->iconButton()->iconSize(IconSize::ExtraLarge)->icon('tabler-arrow-left'))
->nextAction(fn (Action $action) => $action->tooltip(fn () => $action->getLabel())->iconButton()->iconSize(IconSize::ExtraLarge)->icon(TablerIcon::ArrowRight))
->previousAction(fn (Action $action) => $action->tooltip(fn () => $action->getLabel())->iconButton()->iconSize(IconSize::ExtraLarge)->icon(TablerIcon::ArrowLeft))
->submitAction(new HtmlString(Blade::render(<<<'BLADE'
<x-filament::button
<x-filament::icon-button
type="submit"
size="sm"
iconSize="xl"
icon="tabler-plus"
tooltip="{{ trans('admin/server.create') }}"
>
{{ trans('admin/server.create') }}
</x-filament::button>
</x-filament::icon-button>
BLADE))),
]);
}
@@ -93,8 +96,8 @@ class CreateServer extends CreateRecord
return [
Step::make('Information')
->label(trans('admin/server.tabs.information'))
->icon('tabler-info-circle')
->completedIcon('tabler-check')
->icon(TablerIcon::InfoCircle)
->completedIcon(TablerIcon::Check)
->columns([
'default' => 1,
'sm' => 4,
@@ -102,9 +105,10 @@ class CreateServer extends CreateRecord
])
->schema([
TextInput::make('name')
->prefixIcon('tabler-server')
->prefixIcon(TablerIcon::Server)
->label(trans('admin/server.name'))
->suffixAction(Action::make('random')
->suffixAction(Action::make('hint_random')
->tooltip('Random')
->icon('tabler-dice-' . random_int(1, 6))
->action(function (Set $set, Get $get) {
$egg = Egg::find($get('egg_id'));
@@ -134,7 +138,7 @@ class CreateServer extends CreateRecord
Select::make('node_id')
->disabledOn('edit')
->prefixIcon('tabler-server-2')
->prefixIcon(TablerIcon::Server2)
->selectablePlaceholder(false)
->default(function () {
$lastUsedNode = session()->get('last_utilized_node');
@@ -168,7 +172,7 @@ class CreateServer extends CreateRecord
Select::make('owner_id')
->preload()
->prefixIcon('tabler-user')
->prefixIcon(TablerIcon::User)
->selectablePlaceholder(false)
->default(user()?->id)
->label(trans('admin/server.owner'))
@@ -198,7 +202,7 @@ class CreateServer extends CreateRecord
TextInput::make('password')
->label(trans('admin/user.password'))
->hintIcon('tabler-question-mark', trans('admin/user.password_help'))
->hintIcon(TablerIcon::QuestionMark, trans('admin/user.password_help'))
->password(),
])
->createOptionUsing(function ($data, UserCreationService $service) {
@@ -211,7 +215,7 @@ class CreateServer extends CreateRecord
Select::make('allocation_id')
->preload()
->live()
->prefixIcon('tabler-network')
->prefixIcon(TablerIcon::Network)
->label(trans('admin/server.primary_allocation'))
->columnSpan([
'default' => 1,
@@ -247,21 +251,36 @@ class CreateServer extends CreateRecord
return [
Select::make('allocation_ip')
->options(fn () => collect(Node::find($get('node_id'))?->ipAddresses())->mapWithKeys(fn (string $ip) => [$ip => $ip]))
->options(fn (Get $get) => collect(Node::find($getPage('node_id'))?->ipAddresses())
->when($get('allocation_ip'), fn ($ips, $current) => $ips->push($current))
->unique()
->mapWithKeys(fn (string $ip) => [$ip => $ip]))
->label(trans('admin/server.ip_address'))->inlineLabel()
->helperText(trans('admin/server.ip_address_helper'))
->afterStateUpdated(fn (Set $set) => $set('allocation_ports', []))
->ip()
->live()
->hintAction(
Action::make('refresh')
Action::make('hint_refresh')
->iconButton()
->icon('tabler-refresh')
->icon(TablerIcon::Refresh)
->tooltip(trans('admin/node.refresh'))
->action(function () use ($get) {
cache()->forget("nodes.{$get('node_id')}.ips");
})
)
->suffixAction(
Action::make('custom_ip')
->icon(TablerIcon::Keyboard)
->tooltip(trans('admin/node.custom_ip'))
->schema([
TextInput::make('custom_ip')
->label(trans('admin/node.ip_address'))
->ip()
->required(),
])
->action(fn (array $data, Set $set) => $set('allocation_ip', $data['custom_ip']))
)
->required(),
TextInput::make('allocation_alias')
->label(trans('admin/server.alias'))->inlineLabel()
@@ -304,7 +323,7 @@ class CreateServer extends CreateRecord
->live()
->preload()
->disableOptionsWhenSelectedInSiblingRepeaterItems()
->prefixIcon('tabler-network')
->prefixIcon(TablerIcon::Network)
->label(trans('admin/server.additional_allocations'))
->columnSpan(2)
->disabled(fn (Get $get) => $get('../../allocation_id') === null || $get('../../node_id') === null)
@@ -333,8 +352,8 @@ class CreateServer extends CreateRecord
]),
Step::make(trans('admin/server.tabs.egg_configuration'))
->icon('tabler-egg')
->completedIcon('tabler-check')
->icon(TablerIcon::Egg)
->completedIcon(TablerIcon::Check)
->columns([
'default' => 1,
'sm' => 4,
@@ -344,7 +363,7 @@ class CreateServer extends CreateRecord
->schema([
Select::make('egg_id')
->label(trans('admin/server.name'))
->prefixIcon('tabler-egg')
->prefixIcon(TablerIcon::Egg)
->relationship('egg', 'name')
->columnSpan([
'default' => 1,
@@ -401,8 +420,8 @@ class CreateServer extends CreateRecord
true => 'danger',
])
->icons([
false => 'tabler-code',
true => 'tabler-code-off',
false => TablerIcon::Code,
true => TablerIcon::CodeOff,
])
->inline()
->required(),
@@ -426,8 +445,8 @@ class CreateServer extends CreateRecord
false => 'danger',
])
->icons([
true => 'tabler-code',
false => 'tabler-code-off',
true => TablerIcon::Code,
false => TablerIcon::CodeOff,
])
->inline(),
@@ -475,7 +494,7 @@ class CreateServer extends CreateRecord
Hidden::make('environment')->default([]),
Section::make(trans('admin/server.variables'))
->icon('tabler-eggs')
->icon(TablerIcon::Eggs)
->iconColor('primary')
->hidden(fn (Get $get) => $get('egg_id') === null)
->collapsible()
@@ -512,8 +531,8 @@ class CreateServer extends CreateRecord
]),
]),
Step::make(trans('admin/server.tabs.environment_configuration'))
->icon('tabler-brand-docker')
->completedIcon('tabler-check')
->icon(TablerIcon::BrandDocker)
->completedIcon(TablerIcon::Check)
->schema([
Fieldset::make(trans('admin/server.resource_limits'))
->columnSpan(6)
@@ -549,7 +568,7 @@ class CreateServer extends CreateRecord
->hidden(fn (Get $get) => $get('unlimited_cpu'))
->label(trans('admin/server.cpu_limit'))->inlineLabel()
->suffix('%')
->hintIcon('tabler-question-mark', trans('admin/server.cpu_helper'))
->hintIcon(TablerIcon::QuestionMark, trans('admin/server.cpu_helper'))
->default(0)
->required()
->columnSpan(2)
@@ -581,7 +600,7 @@ class CreateServer extends CreateRecord
->hidden(fn (Get $get) => $get('unlimited_mem'))
->label(trans('admin/server.memory_limit'))->inlineLabel()
->suffix(config('panel.use_binary_prefix') ? 'MiB' : 'MB')
->hintIcon('tabler-question-mark', trans('admin/server.memory_helper'))
->hintIcon(TablerIcon::QuestionMark, trans('admin/server.memory_helper'))
->default(0)
->required()
->columnSpan(2)
@@ -745,21 +764,21 @@ class CreateServer extends CreateRecord
->schema([
TextInput::make('allocation_limit')
->label(trans('admin/server.allocations'))
->suffixIcon('tabler-network')
->suffixIcon(TablerIcon::Network)
->required()
->numeric()
->minValue(0)
->default(0),
TextInput::make('database_limit')
->label(trans('admin/server.databases'))
->suffixIcon('tabler-database')
->suffixIcon(TablerIcon::Database)
->required()
->numeric()
->minValue(0)
->default(0),
TextInput::make('backup_limit')
->label(trans('admin/server.backups'))
->suffixIcon('tabler-copy-check')
->suffixIcon(TablerIcon::CopyCheck)
->required()
->numeric()
->minValue(0)

View File

@@ -3,6 +3,7 @@
namespace App\Filament\Admin\Resources\Servers\Pages;
use App\Enums\SuspendAction;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\Servers\ServerResource;
use App\Filament\Components\Actions\DeleteServerIcon;
use App\Filament\Components\Actions\PreviewStartupAction;
@@ -56,7 +57,6 @@ use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Components\Utilities\Set;
use Filament\Schemas\Schema;
use Filament\Support\Enums\Alignment;
use Filament\Support\Enums\IconSize;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Client\ConnectionException;
use Illuminate\Support\Arr;
@@ -108,7 +108,7 @@ class EditServer extends EditRecord
return [
Tab::make('information')
->label(trans('admin/server.tabs.information'))
->icon('tabler-info-circle')
->icon(TablerIcon::InfoCircle)
->schema([
Grid::make()
->columns(2)
@@ -121,8 +121,9 @@ class EditServer extends EditRecord
->columnSpan(2)
->alignJustify(),
Action::make('uploadIcon')
->iconButton()->iconSize(IconSize::Large)
->icon('tabler-photo-up')
->hiddenLabel()
->icon(TablerIcon::PhotoUp)
->tooltip(trans('admin/server.import_image'))
->modal()
->modalSubmitActionLabel(trans('server/setting.server_info.icon.upload'))
->schema([
@@ -257,9 +258,10 @@ class EditServer extends EditRecord
])
->schema([
TextInput::make('name')
->prefixIcon('tabler-server')
->prefixIcon(TablerIcon::Server)
->label(trans('admin/server.name'))
->suffixAction(Action::make('random')
->suffixAction(Action::make('hint_random')
->tooltip('Random')
->icon('tabler-dice-' . random_int(1, 6))
->action(function (Set $set, Get $get) {
$egg = Egg::find($get('egg_id'));
@@ -278,7 +280,7 @@ class EditServer extends EditRecord
->required()
->maxLength(255),
Select::make('owner_id')
->prefixIcon('tabler-user')
->prefixIcon(TablerIcon::User)
->label(trans('admin/server.owner'))
->columnSpan([
'default' => 2,
@@ -384,7 +386,7 @@ class EditServer extends EditRecord
]),
Tab::make('environment_configuration')
->label(trans('admin/server.tabs.environment_configuration'))
->icon('tabler-brand-docker')
->icon(TablerIcon::BrandDocker)
->schema([
Fieldset::make(trans('admin/server.resource_limits'))
->columnSpanFull()
@@ -421,7 +423,7 @@ class EditServer extends EditRecord
->hidden(fn (Get $get) => $get('unlimited_cpu'))
->label(trans('admin/server.cpu_limit'))->inlineLabel()
->suffix('%')
->hintIcon('tabler-question-mark', trans('admin/server.cpu_helper'))
->hintIcon(TablerIcon::QuestionMark, trans('admin/server.cpu_helper'))
->required()
->columnSpan(2)
->numeric()
@@ -453,7 +455,7 @@ class EditServer extends EditRecord
->hidden(fn (Get $get) => $get('unlimited_mem'))
->label(trans('admin/server.memory_limit'))->inlineLabel()
->suffix(config('panel.use_binary_prefix') ? 'MiB' : 'MB')
->hintIcon('tabler-question-mark', trans('admin/server.memory_helper'))
->hintIcon(TablerIcon::QuestionMark, trans('admin/server.memory_helper'))
->required()
->columnSpan(2)
->numeric()
@@ -623,19 +625,19 @@ class EditServer extends EditRecord
->schema([
TextInput::make('allocation_limit')
->label(trans('admin/server.allocations'))
->suffixIcon('tabler-network')
->suffixIcon(TablerIcon::Network)
->required()
->minValue(0)
->numeric(),
TextInput::make('database_limit')
->label(trans('admin/server.databases'))
->suffixIcon('tabler-database')
->suffixIcon(TablerIcon::Database)
->required()
->minValue(0)
->numeric(),
TextInput::make('backup_limit')
->label(trans('admin/server.backups'))
->suffixIcon('tabler-copy-check')
->suffixIcon(TablerIcon::CopyCheck)
->required()
->minValue(0)
->numeric(),
@@ -705,7 +707,7 @@ class EditServer extends EditRecord
]),
Tab::make('egg')
->label(trans('admin/server.egg'))
->icon('tabler-egg')
->icon(TablerIcon::Egg)
->columns([
'default' => 1,
'sm' => 3,
@@ -715,7 +717,7 @@ class EditServer extends EditRecord
->schema([
Select::make('egg_id')
->disabled()
->prefixIcon('tabler-egg')
->prefixIcon(TablerIcon::Egg)
->columnSpan([
'default' => 6,
'sm' => 3,
@@ -728,7 +730,7 @@ class EditServer extends EditRecord
->preload()
->required()
->hintAction(
Action::make('change_egg')
Action::make('hint_change_egg')
->label(trans('admin/server.change_egg'))
->action(function (array $data, Server $server, EggChangerService $service) {
$service->handle($server, $data['egg_id'], $data['keep_old_variables']);
@@ -739,7 +741,7 @@ class EditServer extends EditRecord
->schema(fn (Server $server) => [
Select::make('egg_id')
->label(trans('admin/server.new_egg'))
->prefixIcon('tabler-egg')
->prefixIcon(TablerIcon::Egg)
->options(fn () => Egg::all()->filter(fn (Egg $egg) => $egg->id !== $server->egg->id)->mapWithKeys(fn (Egg $egg) => [$egg->id => $egg->name]))
->searchable()
->preload()
@@ -769,8 +771,8 @@ class EditServer extends EditRecord
1 => 'danger',
])
->icons([
0 => 'tabler-code',
1 => 'tabler-code-off',
0 => TablerIcon::Code,
1 => TablerIcon::CodeOff,
])
->required(),
@@ -795,7 +797,7 @@ class EditServer extends EditRecord
})
->selectablePlaceholder(false)
->columnSpanFull()
->hintAction(PreviewStartupAction::make('preview')),
->hintAction(PreviewStartupAction::make('hint_preview')),
Textarea::make('startup')
->hiddenLabel()
@@ -841,13 +843,13 @@ class EditServer extends EditRecord
]),
Tab::make('mounts')
->label(trans('admin/server.mounts'))
->icon('tabler-layers-linked')
->icon(TablerIcon::LayersLinked)
->schema(fn (Get $get) => [
ServerResource::getMountCheckboxList($get),
]),
Tab::make('actions')
->label(trans('admin/server.actions'))
->icon('tabler-settings')
->icon(TablerIcon::Settings)
->schema([
Fieldset::make(trans('admin/server.actions'))
->columnSpanFull()
@@ -862,7 +864,7 @@ class EditServer extends EditRecord
->columnSpan(3)
->schema([
Actions::make([
Action::make('toggleInstall')
Action::make('exclude_toggle_install')
->label(trans('admin/server.toggle_install'))
->disabled(fn (Server $server) => $server->isSuspended())
->modal(fn (Server $server) => $server->isFailedInstall())
@@ -913,7 +915,7 @@ class EditServer extends EditRecord
->columnSpan(3)
->schema([
Actions::make([
Action::make('toggleSuspend')
Action::make('exclude_toggle_suspend')
->label(trans('admin/server.suspend'))
->color('warning')
->hidden(fn (Server $server) => $server->isSuspended())
@@ -934,7 +936,7 @@ class EditServer extends EditRecord
->send();
}
}),
Action::make('toggleUnsuspend')
Action::make('exclude_toggle_unsuspend')
->label(trans('admin/server.unsuspend'))
->color('success')
->hidden(fn (Server $server) => !$server->isSuspended())
@@ -969,7 +971,7 @@ class EditServer extends EditRecord
->columnSpan(3)
->schema([
Actions::make([
Action::make('transfer')
Action::make('exclude_transfer')
->label(trans('admin/server.transfer'))
->disabled(fn (Server $server) => user()?->accessibleNodes()->count() <= 1 || $server->isInConflictState())
->modalHeading(trans('admin/server.transfer'))
@@ -1007,7 +1009,7 @@ class EditServer extends EditRecord
->columnSpan(3)
->schema([
Actions::make([
Action::make('reinstall')
Action::make('exclude_reinstall')
->label(trans('admin/server.reinstall'))
->color('danger')
->requiresConfirmation()
@@ -1048,7 +1050,7 @@ class EditServer extends EditRecord
return [
Select::make('node_id')
->label(trans('admin/server.node'))
->prefixIcon('tabler-server-2')
->prefixIcon(TablerIcon::Server2)
->selectablePlaceholder(false)
->default(fn (Server $server) => user()?->accessibleNodes()->whereNot('id', $server->node->id)->first()?->id)
->required()
@@ -1058,7 +1060,7 @@ class EditServer extends EditRecord
->label(trans('admin/server.primary_allocation'))
->disabled(fn (Get $get, Server $server) => !$get('node_id') || !$server->allocation_id)
->required(fn (Server $server) => $server->allocation_id)
->prefixIcon('tabler-network')
->prefixIcon(TablerIcon::Network)
->options(fn (Get $get) => Allocation::where('node_id', $get('node_id'))->whereNull('server_id')->get()->mapWithKeys(fn (Allocation $allocation) => [$allocation->id => $allocation->address]))
->searchable(['ip', 'port', 'ip_alias'])
->placeholder(trans('admin/server.select_allocation')),
@@ -1068,7 +1070,7 @@ class EditServer extends EditRecord
->multiple()
->minItems(fn (Select $select) => $select->getMaxItems())
->maxItems(fn (Select $select, Server $server) => $select->isDisabled() ? null : $server->allocations->count() - 1)
->prefixIcon('tabler-network')
->prefixIcon(TablerIcon::Network)
->required(fn (Server $server) => $server->allocations->count() > 1)
->options(fn (Get $get) => Allocation::where('node_id', $get('node_id'))->whereNull('server_id')->when($get('allocation_id'), fn ($query) => $query->whereNot('id', $get('allocation_id')))->get()->mapWithKeys(fn (Allocation $allocation) => [$allocation->id => $allocation->address]))
->searchable(['ip', 'port', 'ip_alias'])
@@ -1100,7 +1102,8 @@ class EditServer extends EditRecord
return [
Action::make('Delete')
->color('danger')
->label(trans('filament-actions::delete.single.label'))
->hiddenLabel()
->tooltip(trans('filament-actions::delete.single.label'))
->modalHeading(trans('filament-actions::delete.single.modal.heading', ['label' => $this->getRecordTitle()]))
->modalSubmitActionLabel(trans('filament-actions::delete.single.label'))
->requiresConfirmation()
@@ -1116,16 +1119,15 @@ class EditServer extends EditRecord
->title(trans('admin/server.notifications.error_server_delete'))
->body(trans('admin/server.notifications.error_server_delete_body'))
->color('warning')
->icon('tabler-database')
->icon(TablerIcon::Database)
->warning()
->send();
}
})
->hidden(fn () => $canForceDelete)
->authorize(fn (Server $server) => user()?->can('delete server', $server))
->icon('tabler-trash')
->iconButton()->iconSize(IconSize::ExtraLarge),
Action::make('ForceDelete')
->icon(TablerIcon::Trash),
Action::make('exclude_force_delete')
->color('danger')
->label(trans('filament-actions::force-delete.single.label'))
->modalHeading(trans('filament-actions::force-delete.single.modal.heading', ['label' => $this->getRecordTitle()]))
@@ -1143,13 +1145,16 @@ class EditServer extends EditRecord
->visible(fn () => $canForceDelete)
->authorize(fn (Server $server) => user()?->can('delete server', $server)),
Action::make('console')
->label(trans('admin/server.console'))
->icon('tabler-terminal')
->iconButton()->iconSize(IconSize::ExtraLarge)
->hiddenLabel()
->tooltip(trans('admin/server.console'))
->icon(TablerIcon::Terminal)
->url(fn (Server $server) => Console::getUrl(panel: 'server', tenant: $server)),
$this->getSaveFormAction()->formId('form')
->iconButton()->iconSize(IconSize::ExtraLarge)
->icon('tabler-device-floppy'),
Action::make('save')
->hiddenLabel()
->action('save')
->keyBindings(['mod+s'])
->tooltip(trans('filament-panels::resources/pages/edit-record.form.actions.save.label'))
->icon(TablerIcon::DeviceFloppy),
];
}
@@ -1187,7 +1192,7 @@ class EditServer extends EditRecord
->title(trans('admin/server.notifications.error_connecting', ['node' => $server->node->name]))
->body(trans('admin/server.notifications.error_connecting_description'))
->color('warning')
->icon('tabler-database')
->icon(TablerIcon::Database)
->warning()
->send();
}
@@ -1214,18 +1219,20 @@ class EditServer extends EditRecord
],
]);
$normalizedExtension = match ($extension) {
'svg+xml', 'svg' => 'svg',
'jpeg', 'jpg' => 'jpg',
'png' => 'png',
'webp' => 'webp',
default => throw new Exception(trans('admin/egg.import.unknown_extension')),
};
$data = @file_get_contents($imageUrl, false, $context, 0, 262144); //256KB
if (empty($data)) {
throw new \Exception(trans('admin/egg.import.invalid_url'));
throw new Exception(trans('admin/egg.import.invalid_url'));
}
$normalizedExtension = match ($extension) {
'svg+xml' => 'svg',
'jpeg' => 'jpg',
default => $extension,
};
Storage::disk('public')->put(Server::ICON_STORAGE_PATH . "/$server->uuid.$normalizedExtension", $data);
}
}

View File

@@ -2,17 +2,16 @@
namespace App\Filament\Admin\Resources\Servers\Pages;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\Servers\ServerResource;
use App\Filament\Server\Pages\Console;
use App\Models\Server;
use App\Traits\Filament\CanCustomizeHeaderActions;
use App\Traits\Filament\CanCustomizeHeaderWidgets;
use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Actions\CreateAction;
use Filament\Actions\EditAction;
use Filament\Resources\Pages\ListRecords;
use Filament\Support\Enums\IconSize;
use Filament\Tables\Columns\SelectColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Grouping\Group;
@@ -91,28 +90,19 @@ class ListServers extends ListRecords
->sortable(),
])
->recordActions([
Action::make('View')
->label(trans('admin/server.view'))
->iconButton()
->icon('tabler-terminal')
->iconSize(IconSize::Large)
Action::make('view')
->tooltip(trans('admin/server.view'))
->icon(TablerIcon::Terminal)
->url(fn (Server $server) => Console::getUrl(panel: 'server', tenant: $server))
->authorize(fn (Server $server) => user()?->canAccessTenant($server)),
EditAction::make(),
])
->emptyStateIcon('tabler-brand-docker')
->toolbarActions([
CreateAction::make(),
])
->searchable()
->emptyStateIcon(TablerIcon::BrandDocker)
->emptyStateDescription('')
->emptyStateHeading(trans('admin/server.no_servers'));
}
/** @return array<Action|ActionGroup> */
protected function getDefaultHeaderActions(): array
{
return [
CreateAction::make()
->iconButton()->iconSize(IconSize::ExtraLarge)
->icon('tabler-file-plus'),
];
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Resources\Servers\RelationManagers;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\Servers\Pages\CreateServer;
use App\Models\Allocation;
use App\Models\Server;
@@ -51,8 +52,8 @@ class AllocationsRelationManager extends RelationManager
->placeholder(trans('admin/server.no_notes')),
IconColumn::make('primary')
->icon(fn ($state) => match ($state) {
true => 'tabler-star-filled',
default => 'tabler-star',
true => TablerIcon::StarFilled,
default => TablerIcon::Star,
})
->color(fn ($state) => match ($state) {
true => 'warning',
@@ -65,8 +66,8 @@ class AllocationsRelationManager extends RelationManager
IconColumn::make('is_locked')
->label(trans('admin/server.locked'))
->tooltip(trans('admin/server.locked_helper'))
->trueIcon('tabler-lock')
->falseIcon('tabler-lock-open'),
->trueIcon(TablerIcon::Lock)
->falseIcon(TablerIcon::LockOpen),
])
->recordActions([
Action::make('make-primary')
@@ -106,26 +107,40 @@ class AllocationsRelationManager extends RelationManager
}
}),
CreateAction::make()
->label(trans('admin/server.create_allocation'))
->icon('tabler-network')
->iconButton()->iconSize(IconSize::ExtraLarge)
->hiddenLabel()
->tooltip(trans('admin/server.create_allocation'))
->icon(TablerIcon::Network)
->createAnother(false)
->schema(fn () => [
Select::make('allocation_ip')
->options(fn () => collect($this->getOwnerRecord()->node->ipAddresses())->mapWithKeys(fn (string $ip) => [$ip => $ip]))
->options(fn (Get $get) => collect($this->getOwnerRecord()->node->ipAddresses())
->when($get('allocation_ip'), fn ($ips, $current) => $ips->push($current))
->unique()
->mapWithKeys(fn (string $ip) => [$ip => $ip]))
->label(trans('admin/server.ip_address'))
->inlineLabel()
->ip()
->live()
->hintAction(
Action::make('refresh')
->iconButton()
->icon('tabler-refresh')
->icon(TablerIcon::Refresh)
->tooltip(trans('admin/node.refresh'))
->action(function () {
cache()->forget("nodes.{$this->getOwnerRecord()->node->id}.ips");
})
)
->suffixAction(
Action::make('custom_ip')
->icon(TablerIcon::Keyboard)
->tooltip(trans('admin/node.custom_ip'))
->schema([
TextInput::make('custom_ip')
->label(trans('admin/node.ip_address'))
->ip()
->required(),
])
->action(fn (array $data, Set $set) => $set('allocation_ip', $data['custom_ip']))
)
->afterStateUpdated(fn (Set $set) => $set('allocation_ports', []))
->required(),
TextInput::make('allocation_alias')
@@ -147,14 +162,14 @@ class AllocationsRelationManager extends RelationManager
])
->action(fn (array $data, AssignmentService $service) => $service->handle($this->getOwnerRecord()->node, $data, $this->getOwnerRecord())),
AssociateAction::make()
->icon('tabler-file-plus')
->icon(TablerIcon::FilePlus)
->iconButton()->iconSize(IconSize::ExtraLarge)
->multiple()
->associateAnother(false)
->preloadRecordSelect()
->recordSelectOptionsQuery(fn ($query) => $query->whereBelongsTo($this->getOwnerRecord()->node)->whereNull('server_id'))
->recordSelectSearchColumns(['ip', 'port'])
->label(trans('admin/server.add_allocation'))
->tooltip(trans('admin/server.add_allocation'))
->after(function (array $data) {
Allocation::whereIn('id', array_values(array_unique($data['recordId'])))->update(['is_locked' => true]);

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Resources\Servers\RelationManagers;
use App\Enums\TablerIcon;
use App\Filament\Components\Actions\RotateDatabasePasswordAction;
use App\Filament\Components\Tables\Columns\DateTimeColumn;
use App\Models\Database;
@@ -18,7 +19,6 @@ use Filament\Forms\Components\TextInput;
use Filament\Notifications\Notification;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Schemas\Schema;
use Filament\Support\Enums\IconSize;
use Filament\Support\Exceptions\Halt;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
@@ -83,7 +83,6 @@ class DatabasesRelationManager extends RelationManager
ViewAction::make()
->color('primary'),
DeleteAction::make()
->iconButton()->iconSize(IconSize::ExtraLarge)
->successNotificationTitle(null)
->using(function (Database $database, DatabaseManagementService $service) {
try {
@@ -105,11 +104,11 @@ class DatabasesRelationManager extends RelationManager
])
->toolbarActions([
CreateAction::make()
->hiddenLabel()
->disabled(fn () => DatabaseHost::count() < 1)
->label(fn () => DatabaseHost::count() < 1 ? trans('admin/server.no_db_hosts') : trans('admin/server.create_database'))
->tooltip(fn () => DatabaseHost::count() < 1 ? trans('admin/server.no_db_hosts') : trans('admin/server.create_database'))
->color(fn () => DatabaseHost::count() < 1 ? 'danger' : 'primary')
->icon(fn () => DatabaseHost::count() < 1 ? 'tabler-database-x' : 'tabler-database-plus')
->iconButton()->iconSize(IconSize::ExtraLarge)
->icon(fn () => DatabaseHost::count() < 1 ? TablerIcon::DatabaseX : TablerIcon::DatabasePlus)
->createAnother(false)
->action(function (array $data, DatabaseManagementService $service, RandomWordService $randomWordService) {
$data['database'] ??= $randomWordService->word() . random_int(1, 420);
@@ -143,13 +142,13 @@ class DatabasesRelationManager extends RelationManager
->label(trans('admin/server.name'))
->alphaDash()
->prefix(fn () => 's' . $this->getOwnerRecord()->id . '_')
->hintIcon('tabler-question-mark', trans('admin/databasehost.table.name_helper')),
->hintIcon(TablerIcon::QuestionMark, trans('admin/databasehost.table.name_helper')),
TextInput::make('remote')
->columnSpan(1)
->regex('/^[\w\-\/.%:]+$/')
->label(trans('admin/databasehost.table.remote'))
->default('%')
->hintIcon('tabler-question-mark', trans('admin/databasehost.table.remote_helper')),
->hintIcon(TablerIcon::QuestionMark, trans('admin/databasehost.table.remote_helper')),
]),
]);
}

View File

@@ -3,6 +3,7 @@
namespace App\Filament\Admin\Resources\Servers;
use App\Enums\CustomizationKey;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\Servers\Pages\CreateServer;
use App\Filament\Admin\Resources\Servers\Pages\EditServer;
use App\Filament\Admin\Resources\Servers\Pages\ListServers;
@@ -12,6 +13,7 @@ use App\Models\Mount;
use App\Models\Server;
use App\Traits\Filament\CanCustomizePages;
use App\Traits\Filament\CanCustomizeRelations;
use BackedEnum;
use Exception;
use Filament\Forms\Components\CheckboxList;
use Filament\Resources\Pages\PageRegistration;
@@ -27,7 +29,7 @@ class ServerResource extends Resource
protected static ?string $model = Server::class;
protected static string|\BackedEnum|null $navigationIcon = 'tabler-brand-docker';
protected static string|BackedEnum|null $navigationIcon = TablerIcon::BrandDocker;
protected static ?string $recordTitleAttribute = 'name';

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Resources\Users\Pages;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\Users\UserResource;
use App\Models\Role;
use App\Services\Users\UserCreationService;
@@ -10,7 +11,6 @@ use App\Traits\Filament\CanCustomizeHeaderWidgets;
use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Resources\Pages\CreateRecord;
use Filament\Support\Enums\IconSize;
use Illuminate\Database\Eloquent\Model;
class CreateUser extends CreateRecord
@@ -33,9 +33,12 @@ class CreateUser extends CreateRecord
protected function getDefaultHeaderActions(): array
{
return [
$this->getCreateFormAction()->formId('form')
->iconButton()->iconSize(IconSize::ExtraLarge)
->icon('tabler-user-plus'),
Action::make('create')
->hiddenLabel()
->action('create')
->keyBindings(['mod+s'])
->tooltip(trans('filament-panels::resources/pages/create-record.form.actions.create.label'))
->icon(TablerIcon::UserPlus),
];
}

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Resources\Users\Pages;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\Users\UserResource;
use App\Models\User;
use App\Services\Users\UserUpdateService;
@@ -11,7 +12,6 @@ use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Actions\DeleteAction;
use Filament\Resources\Pages\EditRecord;
use Filament\Support\Enums\IconSize;
use Illuminate\Database\Eloquent\Model;
class EditUser extends EditRecord
@@ -33,12 +33,14 @@ class EditUser extends EditRecord
{
return [
DeleteAction::make()
->label(fn (User $user) => user()?->id === $user->id ? trans('admin/user.self_delete') : ($user->servers()->count() > 0 ? trans('admin/user.has_servers') : trans('filament-actions::delete.single.modal.actions.delete.label')))
->disabled(fn (User $user) => user()?->id === $user->id || $user->servers()->count() > 0)
->iconButton()->iconSize(IconSize::ExtraLarge),
$this->getSaveFormAction()->formId('form')
->iconButton()->iconSize(IconSize::ExtraLarge)
->icon('tabler-device-floppy'),
->tooltip(fn (User $user) => user()?->id === $user->id ? trans('admin/user.self_delete') : ($user->servers()->count() > 0 ? trans('admin/user.has_servers') : trans('filament-actions::delete.single.modal.actions.delete.label')))
->disabled(fn (User $user) => user()?->id === $user->id || $user->servers()->count() > 0),
Action::make('save')
->hiddenLabel()
->action('save')
->keyBindings(['mod+s'])
->tooltip(trans('filament-panels::resources/pages/edit-record.form.actions.save.label'))
->icon(TablerIcon::DeviceFloppy),
];
}

View File

@@ -5,11 +5,7 @@ namespace App\Filament\Admin\Resources\Users\Pages;
use App\Filament\Admin\Resources\Users\UserResource;
use App\Traits\Filament\CanCustomizeHeaderActions;
use App\Traits\Filament\CanCustomizeHeaderWidgets;
use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Actions\CreateAction;
use Filament\Resources\Pages\ListRecords;
use Filament\Support\Enums\IconSize;
class ListUsers extends ListRecords
{
@@ -17,14 +13,4 @@ class ListUsers extends ListRecords
use CanCustomizeHeaderWidgets;
protected static string $resource = UserResource::class;
/** @return array<Action|ActionGroup> */
protected function getDefaultHeaderActions(): array
{
return [
CreateAction::make()
->iconButton()->iconSize(IconSize::ExtraLarge)
->icon('tabler-user-plus'),
];
}
}

View File

@@ -9,7 +9,6 @@ use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Actions\EditAction;
use Filament\Resources\Pages\ViewRecord;
use Filament\Support\Enums\IconSize;
class ViewUser extends ViewRecord
{
@@ -22,8 +21,7 @@ class ViewUser extends ViewRecord
protected function getDefaultHeaderActions(): array
{
return [
EditAction::make()
->iconButton()->iconSize(IconSize::ExtraLarge),
EditAction::make(),
];
}
}

View File

@@ -3,6 +3,7 @@
namespace App\Filament\Admin\Resources\Users;
use App\Enums\CustomizationKey;
use App\Enums\TablerIcon;
use App\Extensions\OAuth\OAuthService;
use App\Facades\Activity;
use App\Filament\Admin\Resources\Users\Pages\CreateUser;
@@ -21,9 +22,12 @@ use App\Traits\Filament\CanCustomizeRelations;
use App\Traits\Filament\CanCustomizeStaticTabs;
use App\Traits\Filament\CanModifyForm;
use App\Traits\Filament\CanModifyTable;
use BackedEnum;
use DateTimeZone;
use Exception;
use Filament\Actions\Action;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\CreateAction;
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction;
use Filament\Actions\ViewAction;
@@ -66,7 +70,7 @@ class UserResource extends Resource
protected static ?string $model = User::class;
protected static string|\BackedEnum|null $navigationIcon = 'tabler-users';
protected static string|BackedEnum|null $navigationIcon = TablerIcon::Users;
protected static ?string $recordTitleAttribute = 'username';
@@ -117,7 +121,7 @@ class UserResource extends Resource
IconColumn::make('mfa_email_enabled')
->label(trans('profile.tabs.2fa'))
->visibleFrom('lg')
->icon(fn (User $user) => filled($user->mfa_app_secret) ? 'tabler-qrcode' : ($user->mfa_email_enabled ? 'tabler-mail' : 'tabler-lock-open-off'))
->icon(fn (User $user) => filled($user->mfa_app_secret) ? TablerIcon::Qrcode : ($user->mfa_email_enabled ? TablerIcon::Mail : TablerIcon::LockOpenOff))
->tooltip(fn (User $user) => filled($user->mfa_app_secret) ? 'App' : ($user->mfa_email_enabled ? 'E-Mail' : 'None')),
TextColumn::make('roles.name')
->label(trans('admin/user.roles'))
@@ -136,10 +140,15 @@ class UserResource extends Resource
->hidden(fn ($record) => static::getEditAuthorizationResponse($record)->allowed()),
EditAction::make(),
])
->checkIfRecordIsSelectableUsing(fn (User $user) => user()?->id !== $user->id && !$user->servers_count)
->groupedBulkActions([
DeleteBulkAction::make(),
]);
->toolbarActions([
BulkActionGroup::make([
DeleteBulkAction::make('exclude_bulk_delete'),
]),
CreateAction::make()
->hiddenLabel()
->icon(TablerIcon::UserPlus),
])
->checkIfRecordIsSelectableUsing(fn (User $user) => user()?->id !== $user->id && !$user->servers_count);
}
public static function defaultForm(Schema $schema): Schema
@@ -159,7 +168,7 @@ class UserResource extends Resource
return [
Tab::make('account')
->label(trans('profile.tabs.account'))
->icon('tabler-user-cog')
->icon(TablerIcon::UserCog)
->columns([
'default' => 1,
'md' => 3,
@@ -194,13 +203,13 @@ class UserResource extends Resource
'md' => 1,
'lg' => 1,
])
->hintIcon(fn ($operation) => $operation === 'create' ? 'tabler-question-mark' : null, fn ($operation) => $operation === 'create' ? trans('admin/user.password_help') : null)
->hintIcon(fn ($operation) => $operation === 'create' ? TablerIcon::QuestionMark : null, fn ($operation) => $operation === 'create' ? trans('admin/user.password_help') : null)
->password()
->hintAction(
Action::make('password_reset')
Action::make('hint_password_reset')
->label(trans('admin/user.password_reset'))
->hidden(fn (string $operation) => $operation === 'create' || config('mail.default', 'log') === 'log')
->icon('tabler-send')
->icon(TablerIcon::Send)
->action(function (User $user) {
$status = Password::broker(Filament::getPanel('app')->getAuthPasswordBroker())->sendResetLink([
'email' => $user->email,
@@ -237,7 +246,7 @@ class UserResource extends Resource
]),
Toggle::make('is_managed_externally')
->label(trans('admin/user.is_managed_externally'))
->hintIcon('tabler-question-mark', trans('admin/user.is_managed_externally_helper'))
->hintIcon(TablerIcon::QuestionMark, trans('admin/user.is_managed_externally_helper'))
->inline(false)
->columnSpan([
'default' => 1,
@@ -252,7 +261,7 @@ class UserResource extends Resource
Select::make('timezone')
->label(trans('profile.timezone'))
->required()
->prefixIcon('tabler-clock-pin')
->prefixIcon(TablerIcon::ClockPin)
->default(fn () => config('app.timezone', 'UTC'))
->selectablePlaceholder(false)
->options(fn () => collect(DateTimeZone::listIdentifiers())->mapWithKeys(fn ($tz) => [$tz => $tz]))
@@ -260,7 +269,7 @@ class UserResource extends Resource
Select::make('language')
->label(trans('profile.language'))
->required()
->prefixIcon('tabler-flag')
->prefixIcon(TablerIcon::Flag)
->live()
->default('en')
->searchable()
@@ -315,7 +324,7 @@ class UserResource extends Resource
$actions[] = Action::make("oauth_$id")
->label(trans('profile.unlink', ['name' => $name]))
->icon('tabler-unlink')
->icon(TablerIcon::Unlink)
->requiresConfirmation()
->color($color)
->action(function ($livewire) use ($oauthService, $user, $name, $schema) {
@@ -341,7 +350,7 @@ class UserResource extends Resource
]),
Tab::make('roles')
->label(trans('admin/user.roles'))
->icon('tabler-users-group')
->icon(TablerIcon::UsersGroup)
->schema([
CheckboxList::make('roles')
->hidden(fn (?User $user) => $user && $user->isRootAdmin())
@@ -368,7 +377,7 @@ class UserResource extends Resource
Tab::make('keys')
->visible(fn (?User $user) => $user)
->label(trans('profile.tabs.keys'))
->icon('tabler-key')
->icon(TablerIcon::Key)
->schema([
Section::make(trans('profile.api_keys'))
->columnSpan(2)
@@ -464,7 +473,7 @@ class UserResource extends Resource
->visible(fn (?User $user) => $user)
->disabledOn('create')
->label(trans('profile.tabs.activity'))
->icon('tabler-history')
->icon(TablerIcon::History)
->schema([
Repeater::make('activity')
->hiddenLabel()

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Resources\Webhooks\Pages;
use App\Enums\TablerIcon;
use App\Enums\WebhookType;
use App\Filament\Admin\Resources\Webhooks\WebhookResource;
use App\Traits\Filament\CanCustomizeHeaderActions;
@@ -9,7 +10,6 @@ use App\Traits\Filament\CanCustomizeHeaderWidgets;
use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Resources\Pages\CreateRecord;
use Filament\Support\Enums\IconSize;
class CreateWebhookConfiguration extends CreateRecord
{
@@ -25,11 +25,15 @@ class CreateWebhookConfiguration extends CreateRecord
{
return [
$this->getCancelFormAction()->formId('form')
->iconButton()->iconSize(IconSize::ExtraLarge)
->icon('tabler-arrow-left'),
$this->getCreateFormAction()->formId('form')
->iconButton()->iconSize(IconSize::ExtraLarge)
->icon('tabler-file-plus'),
->hiddenLabel()
->tooltip(trans('filament-panels::resources/pages/create-record.form.actions.cancel.label'))
->icon(TablerIcon::ArrowLeft),
Action::make('create')
->hiddenLabel()
->action('create')
->keyBindings(['mod+s'])
->tooltip(trans('filament-panels::resources/pages/create-record.form.actions.create.label'))
->icon(TablerIcon::Plus),
];
}

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Resources\Webhooks\Pages;
use App\Enums\TablerIcon;
use App\Enums\WebhookType;
use App\Filament\Admin\Resources\Webhooks\WebhookResource;
use App\Models\WebhookConfiguration;
@@ -11,7 +12,6 @@ use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Actions\DeleteAction;
use Filament\Resources\Pages\EditRecord;
use Filament\Support\Enums\IconSize;
class EditWebhookConfiguration extends EditRecord
{
@@ -24,17 +24,19 @@ class EditWebhookConfiguration extends EditRecord
protected function getDefaultHeaderActions(): array
{
return [
DeleteAction::make()
->iconButton()->iconSize(IconSize::ExtraLarge),
DeleteAction::make(),
Action::make('test_now')
->label(trans('admin/webhook.test_now'))
->tooltip(trans('admin/webhook.test_now'))
->color('primary')
->disabled(fn (WebhookConfiguration $webhookConfiguration) => count($webhookConfiguration->events) === 0)
->action(fn (WebhookConfiguration $webhookConfiguration) => $webhookConfiguration->run())
->tooltip(trans('admin/webhook.test_now_help')),
$this->getSaveFormAction()->formId('form')
->iconButton()->iconSize(IconSize::ExtraLarge)
->icon('tabler-device-floppy'),
->icon(TablerIcon::TestPipe),
Action::make('save')
->hiddenLabel()
->action('save')
->keyBindings(['mod+s'])
->tooltip(trans('filament-panels::resources/pages/edit-record.form.actions.save.label'))
->icon(TablerIcon::DeviceFloppy),
];
}

View File

@@ -5,11 +5,7 @@ namespace App\Filament\Admin\Resources\Webhooks\Pages;
use App\Filament\Admin\Resources\Webhooks\WebhookResource;
use App\Traits\Filament\CanCustomizeHeaderActions;
use App\Traits\Filament\CanCustomizeHeaderWidgets;
use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Actions\CreateAction;
use Filament\Resources\Pages\ListRecords;
use Filament\Support\Enums\IconSize;
class ListWebhookConfigurations extends ListRecords
{
@@ -17,14 +13,4 @@ class ListWebhookConfigurations extends ListRecords
use CanCustomizeHeaderWidgets;
protected static string $resource = WebhookResource::class;
/** @return array<Action|ActionGroup> */
protected function getDefaultHeaderActions(): array
{
return [
CreateAction::make()
->iconButton()->iconSize(IconSize::ExtraLarge)
->icon('tabler-file-plus'),
];
}
}

View File

@@ -9,7 +9,6 @@ use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Actions\EditAction;
use Filament\Resources\Pages\ViewRecord;
use Filament\Support\Enums\IconSize;
class ViewWebhookConfiguration extends ViewRecord
{
@@ -22,8 +21,7 @@ class ViewWebhookConfiguration extends ViewRecord
protected function getDefaultHeaderActions(): array
{
return [
EditAction::make()
->iconButton()->iconSize(IconSize::ExtraLarge),
EditAction::make(),
];
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Resources\Webhooks;
use App\Enums\TablerIcon;
use App\Enums\WebhookType;
use App\Filament\Admin\Resources\Webhooks\Pages\CreateWebhookConfiguration;
use App\Filament\Admin\Resources\Webhooks\Pages\EditWebhookConfiguration;
@@ -13,8 +14,11 @@ use App\Traits\Filament\CanCustomizePages;
use App\Traits\Filament\CanCustomizeRelations;
use App\Traits\Filament\CanModifyForm;
use App\Traits\Filament\CanModifyTable;
use BackedEnum;
use Exception;
use Filament\Actions\Action;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\CreateAction;
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction;
use Filament\Actions\ReplicateAction;
@@ -51,7 +55,7 @@ class WebhookResource extends Resource
protected static ?string $model = WebhookConfiguration::class;
protected static string|\BackedEnum|null $navigationIcon = 'tabler-webhook';
protected static string|BackedEnum|null $navigationIcon = TablerIcon::Webhook;
protected static ?string $recordTitleAttribute = 'description';
@@ -107,10 +111,13 @@ class WebhookResource extends Resource
->beforeReplicaSaved(fn (WebhookConfiguration $replica) => $replica->description .= ' Copy ' . now()->format('Y-m-d H:i:s'))
->successRedirectUrl(fn (WebhookConfiguration $replica) => EditWebhookConfiguration::getUrl(['record' => $replica])),
])
->groupedBulkActions([
DeleteBulkAction::make(),
->toolbarActions([
CreateAction::make(),
BulkActionGroup::make([
DeleteBulkAction::make('exclude_bulk_delete'),
]),
])
->emptyStateIcon('tabler-webhook')
->emptyStateIcon(TablerIcon::Webhook)
->emptyStateDescription('')
->emptyStateHeading(trans('admin/webhook.no_webhooks'))
->persistFiltersInSession()
@@ -143,9 +150,9 @@ class WebhookResource extends Resource
->schema(fn () => self::getRegularFields())
->headerActions([
Action::make('reset_headers')
->label(trans('admin/webhook.reset_headers'))
->tooltip(trans('admin/webhook.reset_headers'))
->color('danger')
->icon('heroicon-o-trash')
->icon(TablerIcon::Restore)
->action(fn (Get $get, Set $set) => $set('headers', [
'X-Webhook-Event' => '{{event}}',
])),
@@ -330,7 +337,7 @@ class WebhookResource extends Resource
AlertBanner::make('discord_webhook_help')
->title(trans('admin/webhook.help'))
->body(trans('admin/webhook.help_text'))
->icon('tabler-question-mark')
->icon(TablerIcon::QuestionMark)
->info()
->send();
}

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Widgets;
use App\Enums\TablerIcon;
use Exception;
use Filament\Actions\Action;
use Filament\Infolists\Components\TextEntry;
@@ -25,7 +26,7 @@ class CanaryWidget extends FormWidget
return $schema
->components([
Section::make(trans('admin/dashboard.sections.intro-developers.heading'))
->icon('tabler-code')
->icon(TablerIcon::Code)
->iconColor('primary')
->collapsible()
->collapsed()
@@ -39,9 +40,9 @@ class CanaryWidget extends FormWidget
->state(trans('admin/dashboard.sections.intro-developers.extra_note')),
])
->headerActions([
Action::make('issues')
Action::make('db_issues')
->label(trans('admin/dashboard.sections.intro-developers.button_issues'))
->icon('tabler-brand-github')
->icon(TablerIcon::BrandGithub)
->url('https://github.com/pelican-dev/panel/issues', true),
]),
]);

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Widgets;
use App\Enums\TablerIcon;
use Exception;
use Filament\Actions\Action;
use Filament\Infolists\Components\TextEntry;
@@ -20,7 +21,7 @@ class HelpWidget extends FormWidget
return $schema
->components([
Section::make(trans('admin/dashboard.sections.intro-help.heading'))
->icon('tabler-question-mark')
->icon(TablerIcon::QuestionMark)
->iconColor('info')
->collapsible()
->persistCollapsed()
@@ -30,9 +31,9 @@ class HelpWidget extends FormWidget
->state(trans('admin/dashboard.sections.intro-help.content')),
])
->headerActions([
Action::make('docs')
Action::make('db_docs')
->label(trans('admin/dashboard.sections.intro-help.button_docs'))
->icon('tabler-speedboat')
->icon(TablerIcon::Speedboat)
->url('https://pelican.dev/docs', true),
]),
]);

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Widgets;
use App\Enums\TablerIcon;
use App\Filament\Admin\Resources\Nodes\Pages\CreateNode;
use App\Models\Node;
use Exception;
@@ -27,7 +28,7 @@ class NoNodesWidget extends FormWidget
return $schema
->components([
Section::make(trans('admin/dashboard.sections.intro-first-node.heading'))
->icon('tabler-server-2')
->icon(TablerIcon::Server2)
->iconColor('primary')
->collapsible()
->persistCollapsed()
@@ -37,9 +38,9 @@ class NoNodesWidget extends FormWidget
->state(trans('admin/dashboard.sections.intro-first-node.content')),
])
->headerActions([
Action::make('create-node')
Action::make('db_create-node')
->label(trans('admin/dashboard.sections.intro-first-node.button_label'))
->icon('tabler-server-2')
->icon(TablerIcon::Server2)
->url(CreateNode::getUrl()),
]),
]);

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Widgets;
use App\Enums\TablerIcon;
use Exception;
use Filament\Actions\Action;
use Filament\Infolists\Components\TextEntry;
@@ -20,7 +21,7 @@ class SupportWidget extends FormWidget
return $schema
->components([
Section::make(trans('admin/dashboard.sections.intro-support.heading'))
->icon('tabler-heart-filled')
->icon(TablerIcon::HeartFilled)
->iconColor('danger')
->collapsible()
->persistCollapsed()
@@ -33,9 +34,9 @@ class SupportWidget extends FormWidget
->state(trans('admin/dashboard.sections.intro-support.extra_note')),
])
->headerActions([
Action::make('donate')
Action::make('db_donate')
->label(trans('admin/dashboard.sections.intro-support.button_donate'))
->icon('tabler-cash')
->icon(TablerIcon::Cash)
->url('https://pelican.dev/donate', true)
->color('success'),
]),

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Admin\Widgets;
use App\Enums\TablerIcon;
use App\Services\Helpers\SoftwareVersionService;
use Exception;
use Filament\Actions\Action;
@@ -31,7 +32,7 @@ class UpdateWidget extends FormWidget
->components([
$isLatest
? Section::make(trans('admin/dashboard.sections.intro-no-update.heading'))
->icon('tabler-checkbox')
->icon(TablerIcon::Checkbox)
->iconColor('success')
->schema([
TextEntry::make('info')
@@ -39,14 +40,14 @@ class UpdateWidget extends FormWidget
->state(trans('admin/dashboard.sections.intro-no-update.content', ['version' => $this->softwareVersionService->currentPanelVersion()])),
])
: Section::make(trans('admin/dashboard.sections.intro-update-available.heading'))
->icon('tabler-info-circle')
->icon(TablerIcon::InfoCircle)
->iconColor('warning')
->schema([
TextEntry::make('info')
->hiddenLabel()
->state(trans('admin/dashboard.sections.intro-update-available.content', ['latestVersion' => $this->softwareVersionService->latestPanelVersion()])),
Section::make(trans('admin/dashboard.sections.intro-update-available.button_changelog'))
->icon('tabler-script')
->icon(TablerIcon::Script)
->collapsible()
->collapsed()
->schema([
@@ -57,9 +58,9 @@ class UpdateWidget extends FormWidget
]),
])
->headerActions([
Action::make('update')
Action::make('db_update')
->label(trans('admin/dashboard.sections.intro-update-available.heading'))
->icon('tabler-clipboard-text')
->icon(TablerIcon::ClipboardText)
->url('https://pelican.dev/docs/panel/update', true)
->color('warning'),
]),

View File

@@ -5,6 +5,7 @@ namespace App\Filament\App\Resources\Servers\Pages;
use App\Enums\CustomizationKey;
use App\Enums\ServerResourceType;
use App\Enums\SubuserPermission;
use App\Enums\TablerIcon;
use App\Filament\App\Resources\Servers\ServerResource;
use App\Filament\Components\Tables\Columns\ProgressBarColumn;
use App\Filament\Components\Tables\Columns\ServerEntryColumn;
@@ -127,7 +128,7 @@ class ListServers extends ListRecords
->recordActions(!$usingGrid ? static::getPowerActionGroup() : [])
->recordActionsAlignment(Alignment::Center->value)
->contentGrid($usingGrid ? ['default' => 1, 'md' => 2] : null)
->emptyStateIcon('tabler-brand-docker')
->emptyStateIcon(TablerIcon::BrandDocker)
->emptyStateDescription('')
->emptyStateHeading(fn () => $this->activeTab === 'my' ? 'You don\'t own any servers!' : 'You don\'t have access to any servers!')
->persistFiltersInSession()
@@ -243,34 +244,34 @@ class ListServers extends ListRecords
Action::make('start')
->label(trans('server/console.power_actions.start'))
->color('primary')
->icon('tabler-player-play-filled')
->icon(TablerIcon::PlayerPlayFilled)
->authorize(fn (Server $server) => user()?->can(SubuserPermission::ControlStart, $server))
->visible(fn (Server $server) => $server->retrieveStatus()->isStartable())
->dispatch('powerAction', fn (Server $server) => ['server' => $server, 'action' => 'start']),
Action::make('restart')
->label(trans('server/console.power_actions.restart'))
->color('gray')
->icon('tabler-reload')
->icon(TablerIcon::Reload)
->authorize(fn (Server $server) => user()?->can(SubuserPermission::ControlRestart, $server))
->visible(fn (Server $server) => $server->retrieveStatus()->isRestartable())
->dispatch('powerAction', fn (Server $server) => ['server' => $server, 'action' => 'restart']),
Action::make('stop')
->label(trans('server/console.power_actions.stop'))
->color('danger')
->icon('tabler-player-stop-filled')
->icon(TablerIcon::PlayerStopFilled)
->authorize(fn (Server $server) => user()?->can(SubuserPermission::ControlStop, $server))
->visible(fn (Server $server) => $server->retrieveStatus()->isStoppable() && !$server->retrieveStatus()->isKillable())
->dispatch('powerAction', fn (Server $server) => ['server' => $server, 'action' => 'stop']),
Action::make('kill')
->label(trans('server/console.power_actions.kill'))
->color('danger')
->icon('tabler-alert-square')
->icon(TablerIcon::AlertSquare)
->tooltip(trans('server/console.power_actions.kill_tooltip'))
->authorize(fn (Server $server) => user()?->can(SubuserPermission::ControlStop, $server))
->visible(fn (Server $server) => $server->retrieveStatus()->isKillable())
->dispatch('powerAction', fn (Server $server) => ['server' => $server, 'action' => 'kill']),
])
->icon('tabler-power')
->icon(TablerIcon::Power)
->color('primary')
->tooltip(trans('server/dashboard.power_actions'))
->hidden(fn (Server $server) => $server->isInConflictState())

View File

@@ -2,15 +2,17 @@
namespace App\Filament\App\Resources\Servers;
use App\Enums\TablerIcon;
use App\Filament\App\Resources\Servers\Pages\ListServers;
use App\Models\Server;
use BackedEnum;
use Filament\Resources\Resource;
class ServerResource extends Resource
{
protected static ?string $model = Server::class;
protected static string|\BackedEnum|null $navigationIcon = 'tabler-brand-docker';
protected static string|BackedEnum|null $navigationIcon = TablerIcon::BrandDocker;
protected static ?string $slug = '/';

View File

@@ -2,10 +2,10 @@
namespace App\Filament\Components\Actions;
use App\Enums\TablerIcon;
use App\Models\Server;
use Filament\Actions\Action;
use Filament\Notifications\Notification;
use Filament\Support\Enums\IconSize;
use Illuminate\Support\Facades\Storage;
class DeleteServerIcon extends Action
@@ -23,11 +23,9 @@ class DeleteServerIcon extends Action
$this->hiddenLabel();
$this->icon('tabler-trash');
$this->tooltip(trans('admin/server.import_image'));
$this->iconButton();
$this->iconSize(IconSize::Large);
$this->icon(TablerIcon::Trash);
$this->color('danger');

View File

@@ -3,11 +3,11 @@
namespace App\Filament\Components\Actions;
use App\Enums\EggFormat;
use App\Enums\TablerIcon;
use App\Models\Egg;
use Filament\Actions\Action;
use Filament\Infolists\Components\TextEntry;
use Filament\Support\Enums\Alignment;
use Filament\Support\Enums\IconSize;
class ExportEggAction extends Action
{
@@ -20,15 +20,11 @@ class ExportEggAction extends Action
{
parent::setUp();
$this->label(trans('filament-actions::export.modal.actions.export.label'));
$this->tooltip(trans('filament-actions::export.modal.actions.export.label'));
$this->iconButton();
$this->icon(TablerIcon::Download);
$this->icon('tabler-download');
$this->tableIcon('tabler-download');
$this->iconSize(IconSize::ExtraLarge);
$this->tableIcon(TablerIcon::Download);
$this->authorize(fn () => user()?->can('export egg'));
@@ -45,11 +41,11 @@ class ExportEggAction extends Action
$this->modalFooterActionsAlignment(Alignment::Center);
$this->modalFooterActions([
Action::make('json')
Action::make('exclude_json')
->label(trans('admin/egg.export.as', ['format' => 'json']))
->url(fn (Egg $egg) => route('api.application.eggs.eggs.export', ['egg' => $egg, 'format' => EggFormat::JSON->value]), true)
->close(),
Action::make('yaml')
Action::make('exclude_yaml')
->label(trans('admin/egg.export.as', ['format' => 'yaml']))
->url(fn (Egg $egg) => route('api.application.eggs.eggs.export', ['egg' => $egg, 'format' => EggFormat::YAML->value]), true)
->close(),

View File

@@ -3,12 +3,12 @@
namespace App\Filament\Components\Actions;
use App\Enums\SubuserPermission;
use App\Enums\TablerIcon;
use App\Models\Schedule;
use App\Models\Server;
use App\Services\Schedules\Sharing\ScheduleExporterService;
use Filament\Actions\Action;
use Filament\Facades\Filament;
use Filament\Support\Enums\IconSize;
class ExportScheduleAction extends Action
{
@@ -23,11 +23,7 @@ class ExportScheduleAction extends Action
$this->hiddenLabel();
$this->iconButton();
$this->iconSize(IconSize::ExtraLarge);
$this->icon('tabler-download');
$this->icon(TablerIcon::Download);
$this->tooltip(trans('server/schedule.export'));

Some files were not shown because too many files have changed in this diff Show More