From d3a84bad04b941851d75d58d0f11e683198e2294 Mon Sep 17 00:00:00 2001 From: Leonid Nikitin Date: Wed, 22 Jul 2026 01:01:53 +0500 Subject: [PATCH] Add category-specific documentation view and management - Introduce routes and controller actions for displaying and managing documentation by category. - Adjust views to incorporate category-specific information and actions. - Update services to handle category retrieval and validation. - Add localized strings for new functionality in English and Russian. --- .../DocumentationVersionController.php | 4 +- .../Project/DocumentationVersionService.php | 51 +++++- app/application/lang/en.json | 3 + app/application/lang/en/admin-sections.php | 2 + app/application/lang/ru.json | 3 + app/application/lang/ru/admin-sections.php | 2 + .../documentation-versions/_top.blade.php | 30 +++- .../documentation-versions/show.blade.php | 163 +++++++++++++++--- app/application/routes/web.php | 1 + 9 files changed, 226 insertions(+), 33 deletions(-) diff --git a/app/application/app/Http/Controllers/Admin/Projects/DocumentationVersionController.php b/app/application/app/Http/Controllers/Admin/Projects/DocumentationVersionController.php index 36f1374..492435c 100644 --- a/app/application/app/Http/Controllers/Admin/Projects/DocumentationVersionController.php +++ b/app/application/app/Http/Controllers/Admin/Projects/DocumentationVersionController.php @@ -35,10 +35,10 @@ final class DocumentationVersionController extends Controller return view('admin/projects/documentation-versions/index', $result->getData()); } - public function show(int $projectId, int $id, Request $request): View + public function show(int $projectId, int $id, Request $request, ?int $category = null): View { $user = $request->user(); - $result = $this->documentationVersionService->show($projectId, $id, $user); + $result = $this->documentationVersionService->show($projectId, $id, $category, $user); if ($result->isError()) { $this->errors($result); } diff --git a/app/application/app/Services/Admin/Project/DocumentationVersionService.php b/app/application/app/Services/Admin/Project/DocumentationVersionService.php index 768bbc8..b208461 100644 --- a/app/application/app/Services/Admin/Project/DocumentationVersionService.php +++ b/app/application/app/Services/Admin/Project/DocumentationVersionService.php @@ -2,12 +2,17 @@ namespace App\Services\Admin\Project; +use App\Dto\Builder\Documentation as DocumentationBuilderDto; +use App\Dto\Builder\DocumentationCategory as DocumentationCategoryBuilderDto; use App\Dto\QuerySettingsDto; use App\Dto\Builder\DocumentationVersion as DocumentationVersionBuilderDto; use App\Dto\Service\Admin\Project\DocumentationVersion\StoreUpdate; use App\Enums\DocumentationVersionStatus; use App\Models\DocumentationVersion; +use App\Models\ProjectLanguage; use App\Models\User; +use App\Repositories\DocumentationCategoryRepository; +use App\Repositories\DocumentationRepository; use App\Repositories\DocumentationVersionRepository; use App\Repositories\ProjectRepository; use App\ServiceResults\ServiceResultArray; @@ -17,6 +22,8 @@ use App\ServiceResults\StoreUpdateResult; use App\Services\ClearCacheCommandHandler; use App\Services\DocumentationVersion\DocumentationVersionCommandHandler; use App\Services\Service; +use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Relations\HasOne; use Illuminate\Support\Facades\DB; final class DocumentationVersionService extends Service @@ -26,6 +33,9 @@ final class DocumentationVersionService extends Service private readonly DocumentationVersionRepository $documentationVersionRepository, private readonly DocumentationVersionCommandHandler $documentationVersionCommandHandler, private readonly ClearCacheCommandHandler $clearCacheCommandHandler, + + private readonly DocumentationCategoryRepository $documentationCategoryRepository, + private readonly DocumentationRepository $documentationRepository ) { } public function index(int $projectId, DocumentationVersionBuilderDto $documentationVersionBuilderDto, QuerySettingsDto $querySettingsDto, User $user): ServiceResultError | ServiceResultArray @@ -54,7 +64,7 @@ final class DocumentationVersionService extends Service ]); } - public function show(int $projectId, int $versionId, User $user): ServiceResultError | ServiceResultArray + public function show(int $projectId, int $versionId, ?int $categoryId, User $user): ServiceResultError | ServiceResultArray { $project = $this->projectRepository->getProjectById($projectId); if (\is_null($project)) { @@ -70,9 +80,48 @@ final class DocumentationVersionService extends Service return $this->errFobidden(__('Access is denied')); } + $category = null; + if (!\is_null($categoryId)) { + $category = $this->documentationCategoryRepository->getCategoryById($categoryId); + if (\is_null($category) || $category->version_id !== $version->id) { + return $this->errNotFound(__('Not Found')); + } + if ($user->cannot('view', $category)) { + return $this->errFobidden(__('Access is denied')); + } + } + + $defaultLanguage = $project->languages()->where('is_default', 1)->first(); + $with = [ + 'content' => function (HasOne $hasOne) use ($defaultLanguage) { + /** @var ?ProjectLanguage $defaultLanguage */ + $hasOne->when($defaultLanguage, function (Builder $query, ProjectLanguage $defaultLanguage) { + $query->where('language_id', $defaultLanguage->id); + }); + } + ]; + + $categoryDto = new DocumentationCategoryBuilderDto\Category($category->id ?? null); + $categories = $this->documentationCategoryRepository + ->getCategories( + $version->id, + new DocumentationCategoryBuilderDto(parentId: $categoryDto), + $with + )->all(); + $documents = $this->documentationRepository + ->getDocumentations( + $version->id, + new DocumentationBuilderDto(categoryId: $categoryDto), + $with + )->all(); + return $this->result([ 'version' => $version, 'project' => $project, + + 'category' => $category, + 'categories' => $categories, + 'documentations' => $documents, ]); } diff --git a/app/application/lang/en.json b/app/application/lang/en.json index d976cca..8ee4b02 100644 --- a/app/application/lang/en.json +++ b/app/application/lang/en.json @@ -38,6 +38,9 @@ "Connection Timed Out": "Connection Timed Out", "Continue": "Continue", "Create": "Create", + "Create documentation": "Create documentation", + "Create category": "Create category", + "Create version documentation": "Create a version of the documentation", "Create :name": "Create :name", "Created": "Created", "Delete": "Delete", diff --git a/app/application/lang/en/admin-sections.php b/app/application/lang/en/admin-sections.php index 69871f4..7309220 100644 --- a/app/application/lang/en/admin-sections.php +++ b/app/application/lang/en/admin-sections.php @@ -17,4 +17,6 @@ return [ 'Documentation' => 'Documentation', 'Categories' => 'Categories', 'Setting up automatic translation' => 'Setting up automatic translation', + 'Documentation not found' => 'Documentation not found', + 'No categories found' => 'No categories found', ]; diff --git a/app/application/lang/ru.json b/app/application/lang/ru.json index 0d55c4b..36c2e67 100644 --- a/app/application/lang/ru.json +++ b/app/application/lang/ru.json @@ -38,6 +38,9 @@ "Connection Timed Out": "Соединение не отвечает", "Continue": "Продолжай", "Create": "Создать", + "Create documentation": "Создать документацию", + "Create category": "Создать категорию", + "Create version documentation": "Создать версию документации", "Create :name": "Создать :name", "Created": "Создано", "Delete": "Удалить", diff --git a/app/application/lang/ru/admin-sections.php b/app/application/lang/ru/admin-sections.php index 09c6504..454ccd4 100644 --- a/app/application/lang/ru/admin-sections.php +++ b/app/application/lang/ru/admin-sections.php @@ -17,4 +17,6 @@ return [ 'Documentation' => 'Документация', 'Categories' => 'Категории', 'Setting up automatic translation' => 'Настройка автоматического перевода', + 'Documentation not found' => 'Документация не найдена', + 'No categories found' => 'Категории не найдены', ]; diff --git a/app/application/resources/views/admin/projects/documentation-versions/_top.blade.php b/app/application/resources/views/admin/projects/documentation-versions/_top.blade.php index 6010f38..d9d038b 100644 --- a/app/application/resources/views/admin/projects/documentation-versions/_top.blade.php +++ b/app/application/resources/views/admin/projects/documentation-versions/_top.blade.php @@ -1,18 +1,34 @@ - -
+
@can('create', \App\Models\DocumentationVersion::class) - + - {{ __('Create') }} + {{ __('Create version documentation') }} @endcan @can('viewAny', \App\Models\DocumentationVersion::class) - + - {{ __('List') }} + {{ __('admin-sections.Documentation version') }} @endcan + @if(!empty($version) && $version->id) + @can('viewAny', \App\Models\Documentation::class) + + + {{ __('admin-sections.Documentation') }} + + @endcan + @can('viewAny', \App\Models\DocumentationCategory::class) + + + {{ __('admin-sections.Categories') }} + + @endcan + @endif
- diff --git a/app/application/resources/views/admin/projects/documentation-versions/show.blade.php b/app/application/resources/views/admin/projects/documentation-versions/show.blade.php index 2100a7d..6a1dc09 100644 --- a/app/application/resources/views/admin/projects/documentation-versions/show.blade.php +++ b/app/application/resources/views/admin/projects/documentation-versions/show.blade.php @@ -1,45 +1,162 @@ @section('meta_title', __('admin-sections.Documentation version')) @section('h1', __('admin-sections.Project') . ': ' . $project->name) +@php + $categoryId = null; + if (!empty($category) && $category->id) { + $categoryId = $category->id; + } +@endphp @include('admin.projects.documentation-versions._top')
-

