diff --git a/database/migrations/add_category_id_column_to_admin_kit_documents_table.php.stub b/database/migrations/add_category_id_column_to_admin_kit_documents_table.php.stub new file mode 100644 index 0000000..0079576 --- /dev/null +++ b/database/migrations/add_category_id_column_to_admin_kit_documents_table.php.stub @@ -0,0 +1,22 @@ +unsignedBigInteger('category_id')->nullable(); + }); + } + + public function down() + { + Schema::table('admin_kit_documents', function (Blueprint $table) { + $table->dropColumn('category_id'); + }); + } +}; diff --git a/database/migrations/create_admin_kit_document_categories_table.php.stub b/database/migrations/create_admin_kit_document_categories_table.php.stub new file mode 100644 index 0000000..7434701 --- /dev/null +++ b/database/migrations/create_admin_kit_document_categories_table.php.stub @@ -0,0 +1,25 @@ +id(); + + $table->json('title')->default('{}'); + $table->integer('sort')->nullable(); + + $table->timestamps(); + }); + } + + public function down() + { + Schema::dropIfExists('admin_kit_document_categories'); + } +}; diff --git a/src/DocumentsServiceProvider.php b/src/DocumentsServiceProvider.php index 0a675c5..d39cf46 100644 --- a/src/DocumentsServiceProvider.php +++ b/src/DocumentsServiceProvider.php @@ -24,6 +24,8 @@ public function configurePackage(Package $package): void ->hasMigrations([ 'create_admin_kit_documents_table', 'add_link_and_published_at_columns_to_admin_kit_documents_table', + 'create_admin_kit_document_categories_table', + 'add_category_id_column_to_admin_kit_documents_table', ]) ->hasCommand(DocumentsCommand::class); } diff --git a/src/FilamentPlugin.php b/src/FilamentPlugin.php index 3f892e2..bb36083 100644 --- a/src/FilamentPlugin.php +++ b/src/FilamentPlugin.php @@ -2,6 +2,7 @@ namespace AdminKit\Documents; +use AdminKit\Documents\UI\Filament\Resources\DocumentCategoryResource; use AdminKit\Documents\UI\Filament\Resources\DocumentResource; use Filament\Contracts\Plugin; use Filament\Panel; @@ -17,6 +18,7 @@ public function register(Panel $panel): void { $panel->resources([ DocumentResource::class, + DocumentCategoryResource::class, ]); } diff --git a/src/Models/Document.php b/src/Models/Document.php index 2bc0866..3587a4a 100644 --- a/src/Models/Document.php +++ b/src/Models/Document.php @@ -7,6 +7,7 @@ use Carbon\Carbon; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Database\Eloquent\Relations\BelongsTo; use Spatie\MediaLibrary\HasMedia; use Spatie\MediaLibrary\InteractsWithMedia; use Spatie\Translatable\HasTranslations; @@ -29,6 +30,11 @@ class Document extends AbstractModel implements HasMedia 'title', ]; + public function category(): BelongsTo + { + return $this->belongsTo(DocumentCategory::class); + } + public function scopeYear(Builder $query, $year): Builder { $date = Carbon::createFromDate($year); @@ -38,6 +44,12 @@ public function scopeYear(Builder $query, $year): Builder ->where('published_at', '<=', $date->copy()->endOfYear()); } + public function scopeCategoryId(Builder $query, $categoryId): Builder + { + return $query + ->whereHas('category', fn ($query) => $query->where('id', $categoryId)); + } + protected static function newFactory(): DocumentFactory { return new DocumentFactory(); diff --git a/src/Models/DocumentCategory.php b/src/Models/DocumentCategory.php new file mode 100644 index 0000000..acd66e7 --- /dev/null +++ b/src/Models/DocumentCategory.php @@ -0,0 +1,21 @@ +allowedFilters([ AllowedFilter::scope('year'), + AllowedFilter::scope('category_id'), ]) ->paginate(); @@ -35,4 +37,17 @@ public function years(): JsonResponse return response()->json($years); } + + public function categories(): JsonResponse + { + $locale = app()->getLocale(); + + $categories = DocumentCategory::query() + ->selectRaw("id, title->'$locale' as title") + ->orderBy('sort') + ->get() + ->toArray(); + + return response()->json($categories); + } } diff --git a/src/UI/API/Data/DocumentData.php b/src/UI/API/Data/DocumentData.php index b345758..3313034 100644 --- a/src/UI/API/Data/DocumentData.php +++ b/src/UI/API/Data/DocumentData.php @@ -18,6 +18,7 @@ public function __construct( public ?string $link, public ?array $file, public ?string $publishedAt, + public ?array $category, ) {} public static function fromModel(Document $document): DocumentData @@ -33,6 +34,7 @@ public static function fromModel(Document $document): DocumentData 'size' => $media->size, ] : null, publishedAt: $document->published_at, + category: $document->category->only('id', 'title'), ); } } diff --git a/src/UI/API/Routes/api.php b/src/UI/API/Routes/api.php index 6cf219a..3c11014 100644 --- a/src/UI/API/Routes/api.php +++ b/src/UI/API/Routes/api.php @@ -5,3 +5,4 @@ Route::get('/documents', [DocumentController::class, 'index']); Route::get('/documents/years', [DocumentController::class, 'years']); +Route::get('/documents/categories', [DocumentController::class, 'categories']); diff --git a/src/UI/Filament/Resources/DocumentCategoryResource.php b/src/UI/Filament/Resources/DocumentCategoryResource.php new file mode 100644 index 0000000..1891c67 --- /dev/null +++ b/src/UI/Filament/Resources/DocumentCategoryResource.php @@ -0,0 +1,98 @@ +schema([ + TranslatableTabs::make(fn ($locale) => [ + TextInput::make("title.$locale") + ->label('Наименование') + ->required($locale === app()->getLocale()), + ]) + ->columnSpan(2), + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('title') + ->label('Наименование') + ->limit(30), + Tables\Columns\TextColumn::make('sort') + ->label('Порядок'), + ]) + ->filters([ + // + ]) + ->actions([ + Tables\Actions\EditAction::make(), + ]) + ->bulkActions([ + Tables\Actions\BulkActionGroup::make([ + Tables\Actions\DeleteBulkAction::make(), + ]), + ]) + ->reorderable('sort') + ->defaultSort('sort'); + } + + public static function getRelations(): array + { + return [ + // + ]; + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ListDocumentCategory::route('/'), + 'create' => Pages\CreateDocumentCategory::route('/create'), + 'edit' => Pages\EditDocumentCategory::route('/{record}/edit'), + ]; + } +} diff --git a/src/UI/Filament/Resources/DocumentCategoryResource/Pages/CreateDocumentCategory.php b/src/UI/Filament/Resources/DocumentCategoryResource/Pages/CreateDocumentCategory.php new file mode 100644 index 0000000..144c094 --- /dev/null +++ b/src/UI/Filament/Resources/DocumentCategoryResource/Pages/CreateDocumentCategory.php @@ -0,0 +1,11 @@ +getLocale(); + return $form + ->columns(3) ->schema([ + Forms\Components\Grid::make() + ->columns() + ->columnSpan(2) + ->schema([ + TranslatableTabs::make(fn ($locale) => Forms\Components\Tabs\Tab::make($locale)->schema([ + Forms\Components\TextInput::make("title.$locale") + ->label(__('admin-kit-documents::documents.resource.title')) + ->required($locale === app()->getLocale()), + ])) + ->columnSpan(2), + Forms\Components\Select::make('category') + ->label('Категория') + ->preload() + ->columnSpan(1) + ->relationship( + name: 'category', + titleAttribute: 'title', + modifyQueryUsing: fn(Builder $query) => $query + ->selectRaw("id, title->>'$locale' as title, sort") + ->orderBy('sort'), + ) + ->createOptionForm([ + TranslatableTabs::make(fn ($locale) => [ + Forms\Components\TextInput::make("title.$locale") + ->label('Название') + ->required(), + ]), + ]), + Forms\Components\DateTimePicker::make('published_at') + ->label(__('admin-kit-documents::documents.resource.published_at')) + ->columnSpan(1) + ->default(now()), + ]), + Forms\Components\Tabs::make('') + ->columns(1) ->tabs(fn () => [ Tab::make(__('admin-kit-documents::documents.resource.file')) ->schema([ @@ -35,16 +79,7 @@ public static function form(Forms\Form $form): Forms\Form ]), ]) ->activeTab(fn (?Document $record) => $record?->link ? 2 : 1), - TranslatableTabs::make(fn ($locale) => Forms\Components\Tabs\Tab::make($locale)->schema([ - Forms\Components\TextInput::make("title.$locale") - ->label(__('admin-kit-documents::documents.resource.title')) - ->required($locale === app()->getLocale()), - ])), - Forms\Components\DateTimePicker::make('published_at') - ->label(__('admin-kit-documents::documents.resource.published_at')) - ->default(now()), - ]) - ->columns(1); + ]); } public static function table(Tables\Table $table): Tables\Table