選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

CategoryResource.php 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. <?php
  2. namespace App\Filament\Company\Resources\Setting;
  3. use App\Enums\CategoryType;
  4. use App\Filament\Company\Resources\Setting\CategoryResource\Pages;
  5. use App\Models\Setting\Category;
  6. use Closure;
  7. use Exception;
  8. use Filament\Forms\Form;
  9. use Filament\Notifications\Notification;
  10. use Filament\Resources\Resource;
  11. use Filament\Tables\Table;
  12. use Filament\{Forms, Tables};
  13. use Illuminate\Database\Eloquent\Collection;
  14. use Wallo\FilamentSelectify\Components\ToggleButton;
  15. class CategoryResource extends Resource
  16. {
  17. protected static ?string $model = Category::class;
  18. protected static ?string $navigationIcon = 'heroicon-o-folder';
  19. protected static ?string $navigationGroup = 'Settings';
  20. protected static ?string $slug = 'settings/categories';
  21. public static function form(Form $form): Form
  22. {
  23. return $form
  24. ->schema([
  25. Forms\Components\Section::make('General')
  26. ->schema([
  27. Forms\Components\TextInput::make('name')
  28. ->label('Name')
  29. ->autofocus()
  30. ->required()
  31. ->maxLength(255)
  32. ->rule(static function (Forms\Get $get, Forms\Components\Component $component): Closure {
  33. return static function (string $attribute, $value, Closure $fail) use ($get, $component) {
  34. $existingCategory = Category::where('company_id', auth()->user()->currentCompany->id)
  35. ->where('name', $value)
  36. ->where('type', $get('type'))
  37. ->first();
  38. if ($existingCategory && $existingCategory->getKey() !== $component->getRecord()?->getKey()) {
  39. $type = ucwords($get('type'));
  40. $fail("The {$type} category \"{$value}\" already exists.");
  41. }
  42. };
  43. }),
  44. Forms\Components\Select::make('type')
  45. ->options(CategoryType::class)
  46. ->required()
  47. ->native(false)
  48. ->label('Type'),
  49. Forms\Components\ColorPicker::make('color')
  50. ->required()
  51. ->label('Color'),
  52. ToggleButton::make('enabled')
  53. ->label('Default'),
  54. ])->columns(),
  55. ]);
  56. }
  57. /**
  58. * @throws Exception
  59. */
  60. public static function table(Table $table): Table
  61. {
  62. return $table
  63. ->columns([
  64. Tables\Columns\TextColumn::make('name')
  65. ->label('Name')
  66. ->weight('semibold')
  67. ->icon(static fn (Category $record) => $record->enabled ? 'heroicon-o-lock-closed' : null)
  68. ->tooltip(static fn (Category $record) => $record->enabled ? "Default {$record->type->getLabel()} Category" : null)
  69. ->iconPosition('after')
  70. ->searchable()
  71. ->sortable(),
  72. Tables\Columns\TextColumn::make('type')
  73. ->label('Type')
  74. ->sortable()
  75. ->searchable(),
  76. Tables\Columns\ColorColumn::make('color')
  77. ->label('Color')
  78. ->copyable()
  79. ->copyMessage('Color code copied'),
  80. ])
  81. ->filters([
  82. Tables\Filters\SelectFilter::make('type')
  83. ->label('Type')
  84. ->multiple()
  85. ->options(CategoryType::class),
  86. ])
  87. ->actions([
  88. Tables\Actions\EditAction::make(),
  89. Tables\Actions\DeleteAction::make()
  90. ->before(static function (Category $record, Tables\Actions\DeleteAction $action) {
  91. if ($record->enabled) {
  92. Notification::make()
  93. ->danger()
  94. ->title('Action Denied')
  95. ->body(__('The :name category is currently set as your default :type category and cannot be deleted. Please set a different category as your default before attempting to delete this one.', ['name' => $record->name, 'type' => $record->type->getLabel()]))
  96. ->persistent()
  97. ->send();
  98. $action->cancel();
  99. }
  100. }),
  101. ])
  102. ->bulkActions([
  103. Tables\Actions\BulkActionGroup::make([
  104. Tables\Actions\DeleteBulkAction::make()
  105. ->before(static function (Collection $records, Tables\Actions\DeleteBulkAction $action) {
  106. $defaultCategories = $records->filter(static function (Category $record) {
  107. return $record->enabled;
  108. });
  109. if ($defaultCategories->isNotEmpty()) {
  110. $defaultCategoryNames = $defaultCategories->pluck('name')->toArray();
  111. Notification::make()
  112. ->danger()
  113. ->title('Action Denied')
  114. ->body(static function () use ($defaultCategoryNames) {
  115. $message = __('The following categories are currently set as your default and cannot be deleted. Please set a different category as your default before attempting to delete these ones.') . '<br><br>';
  116. $message .= implode('<br>', array_map(static function ($name) {
  117. return '&bull; ' . $name;
  118. }, $defaultCategoryNames));
  119. return $message;
  120. })
  121. ->persistent()
  122. ->send();
  123. $action->cancel();
  124. }
  125. }),
  126. ]),
  127. ])
  128. ->emptyStateActions([
  129. Tables\Actions\CreateAction::make(),
  130. ]);
  131. }
  132. public static function getPages(): array
  133. {
  134. return [
  135. 'index' => Pages\ListCategories::route('/'),
  136. 'create' => Pages\CreateCategory::route('/create'),
  137. 'edit' => Pages\EditCategory::route('/{record}/edit'),
  138. ];
  139. }
  140. }