{{ __('admin-sections.Documentation version') }}: {{ $version->title }}

+

+ {{ __('admin-sections.Documentation version') }}: {{ $version->title }} +

+ @if(!empty($category)) +

+ {{ __('admin-sections.Categories') }}: {{ $category->content?->title }} +

+ @endif + @can('create', \App\Models\Documentation::class) + + + {{ __('Create documentation') }} + + @endcan + @can('create', \App\Models\DocumentationCategory::class) + + + {{ __('Create category') }} + + @endcan
- + + + + + + + - @can('viewAny', \App\Models\Documentation::class) - - + - - @endcan - @can('viewAny', \App\Models\DocumentationCategory::class) - - + + + - - @endcan + @endcan + @can('delete', $category) + + @csrf + @method('DELETE') + + + @endcan + + + @empty + + + + @endforelse + + + + + + + + + + + + @forelse($documentations as $documentation) + + + + + + + @empty + + + + @endforelse
{{ __('admin-sections.Sections') }}
{{ __('admin-sections.Categories') }}
{{ __('validation.attributes.title') }}{{ __('validation.attributes.slug') }}{{ __('validation.attributes.is_public') }}
- - - {{ __('admin-sections.Documentation') }} + @forelse($categories as $category) +
+ @can('view', $category) + + {{ $category->content?->title }} -
- - + {{ $category->slug }} + + @if($category->is_public) + {{ __('Yes') }} + @else + {{ __('No') }} + @endif + + @can('update', $category) + + + - {{ __('admin-sections.Categories') }} -
+
+ {{ __('admin-sections.No categories found') }} +
+
{{ __('admin-sections.Documentation') }}
{{ __('validation.attributes.title') }}{{ __('validation.attributes.slug') }}{{ __('validation.attributes.is_public') }}
+ {{ $documentation->content?->title }} + + {{ $documentation->slug }} + + @if($documentation->is_public) + {{ __('Yes') }} + @else + {{ __('No') }} + @endif + + @can('update', $documentation) + + + + + + @endcan + @can('delete', $documentation) +
+ @csrf + @method('DELETE') + +
+ @endcan +
+
+ {{ __('admin-sections.Documentation not found') }} +
+
+ @push('scripts') + @include('admin._scripts._click-confirm', ['alert' => __('Do you want to delete?')]) + @endpush
diff --git a/app/application/routes/web.php b/app/application/routes/web.php index 90ffec4..a6be9f0 100644 --- a/app/application/routes/web.php +++ b/app/application/routes/web.php @@ -38,6 +38,7 @@ Route::middleware(['auth', 'verified', \App\Http\Middleware\UserLocale::class])- Route::resource('documentation-versions', \App\Http\Controllers\Admin\Projects\DocumentationVersionController::class)->where(['documentation_version' => '[0-9]+']); Route::prefix('documentation-versions/{version}')->as('documentation-versions.')->group(function () { + Route::get('category/{category}', [\App\Http\Controllers\Admin\Projects\DocumentationVersionController::class, 'show'])->where(['category' => '[0-9]+'])->name('category.show'); Route::resource('documentations', \App\Http\Controllers\Admin\Projects\DocumentationsController::class)->except(['show'])->where(['documentation' => '[0-9]+']); Route::resource('categories', \App\Http\Controllers\Admin\Projects\DocumentationCategoriesController::class)->except(['show'])->where(['category' => '[0-9]+']); })->where(['version' => '[0-9]+']);