48 Commits
Author SHA1 Message Date
kor-elf 5613ead566 Merge pull request 'Версия 0.7.0' (#10) from develop into main
Reviewed-on: #10
2026-07-26 02:35:45 +05:00
kor-elf 4cdf11be3d Update production Docker Compose to switch images to MDHub registry
- Replace Docker Hub image references with MDHub equivalents across all services.
- Update environment variables and volume bindings for web and app services.
- Add production-specific environment variables (`APP_ENV`) for queue and scheduler.
2026-07-26 02:20:36 +05:00
kor-elf 0fc181bf12 Update Docker Compose files to use consolidated Dockerfile
- Replace references to separate `php/Dockerfile` and `web/Dockerfile` with the unified `docker/Dockerfile`.
- Adjust target stages across services for development and production environments.
2026-07-26 02:20:13 +05:00
kor-elf 059d2b9d66 Consolidate PHP and Nginx Dockerfiles
- Merge separate PHP and Nginx Dockerfiles into a unified structure under `app/docker/Dockerfile`.
- Simplify build stages and streamline multi-service configuration for production, development, and utility containers.
- Remove outdated individual Dockerfiles (`php/Dockerfile` and `web/Dockerfile`).
2026-07-26 02:19:29 +05:00
kor-elf 136451dc5a Add breadcrumbs to site documentation views
- Integrate breadcrumb rendering across documentation views (`index`, `category`, `view`, and `no-default-version`).
- Add support for dynamic JSON-LD breadcrumb generation.
2026-07-25 23:10:37 +05:00
kor-elf 1ee453dcfe Add category path support to site documentation views
- Introduce `categoryPath` for `DocumentationService` methods.
- Resolve category paths dynamically based on parent or category ID.
2026-07-25 23:10:18 +05:00
kor-elf 2a26008e87 Add breadcrumbs to site views
- Introduce breadcrumb SCSS styles and integrate `breadcrumbs/site.blade.php`.
- Update SCSS imports to include new breadcrumb styles.
2026-07-25 23:09:49 +05:00
kor-elf 031aa196d1 Add breadcrumbs to site feedback page
- Extend breadcrumb definitions for `home` and `feedbacks.index`.
- Integrate breadcrumbs into the feedback page layout.
- Add support for dynamic JSON-LD breadcrumb rendering.
2026-07-25 22:34:21 +05:00
kor-elf c3b9fa56fb Add breadcrumbs and dynamic head stack to site layout
- Inject breadcrumbs into the main site layout for improved navigation.
- Add `@stack('head')` for dynamic head content integration.
2026-07-25 22:33:43 +05:00
kor-elf 0922ee217f Adjust breadcrumb icon styling in SCSS 2026-07-25 20:37:33 +05:00
kor-elf 7a1b9ecda1 Refactor table structure in admin documentation versions view
- Consolidate category and documentation sections under a single table.
- Adjust layout for clarity and consistency.
2026-07-25 02:09:15 +05:00
kor-elf 5f0958f42e Add breadcrumbs to admin documentation categories views
- Implement breadcrumbs for `index`, `create`, and `edit` views.
- Add conditional logic for category paths in `create` and `edit` views.
2026-07-25 01:25:49 +05:00
kor-elf db0dce27b4 Add breadcrumbs to admin project documentation views
- Implement breadcrumbs for `index`, `create`, and `edit` views.
- Add conditional logic to handle optional category paths in `create` and `edit` views.
2026-07-25 01:25:31 +05:00
kor-elf 754a67c5d0 Add breadcrumbs to admin project documentation versions views
- Introduce breadcrumbs for `index`, `create`, `edit`, and `show` views.
- Adjust breadcrumb logic to handle optional categories in `show` view.
2026-07-25 01:25:18 +05:00
kor-elf ace4c69bd8 Add breadcrumbs to admin project service translate view
- Introduce breadcrumbs for improved navigation on the service translate view.
- Adjust heading structure and reorganize translation form layout.
2026-07-25 01:23:09 +05:00
kor-elf 42d8728b1b Add breadcrumbs to admin project translations views
- Add breadcrumbs to `languages` and `edit` views for improved navigation.
2026-07-25 01:22:26 +05:00
kor-elf efab6d8eed Add breadcrumbs to admin project links views 2026-07-25 01:22:13 +05:00
kor-elf aa03855bb3 Add breadcrumbs to admin project feedbacks index view 2026-07-25 01:21:59 +05:00
kor-elf 7fd3a0d45c Add breadcrumbs to admin project languages and edit views 2026-07-25 01:21:49 +05:00
kor-elf 506f403a00 Add breadcrumbs to admin project feedback view 2026-07-25 01:21:06 +05:00
kor-elf b8efe490a7 Add breadcrumbs to admin projects views
- Implement breadcrumbs for index, create, edit, and show views.
2026-07-25 01:20:54 +05:00
kor-elf e11815b795 Add breadcrumbs to admin users views
- Implement breadcrumbs for index, create, and edit views.
2026-07-25 01:20:08 +05:00
kor-elf d925928ea9 Add cache clearing after key documentation category operations
- Inject `ClearCacheCommandHandler` into `DocumentationCategoryService`.
- Clear cache when creating, updating, or deleting a documentation category.
- Extend responses to include `categoryPath` where applicable.
2026-07-25 01:19:09 +05:00
kor-elf 0d08276d44 Add category path resolution in DocumentationService
- Resolve `categoryPath` using `getPathFromRoot` based on the project's default language.
- Include the resolved `categoryPath` in the response.
2026-07-25 01:18:52 +05:00
kor-elf 54a2d84a00 Add category path resolution in DocumentationVersionService
- Fetch category path using `getPathFromRoot` for the default project language.
- Pass resolved `categoryPath` to the view.
2026-07-25 01:18:29 +05:00
kor-elf a70e09bddc Add recursive method to fetch category path in DocumentationCategoryRepository
- Implement `getPathFromRoot` to retrieve the category path using recursive SQL query.
- Cache results for improved performance.
2026-07-25 01:17:55 +05:00
kor-elf 6e8b708749 Add breadcrumbs for admin users, feedbacks, projects, and related views
- Extend admin breadcrumbs configuration with paths for users, feedbacks, projects, translations, links, about, documentation versions, documentations, and categories.
2026-07-25 01:02:25 +05:00
kor-elf 4a4d6d3bdf Add breadcrumbs for admin roles views
- Implement breadcrumbs in roles index, create, and edit views.
- Update admin breadcrumbs configuration with roles-specific paths.
2026-07-24 00:02:19 +05:00
kor-elf 2e7318c097 Set up custom breadcrumb view for admin panel
- Add `breadcrumbs/admin.blade.php` to define admin-specific breadcrumb structure.
- Update `Admin/Controller` to use the new breadcrumb view.
2026-07-23 23:58:00 +05:00
kor-elf e2f5d155ff Add breadcrumb support and hide navbar links on smaller screens
- Introduce optional `@yield('breadcrumbs')` for rendering breadcrumbs.
- Adjust navbar navigation visibility with `d-none d-lg-flex` class.
2026-07-23 23:57:24 +05:00
kor-elf ba9be40c78 Add profile and settings links to mobile navigation menu 2026-07-23 23:36:14 +05:00
kor-elf 0a612e72c7 Add breadcrumb support using Laravel Breadcrumbs package
- Install `diglactic/laravel-breadcrumbs` and update composer dependencies.
- Configure breadcrumbs in `config/breadcrumbs.php`.
- Define breadcrumbs for admin and site views.
- Update base admin controller to include default breadcrumb view.
2026-07-22 21:01:09 +05:00
kor-elf 949ffc6221 Update environment variables and dependencies in Docker Compose for production
- Replace `UNIT_SOURCE` with `APP_ENV` variable.
- Add `app` and `captcha-app` as dependencies in relevant services.
2026-07-22 20:57:11 +05:00
kor-elf 820450c48c Add optional category selection when creating documentation
- Update `DocumentationService::create` to support an optional `categoryId` parameter.
- Introduce `CreateRequest` for input validation.
- Adjust controller logic to handle `categoryId`.
- Restructure create/edit views under the `documentation-versions` directory.
2026-07-22 01:05:15 +05:00
kor-elf 3a7c747ac4 Add support for parent categories in documentation management
- Update `DocumentationCategoryService::create` to accept an optional `parentId` parameter.
- Introduce `CreateRequest` for validating parent category input.
- Adjust controller actions to handle parent category information.
- Restructure templates under `documentation-versions` for better organization.
2026-07-22 01:04:41 +05:00
kor-elf 02bcac7889 Move documentation templates under version-specific directories
- Relocate `documentations` views to the `documentation-versions` directory.
- Update includes and routes across affected templates to align with the new directory structure.
- Apply minor styling tweaks for improved spacing consistency.
2026-07-22 01:04:01 +05:00
kor-elf 6831592661 Move documentation category templates under version-specific directories
- Update paths to reflect the inclusion of documentation versions: `documentation-categories` views were moved into the `documentation-versions` directory.
- Adjusted includes and routes in affected templates to align with new structure.
- Minor styling updates (e.g., margins) for better spacing consistency.
2026-07-22 01:03:25 +05:00
kor-elf d3a84bad04 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.
2026-07-22 01:01:53 +05:00
kor-elf 756cafdbff Remove SCRIPT_NAME from FastCGI params and update Nginx default index to prioritize index.html. 2026-07-15 23:40:25 +05:00
kor-elf 9356b06ef5 Set default height of TinyMCE textarea to 600px in WYSIWYG component. 2026-07-15 23:00:43 +05:00
kor-elf b5258f840e Replace $request->get() with $request->attributes->get() throughout controllers and middleware for consistency and enhanced reliability. 2026-07-15 22:35:55 +05:00
kor-elf b35f04d220 Replace Unit configuration with Nginx + PHP-FPM setup in Docker
- Remove outdated Unit-based Docker configuration and scripts.
- Introduce Nginx + PHP-FPM stack with environment-based configurations.
- Add custom Nginx setup for frontend-backend routing.
- Update Dockerfiles, Docker Compose, and related scripts for new architecture.
2026-07-15 00:12:32 +05:00
kor-elf d4ae9e0e43 Merge pull request 'Версия 0.6.0' (#9) from develop into main
Reviewed-on: #9
2026-06-21 00:37:21 +05:00
kor-elf 859187bafa Update image version to 0.6.0 in production configuration 2026-06-21 00:17:32 +05:00
kor-elf 9e6e699db0 Add "Do not translate" functionality to TinyMCE editor
- Add a custom TinyMCE plugin to mark content with `translate="no"`.
- Update WYSIWYG editor to support the "Do not translate" toggle button and menu item.
- Highlight non-translatable content with custom styles in the editor.
- Localize plugin strings for English and Russian.
2026-06-20 23:54:25 +05:00
kor-elf 993350073c Cast description input to string with default value in StoreUpdateRequest. 2026-06-20 23:13:59 +05:00
kor-elf 9a6604a40b Replace InterventionImage::read with InterventionImage::decodePath for image processing 2026-06-20 22:18:51 +05:00
kor-elf 85a4361d0c UpUpdated Laravel to version 13. 2026-06-20 22:18:21 +05:00
106 changed files with 3929 additions and 4493 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
DOCKER_APP_PORT=8080
DOCKER_WEB_PORT=8080
DOCKER_CAPTCHA_PORT=8081
DOCKER_CAPTCHA_WEBSOCKET_PORT=8082
DOCKER_DB_PORT=3306
@@ -44,6 +44,7 @@ final class Translations
'site.Choose version',
'site.alert-status-not-supported',
'site.alert-status-future',
'Home',
];
foreach (DocumentationVersionStatus::cases() as $status) {
@@ -3,8 +3,12 @@
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller as BaseController;
use Illuminate\Support\Facades\Config;
abstract class Controller extends BaseController
{
public function __construct()
{
Config::set('breadcrumbs.view', 'breadcrumbs.admin');
}
}
@@ -11,7 +11,9 @@ final class LanguagesController extends Controller
{
public function __construct(
private readonly LanguageService $languageService,
) { }
) {
parent::__construct();
}
public function newLanguage(NewLanguageRequest $request): JsonResponse
{
@@ -13,7 +13,9 @@ final class AboutController extends Controller
{
public function __construct(
private readonly AboutService $aboutService,
) { }
) {
parent::__construct();
}
public function languages(int $project, Request $request): View
{
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Admin\Projects;
use App\Dto\QuerySettingsDto;
use App\Http\Controllers\Admin\Controller;
use App\Http\Requests\Admin\Projects\DocumentationCategories\CreateRequest;
use App\Http\Requests\Admin\Projects\DocumentationCategories\IndexRequest;
use App\Http\Requests\Admin\Projects\DocumentationCategories\StoreUpdateRequest;
use App\Services\Admin\Project\DocumentationCategoryService;
@@ -15,7 +16,9 @@ final class DocumentationCategoriesController extends Controller
{
public function __construct(
private readonly DocumentationCategoryService $documentationCategoryService,
) { }
) {
parent::__construct();
}
public function index(int $projectId, int $versionId, IndexRequest $request): View
{
@@ -32,18 +35,23 @@ final class DocumentationCategoriesController extends Controller
$this->errors($result);
}
return view('admin/projects/documentation-categories/index', $result->getData());
return view('admin/projects/documentation-versions/documentation-categories/index', $result->getData());
}
public function create(int $projectId, int $versionId, Request $request): View
public function create(int $projectId, int $versionId, CreateRequest $request): View
{
$parentId = null;
if ($request->has('category')) {
$parentId = (int) $request->input('category');
}
$user = $request->user();
$result = $this->documentationCategoryService->create($projectId, $versionId, $user);
$result = $this->documentationCategoryService->create($projectId, $versionId, $user, $parentId);
if ($result->isError()) {
$this->errors($result);
}
return view('admin/projects/documentation-categories/create', $result->getData());
return view('admin/projects/documentation-versions/documentation-categories/create', $result->getData());
}
public function edit(int $projectId, int $versionId, int $id, Request $request): View
@@ -54,7 +62,7 @@ final class DocumentationCategoriesController extends Controller
$this->errors($result);
}
return view('admin/projects/documentation-categories/edit', $result->getData());
return view('admin/projects/documentation-versions/documentation-categories/edit', $result->getData());
}
public function store(int $projectId, int $versionId, StoreUpdateRequest $request): RedirectResponse
@@ -15,7 +15,9 @@ final class DocumentationVersionController extends Controller
{
public function __construct(
private readonly DocumentationVersionService $documentationVersionService,
) { }
) {
parent::__construct();
}
public function index(int $projectId, IndexRequest $request): View
{
@@ -35,10 +37,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);
}
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Admin\Projects;
use App\Dto\QuerySettingsDto;
use App\Http\Controllers\Admin\Controller;
use App\Http\Requests\Admin\Projects\Documentations\CreateRequest;
use App\Http\Requests\Admin\Projects\Documentations\IndexRequest;
use App\Http\Requests\Admin\Projects\Documentations\StoreUpdateRequest;
use App\Services\Admin\Project\DocumentationService;
@@ -15,7 +16,9 @@ final class DocumentationsController extends Controller
{
public function __construct(
private readonly DocumentationService $documentationService,
) { }
) {
parent::__construct();
}
public function index(int $projectId, int $versionId, IndexRequest $request): View
{
@@ -32,18 +35,23 @@ final class DocumentationsController extends Controller
$this->errors($result);
}
return view('admin/projects/documentations/index', $result->getData());
return view('admin/projects/documentation-versions/documentations/index', $result->getData());
}
public function create(int $projectId, int $versionId, Request $request): View
public function create(int $projectId, int $versionId, CreateRequest $request): View
{
$categoryId = null;
if ($request->has('category')) {
$categoryId = (int) $request->input('category');
}
$user = $request->user();
$result = $this->documentationService->create($projectId, $versionId, $user);
$result = $this->documentationService->create($projectId, $versionId, $user, $categoryId);
if ($result->isError()) {
$this->errors($result);
}
return view('admin/projects/documentations/create', $result->getData());
return view('admin/projects/documentation-versions/documentations/create', $result->getData());
}
public function edit(int $projectId, int $versionId, int $id, Request $request): View
@@ -54,7 +62,7 @@ final class DocumentationsController extends Controller
$this->errors($result);
}
return view('admin/projects/documentations/edit', $result->getData());
return view('admin/projects/documentation-versions/documentations/edit', $result->getData());
}
public function store(int $projectId, int $versionId, StoreUpdateRequest $request): RedirectResponse
@@ -12,7 +12,9 @@ final class FeedbacksController extends Controller
{
public function __construct(
private readonly FeedbackService $feedbackService,
) { }
) {
parent::__construct();
}
public function index(IndexRequest $request): View
{
@@ -15,7 +15,9 @@ final class LinksController extends Controller
{
public function __construct(
private readonly LinkService $linkService
) { }
) {
parent::__construct();
}
public function index(int $projectId, IndexRequest $request): View
{
@@ -13,7 +13,9 @@ final class ServiceTranslateController extends Controller
{
public function __construct(
private readonly ServiceTranslateService $serviceTranslateService,
) { }
) {
parent::__construct();
}
public function view(int $projectId, Request $request): View
{
@@ -2,7 +2,7 @@
namespace App\Http\Controllers\Admin\Projects;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Admin\Controller;
use App\Http\Requests\Admin\Projects\Translations\UpdateRequest;
use App\Services\Admin\Project\TranslationService;
use Illuminate\Http\RedirectResponse;
@@ -13,7 +13,9 @@ final class TranslationsController extends Controller
{
public function __construct(
private readonly TranslationService $translationService,
) { }
) {
parent::__construct();
}
public function languages(int $projectId, Request $request): View
{
@@ -14,7 +14,9 @@ final class ProjectsController extends Controller
{
public function __construct(
private readonly ProjectService $projectService
) { }
) {
parent::__construct();
}
public function index(IndexRequest $request): View
{
@@ -14,7 +14,9 @@ final class RolesController extends Controller
{
public function __construct(
private readonly RoleService $roleService
) { }
) {
parent::__construct();
}
public function index(IndexRequest $request): View
{
$user = $request->user();
@@ -15,7 +15,9 @@ final class UsersController extends Controller
{
public function __construct(
private readonly UserService $userService
) { }
) {
parent::__construct();
}
public function index(IndexRequest $request): View
{
@@ -16,8 +16,8 @@ final class DocumentationController extends Controller
public function defaultVersion(Request $request): RedirectResponse | View
{
$project = $request->get('project');
$websiteTranslations = $request->get('websiteTranslations');
$project = $request->attributes->get('project');
$websiteTranslations = $request->attributes->get('websiteTranslations');
$result = $this->documentationService->defaultVersion($project, $request->user());
if ($result->isError()) {
@@ -40,9 +40,9 @@ final class DocumentationController extends Controller
public function index(Request $request): View
{
$documentation = new Documentation(
project: $request->get('project'),
version: $request->get('version'),
websiteTranslations: $request->get('websiteTranslations'),
project: $request->attributes->get('project'),
version: $request->attributes->get('version'),
websiteTranslations: $request->attributes->get('websiteTranslations'),
user: $request->user(),
);
$result = $this->documentationService->index($documentation);
@@ -57,9 +57,9 @@ final class DocumentationController extends Controller
public function category(string $slug, Request $request): View
{
$documentation = new Documentation(
project: $request->get('project'),
version: $request->get('version'),
websiteTranslations: $request->get('websiteTranslations'),
project: $request->attributes->get('project'),
version: $request->attributes->get('version'),
websiteTranslations: $request->attributes->get('websiteTranslations'),
user: $request->user(),
);
$result = $this->documentationService->category($slug, $documentation);
@@ -77,9 +77,9 @@ final class DocumentationController extends Controller
public function view(string $slug, Request $request): View
{
$documentation = new Documentation(
project: $request->get('project'),
version: $request->get('version'),
websiteTranslations: $request->get('websiteTranslations'),
project: $request->attributes->get('project'),
version: $request->attributes->get('version'),
websiteTranslations: $request->attributes->get('websiteTranslations'),
user: $request->user(),
);
$result = $this->documentationService->view($slug, $documentation);
@@ -17,16 +17,16 @@ final class FeedbackController extends Controller
public function index(Request $request): View
{
return view('site.feedback.index', [
'project' => $request->get('project'),
'websiteTranslations' => $request->get('websiteTranslations'),
'project' => $request->attributes->get('project'),
'websiteTranslations' => $request->attributes->get('websiteTranslations'),
'captcha' => config('app.captcha', false),
]);
}
public function send(SendRequest $request): RedirectResponse
{
$project = $request->get('project');
$websiteTranslations = $request->get('websiteTranslations');
$project = $request->attributes->get('project');
$websiteTranslations = $request->attributes->get('websiteTranslations');
$user = $request->user();
$data = $request->getDto();
@@ -15,7 +15,7 @@ final class ProjectsController extends Controller
public function index(Request $request): View
{
$user = $request->user();
$project = $request->get('project');
$project = $request->attributes->get('project');
if (\is_null($project)) {
$with = ['storage'];
@@ -27,7 +27,7 @@ final class ProjectsController extends Controller
return \view('site.projects.index', $result->getData());
}
$websiteTranslations = $request->get('websiteTranslations');
$websiteTranslations = $request->attributes->get('websiteTranslations');
$result = $this->projectService->getAboutByProject($project, $websiteTranslations, $user);
if ($result->isError()) {
$this->errors($result);
@@ -10,7 +10,7 @@ final readonly class DocumentationVersion
{
public function handle(Request $request, \Closure $next): Response
{
$project = $request->get('project');
$project = $request->attributes->get('project');
$versionSlug = $request->route()?->parameter('version');
if ($versionSlug === null || $project === null) {
\abort(Response::HTTP_NOT_FOUND);
@@ -10,7 +10,7 @@ final class IsProject
{
public function handle(Request $request, \Closure $next): Response
{
$project = $request->get('project');
$project = $request->attributes->get('project');
if (\is_null($project)) {
\abort(Response::HTTP_NOT_FOUND);
}
@@ -10,7 +10,7 @@ final class IsWebsiteTranslations
{
public function handle(Request $request, \Closure $next): Response
{
$websiteTranslations = $request->get('websiteTranslations');
$websiteTranslations = $request->attributes->get('websiteTranslations');
if (\is_null($websiteTranslations)) {
\abort(Response::HTTP_NOT_FOUND);
}
@@ -34,7 +34,7 @@ final class StoreUpdateRequest extends FormRequest implements FormRequestDto
{
return new StoreUpdate(
title: $this->input('title'),
description: $this->input('description'),
description: (string) $this->input('description', ''),
storages: $this->storages(),
isTranslateAutomatically: (bool) $this->input('translate-automatically', false),
);
@@ -0,0 +1,18 @@
<?php declare(strict_types=1);
namespace App\Http\Requests\Admin\Projects\DocumentationCategories;
use Illuminate\Foundation\Http\FormRequest;
final class CreateRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'category' => ['nullable', 'integer', 'min:1'],
];
}
}
@@ -0,0 +1,18 @@
<?php declare(strict_types=1);
namespace App\Http\Requests\Admin\Projects\Documentations;
use Illuminate\Foundation\Http\FormRequest;
final class CreateRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'category' => ['nullable', 'integer', 'min:1'],
];
}
}
@@ -11,6 +11,9 @@ use App\Services\Search\CreateSearchInstanceCommand;
use App\Dto\Builder\DocumentationCategory as DocumentationCategoryBuilderDto;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
final readonly class DocumentationCategoryRepository
@@ -93,4 +96,52 @@ final readonly class DocumentationCategoryRepository
->pluck('title', 'id')
->toArray();
}
public function getPathFromRoot(int $categoryId, ?ProjectLanguage $projectLanguage): Collection
{
$seconds = 3600;
return Cache::remember(self::class . $categoryId . '_' . $projectLanguage->id ?? 0, $seconds, function () use ($categoryId, $projectLanguage) {
$rows = DB::select(
<<<SQL
WITH RECURSIVE chain AS (
SELECT id, parent_id, 0 AS depth
FROM documentation_categories
WHERE id = ?
UNION ALL
SELECT dc.id, dc.parent_id, chain.depth + 1 AS depth
FROM documentation_categories dc
INNER JOIN chain ON chain.parent_id = dc.id
)
SELECT id, depth
FROM chain
ORDER BY depth DESC
SQL,
[$categoryId]
);
$idsInOrder = collect($rows)->pluck('id')->all();
$with = [
'content' => function (HasOne $hasOne) use ($projectLanguage) {
/** @var ?ProjectLanguage $projectLanguage */
$hasOne->when($projectLanguage, function (Builder $query, ProjectLanguage $projectLanguage) {
$query->where('language_id', $projectLanguage->id);
});
}
];
$categories = DocumentationCategory::query()
->whereIn('id', $idsInOrder)
->with($with)
->get()
->keyBy('id');
return collect($idsInOrder)
->map(fn (int $id) => $categories->get($id))
->filter()
->values();
});
}
}
@@ -20,6 +20,7 @@ use App\ServiceResults\ServiceResultArray;
use App\ServiceResults\ServiceResultError;
use App\ServiceResults\ServiceResultSuccess;
use App\ServiceResults\StoreUpdateResult;
use App\Services\ClearCacheCommandHandler;
use App\Services\DocumentationCategory\DocumentationCategoryCommandHandler;
use App\Services\DocumentationCategoryContent\ModelSyncCommand;
use App\Services\Service;
@@ -34,6 +35,7 @@ final class DocumentationCategoryService extends Service
private readonly DocumentationCategoryRepository $documentationCategoryRepository,
private readonly DocumentationCategoryCommandHandler $categoryCommandHandler,
private readonly ModelSyncCommand $contentSaveCommand,
private readonly ClearCacheCommandHandler $clearCacheCommandHandler,
) { }
public function index(int $projectId, int $versionId, DocumentationCategoryBuilderDto $documentationCategoryBuilderDto, QuerySettingsDto $querySettingsDto, User $user): ServiceResultError | ServiceResultArray
@@ -75,7 +77,7 @@ final class DocumentationCategoryService extends Service
]);
}
public function create(int $projectId, int $versionId, User $user): ServiceResultError | ServiceResultArray
public function create(int $projectId, int $versionId, User $user, ?int $parentId = null): ServiceResultError | ServiceResultArray
{
$version = $this->documentationVersionRepository->getVersionById($versionId);
$project = $version?->project;
@@ -88,12 +90,20 @@ final class DocumentationCategoryService extends Service
}
$defaultLanguage = $project->languages->where('is_default', 1)->first();
$category = new DocumentationCategory();
$categoryPath = null;
if ($parentId !== null) {
$category->parent_id = $parentId;
$categoryPath = $this->documentationCategoryRepository->getPathFromRoot($parentId, $defaultLanguage);
}
return $this->result([
'version' => $version,
'project' => $project,
'category' => new DocumentationCategory(),
'category' => $category,
'categories' => $this->documentationCategoryRepository->getForSelect($version, $defaultLanguage),
'serviceTranslationEnable' => config('translation_service.enable', false),
'categoryPath' => $categoryPath,
]);
}
@@ -114,17 +124,20 @@ final class DocumentationCategoryService extends Service
return $this->errFobidden(__('Access is denied'));
}
$defaultLanguage = $project->languages->where('is_default', 1)->first();
$withCategories = [];
$categoryPath = null;
if ($category->parent_id) {
$withCategories[] = $category->parent_id;
$categoryPath = $this->documentationCategoryRepository->getPathFromRoot($category->parent_id, $defaultLanguage);
}
$defaultLanguage = $project->languages->where('is_default', 1)->first();
return $this->result([
'version' => $version,
'project' => $project,
'category' => $category,
'categories' => $this->documentationCategoryRepository->getForSelect($version, $defaultLanguage, $category, $withCategories),
'serviceTranslationEnable' => config('translation_service.enable', false),
'categoryPath' => $categoryPath,
]);
}
@@ -160,6 +173,8 @@ final class DocumentationCategoryService extends Service
if (\config('translation_service.enable', false)) {
$this->translateContent($category, $data->getContents());
}
$this->clearCacheCommandHandler->all();
} catch (ServiceException $e) {
return $e->getServiceResultError();
} catch (\Throwable $e) {
@@ -214,6 +229,8 @@ final class DocumentationCategoryService extends Service
if (\config('translation_service.enable', false)) {
$this->translateContent($category, $data->getContents());
}
$this->clearCacheCommandHandler->all();
} catch (ServiceException $e) {
return $e->getServiceResultError();
} catch (ParentException $e) {
@@ -250,6 +267,8 @@ final class DocumentationCategoryService extends Service
DB::transaction(function () use ($category) {
$this->categoryCommandHandler->handleDestroy($category);
});
$this->clearCacheCommandHandler->all();
} catch (\Throwable $e) {
report($e);
return $this->errService(__('Server Error'));
@@ -75,7 +75,7 @@ final class DocumentationService extends Service
]);
}
public function create(int $projectId, int $versionId, User $user): ServiceResultError | ServiceResultArray
public function create(int $projectId, int $versionId, User $user, ?int $categoryId = null): ServiceResultError | ServiceResultArray
{
$version = $this->documentationVersionRepository->getVersionById($versionId);
$project = $version?->project;
@@ -88,12 +88,20 @@ final class DocumentationService extends Service
}
$defaultLanguage = $project->languages->where('is_default', 1)->first();
$documentation = new Documentation();
$categoryPath = null;
if ($categoryId !== null) {
$documentation->category_id = $categoryId;
$categoryPath = $this->documentationCategoryRepository->getPathFromRoot($categoryId, $defaultLanguage);
}
return $this->result([
'version' => $version,
'project' => $project,
'documentation' => new Documentation(),
'documentation' => $documentation,
'categories' => $this->documentationCategoryRepository->getForSelect($version, $defaultLanguage),
'serviceTranslationEnable' => config('translation_service.enable', false),
'categoryPath' => $categoryPath,
]);
}
@@ -114,17 +122,20 @@ final class DocumentationService extends Service
return $this->errFobidden(__('Access is denied'));
}
$defaultLanguage = $project->languages->where('is_default', 1)->first();
$withCategories = [];
$categoryPath = null;
if ($documentation->category_id) {
$withCategories[] = $documentation->category_id;
$categoryPath = $this->documentationCategoryRepository->getPathFromRoot($documentation->category_id, $defaultLanguage);
}
$defaultLanguage = $project->languages->where('is_default', 1)->first();
return $this->result([
'version' => $version,
'project' => $project,
'documentation' => $documentation,
'categories' => $this->documentationCategoryRepository->getForSelect($version, $defaultLanguage, null, $withCategories),
'serviceTranslationEnable' => config('translation_service.enable', false),
'categoryPath' => $categoryPath,
]);
}
@@ -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,52 @@ final class DocumentationVersionService extends Service
return $this->errFobidden(__('Access is denied'));
}
$defaultLanguage = $project->languages()->where('is_default', 1)->first();
$category = null;
$categoryPath = 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'));
}
$categoryPath = $this->documentationCategoryRepository->getPathFromRoot($category->id, $defaultLanguage);
}
$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,
'categoryPath' => $categoryPath,
'categories' => $categories,
'documentations' => $documents,
]);
}
@@ -77,10 +77,16 @@ final class DocumentationService extends Service
return $this->errFobidden(__('Access is denied'));
}
$categoryPath = null;
if ($category->parent_id) {
$categoryPath = $this->documentationCategoryRepository->getPathFromRoot($category->parent_id, $documentation->getWebsiteTranslations()->getLanguage());
}
$data = array_merge($documentation->toArray(), [
'category' => $category,
'categories' => $this->getCategories($documentation, $category->id),
'documentations' => $this->getDocumentations($documentation, $category->id),
'categoryPath' => $categoryPath,
]);
return $this->resultSitePage($documentation->getProject(), $documentation->getWebsiteTranslations(), $data, \is_null($category->content?->title));
}
@@ -98,8 +104,14 @@ final class DocumentationService extends Service
return $this->errFobidden(__('Access is denied'));
}
$categoryPath = null;
if ($document->category_id) {
$categoryPath = $this->documentationCategoryRepository->getPathFromRoot($document->category_id, $documentation->getWebsiteTranslations()->getLanguage());
}
$data = array_merge($documentation->toArray(), [
'documentation' => $document,
'categoryPath' => $categoryPath,
]);
return $this->resultSitePage($documentation->getProject(), $documentation->getWebsiteTranslations(), $data, \is_null($document->content?->title));
}
@@ -9,7 +9,7 @@ final readonly class ResizeCommandHandler
{
public function resize(Storage $storage, int $width, int $height): Storage
{
$image = InterventionImage::read($storage->path);
$image = InterventionImage::decodePath($storage->path);
if ($image->width() < $width && $image->height() < $height) {
return $storage;
}
@@ -23,7 +23,7 @@ final readonly class ResizeCommandHandler
public function width(Storage $storage, int $width): Storage
{
$image = InterventionImage::read($storage->path);
$image = InterventionImage::decodePath($storage->path);
if ($image->width() < $width) {
return $storage;
}
@@ -37,7 +37,7 @@ final readonly class ResizeCommandHandler
public function height(Storage $storage, int $height): Storage
{
$image = InterventionImage::read($storage->path);
$image = InterventionImage::decodePath($storage->path);
if ($image->height() < $height) {
return $storage;
}
+262
View File
@@ -0,0 +1,262 @@
<?php
use Diglactic\Breadcrumbs\Breadcrumbs;
Breadcrumbs::for('admin.home', function ($trail) {
$trail->push(__('Home'), route('admin.home'), ['icon' => '<svg class="icon icon-xxs" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"></path></svg>']);
});
// Roles
Breadcrumbs::for('admin.roles.index', function ($trail) {
$trail->parent('admin.home');
$trail->push(__('admin-sections.User group'), route('admin.roles.index'));
});
Breadcrumbs::for('admin.roles.create', function ($trail) {
$trail->parent('admin.roles.index');
$trail->push(__('Create'), route('admin.roles.create'));
});
Breadcrumbs::for('admin.roles.edit', function ($trail, \App\Models\Role $role) {
$trail->parent('admin.roles.index');
$trail->push(__('Edit'), route('admin.roles.edit', $role));
});
// End Roles
// Users
Breadcrumbs::for('admin.users.index', function ($trail) {
$trail->parent('admin.home');
$trail->push(__('admin-sections.Users'), route('admin.users.index'));
});
Breadcrumbs::for('admin.users.create', function ($trail) {
$trail->parent('admin.users.index');
$trail->push(__('Create'), route('admin.users.create'));
});
Breadcrumbs::for('admin.users.edit', function ($trail, \App\Models\User $user) {
$trail->parent('admin.users.index');
$trail->push(__('Edit'), route('admin.users.edit', $user));
});
// End Users
Breadcrumbs::for('admin.feedbacks.index', function ($trail) {
$trail->parent('admin.home');
$trail->push(__('admin-sections.Feedback'), route('admin.feedbacks.index'));
});
// Projects
Breadcrumbs::for('admin.projects.index', function ($trail) {
$trail->parent('admin.home');
$trail->push(__('admin-sections.Projects'), route('admin.projects.index'));
});
Breadcrumbs::for('admin.projects.create', function ($trail) {
$trail->parent('admin.projects.index');
$trail->push(__('Create'), route('admin.projects.create'));
});
Breadcrumbs::for('admin.projects.edit', function ($trail, \App\Models\Project $project) {
$trail->parent('admin.projects.index');
$trail->push(__('Edit'), route('admin.projects.edit', $project));
});
Breadcrumbs::for('admin.projects.show', function ($trail, \App\Models\Project $project) {
$trail->parent('admin.projects.index');
$trail->push($project->name, route('admin.projects.show', $project));
});
Breadcrumbs::for('admin.projects.feedbacks.index', function ($trail, \App\Models\Project $project) {
$trail->parent('admin.projects.show', $project);
$trail->push(__('admin-sections.Feedback'), route('admin.projects.feedbacks.index', $project));
});
// End Projects
// Projects translations
Breadcrumbs::for('admin.projects.translations.languages', function ($trail, \App\Models\Project $project) {
$trail->parent('admin.projects.show', $project);
$trail->push(__('admin-sections.Translations'), route('admin.projects.translations.languages', $project));
});
Breadcrumbs::for('admin.projects.translations.edit', function ($trail, \App\Models\Project $project, \App\Models\ProjectLanguage $language) {
$trail->parent('admin.projects.translations.languages', $project);
$trail->push($language->title, route('admin.projects.translations.edit', ['project' => $project->id, 'language' => $language->id]));
});
Breadcrumbs::for('admin.projects.service-translate.view', function ($trail, \App\Models\Project $project) {
$trail->parent('admin.projects.show', $project);
$trail->push(__('admin-sections.Setting up automatic translation'), route('admin.projects.service-translate.view', $project));
});
// End Projects translations
// Projects links
Breadcrumbs::for('admin.projects.links.index', function ($trail, \App\Models\Project $project) {
$trail->parent('admin.projects.show', $project);
$trail->push(__('admin-sections.Links project'), route('admin.projects.links.index', $project));
});
Breadcrumbs::for('admin.projects.links.create', function ($trail, \App\Models\Project $project) {
$trail->parent('admin.projects.links.index', $project);
$trail->push(__('Create'), route('admin.projects.links.create', $project));
});
Breadcrumbs::for('admin.projects.links.edit', function ($trail, \App\Models\Project $project, \App\Models\ProjectLink $link) {
$trail->parent('admin.projects.links.index', $project);
$trail->push(__('Edit'), route('admin.projects.links.edit', ['project' => $project->id, 'link' => $link->id]));
});
// End Projects links
// Projects about
Breadcrumbs::for('admin.projects.about.languages', function ($trail, \App\Models\Project $project) {
$trail->parent('admin.projects.show', $project);
$trail->push(__('admin-sections.About project'), route('admin.projects.about.languages', $project));
});
Breadcrumbs::for('admin.projects.about.edit', function ($trail, \App\Models\Project $project, \App\Models\ProjectLanguage $language) {
$trail->parent('admin.projects.about.languages', $project);
$trail->push($language->title, route('admin.projects.about.edit', ['project' => $project->id, 'language' => $language->id]));
});
// End Projects about
// Projects documentation-versions
Breadcrumbs::for('admin.projects.documentation-versions.index', function ($trail, \App\Models\Project $project) {
$trail->parent('admin.projects.show', $project);
$trail->push(__('admin-sections.Documentation version'), route('admin.projects.documentation-versions.index', $project));
});
Breadcrumbs::for('admin.projects.documentation-versions.create', function ($trail, \App\Models\Project $project) {
$trail->parent('admin.projects.documentation-versions.index', $project);
$trail->push(__('Create'), route('admin.projects.documentation-versions.create', $project));
});
Breadcrumbs::for('admin.projects.documentation-versions.edit', function ($trail, \App\Models\Project $project, \App\Models\DocumentationVersion $version) {
$trail->parent('admin.projects.documentation-versions.index', $project);
$trail->push(__('Edit'), route('admin.projects.documentation-versions.edit', ['project' => $project->id, 'documentation_version' => $version->id]));
});
Breadcrumbs::for('admin.projects.documentation-versions.show', function ($trail, \App\Models\Project $project, \App\Models\DocumentationVersion $version) {
$trail->parent('admin.projects.documentation-versions.index', $project);
$trail->push($version->title, route('admin.projects.documentation-versions.show', ['project' => $project->id, 'documentation_version' => $version->id]));
});
Breadcrumbs::for('admin.projects.documentation-versions.category-path', function ($trail, \App\Models\Project $project, \App\Models\DocumentationVersion $version, \Illuminate\Support\Collection $categoryPath) {
$trail->parent('admin.projects.documentation-versions.show', $project, $version);
foreach ($categoryPath as $pathItem) {
$trail->push(
$pathItem->content->title,
route('admin.projects.documentation-versions.category.show', [
'project' => $project->id,
'version' => $version->id,
'category' => $pathItem->id,
])
);
}
});
Breadcrumbs::for('admin.projects.documentation-versions.show.category', function ($trail, \App\Models\Project $project, \App\Models\DocumentationVersion $version, \App\Models\DocumentationCategory $category, ?\Illuminate\Support\Collection $categoryPath) {
$path = $categoryPath ?? collect([$category]);
$trail->parent('admin.projects.documentation-versions.category-path', $project, $version, $path);
});
// End Projects documentation-versions
// Projects documentation-versions documentations
Breadcrumbs::for('admin.projects.documentation-versions.documentations.index', function ($trail, \App\Models\Project $project, \App\Models\DocumentationVersion $version) {
$trail->parent('admin.projects.documentation-versions.show', $project, $version);
$trail->push(__('admin-sections.Documentation'), route('admin.projects.documentation-versions.documentations.index', ['project' => $project->id, 'version' => $version->id]));
});
Breadcrumbs::for('admin.projects.documentation-versions.documentations.create', function ($trail, \App\Models\Project $project, \App\Models\DocumentationVersion $version) {
$trail->parent('admin.projects.documentation-versions.documentations.index', $project, $version);
$trail->push(__('Create'), route('admin.projects.documentation-versions.documentations.create', ['project' => $project->id, 'version' => $version->id]));
});
Breadcrumbs::for('admin.projects.documentation-versions.category-path.documentations', function ($trail, \App\Models\Project $project, \App\Models\DocumentationVersion $version, \Illuminate\Support\Collection $categoryPath) {
$trail->parent('admin.projects.documentation-versions.category-path', $project, $version, $categoryPath);
$trail->push(__('admin-sections.Documentation'), route('admin.projects.documentation-versions.documentations.index', ['project' => $project->id, 'version' => $version->id]));
});
Breadcrumbs::for('admin.projects.documentation-versions.category-path.documentations.create', function ($trail, \App\Models\Project $project, \App\Models\DocumentationVersion $version, \Illuminate\Support\Collection $categoryPath) {
$trail->parent('admin.projects.documentation-versions.category-path.documentations', $project, $version, $categoryPath);
$trail->push(__('Create'), route('admin.projects.documentation-versions.documentations.create', ['project' => $project->id, 'version' => $version->id]));
});
Breadcrumbs::for('admin.projects.documentation-versions.documentations.edit', function ($trail, \App\Models\Project $project, \App\Models\DocumentationVersion $version, \App\Models\Documentation $documentation) {
$trail->parent('admin.projects.documentation-versions.documentations.index', $project, $version);
$trail->push(__('Edit'), route('admin.projects.documentation-versions.documentations.edit', ['project' => $project->id, 'version' => $version->id, 'documentation' => $documentation->id]));
});
Breadcrumbs::for('admin.projects.documentation-versions.category-path.documentations.edit', function ($trail, \App\Models\Project $project, \App\Models\DocumentationVersion $version, \App\Models\Documentation $documentation, \Illuminate\Support\Collection $categoryPath) {
$trail->parent('admin.projects.documentation-versions.category-path.documentations', $project, $version, $categoryPath);
$trail->push(__('Edit'), route('admin.projects.documentation-versions.documentations.edit', ['project' => $project->id, 'version' => $version->id, 'documentation' => $documentation->id]));
});
// End Projects documentation-versions documentations
// Projects documentation-versions categories
Breadcrumbs::for('admin.projects.documentation-versions.categories.index', function ($trail, \App\Models\Project $project, \App\Models\DocumentationVersion $version) {
$trail->parent('admin.projects.documentation-versions.show', $project, $version);
$trail->push(__('admin-sections.Categories'), route('admin.projects.documentation-versions.categories.index', ['project' => $project->id, 'version' => $version->id]));
});
Breadcrumbs::for('admin.projects.documentation-versions.categories.create', function ($trail, \App\Models\Project $project, \App\Models\DocumentationVersion $version) {
$trail->parent('admin.projects.documentation-versions.categories.index', $project, $version);
$trail->push(__('Create'), route('admin.projects.documentation-versions.categories.create', ['project' => $project->id, 'version' => $version->id]));
});
Breadcrumbs::for('admin.projects.documentation-versions.category-path.categories', function ($trail, \App\Models\Project $project, \App\Models\DocumentationVersion $version, \Illuminate\Support\Collection $categoryPath) {
$trail->parent('admin.projects.documentation-versions.category-path', $project, $version, $categoryPath);
$trail->push(__('admin-sections.Categories'), route('admin.projects.documentation-versions.categories.index', ['project' => $project->id, 'version' => $version->id]));
});
Breadcrumbs::for('admin.projects.documentation-versions.category-path.categories.create', function ($trail, \App\Models\Project $project, \App\Models\DocumentationVersion $version, \Illuminate\Support\Collection $categoryPath) {
$trail->parent('admin.projects.documentation-versions.category-path.categories', $project, $version, $categoryPath);
$trail->push(__('Create'), route('admin.projects.documentation-versions.categories.create', ['project' => $project->id, 'version' => $version->id]));
});
Breadcrumbs::for('admin.projects.documentation-versions.categories.edit', function ($trail, \App\Models\Project $project, \App\Models\DocumentationVersion $version, \App\Models\DocumentationCategory $category) {
$trail->parent('admin.projects.documentation-versions.categories.index', $project, $version);
$trail->push(__('Edit'), route('admin.projects.documentation-versions.categories.edit', ['project' => $project->id, 'version' => $version->id, 'category' => $category->id]));
});
Breadcrumbs::for('admin.projects.documentation-versions.category-path.categories.edit', function ($trail, \App\Models\Project $project, \App\Models\DocumentationVersion $version, \App\Models\DocumentationCategory $category, \Illuminate\Support\Collection $categoryPath) {
$trail->parent('admin.projects.documentation-versions.category-path.categories', $project, $version, $categoryPath);
$trail->push(__('Edit'), route('admin.projects.documentation-versions.categories.edit', ['project' => $project->id, 'version' => $version->id, 'category' => $category->id]));
});
// End Projects documentation-versions categories
+60
View File
@@ -0,0 +1,60 @@
<?php
use App\Models\DocumentationCategory;
use App\Models\DocumentationVersion;
use App\Models\Documentation;
use App\Services\WebsiteTranslations;
use App\Enums\Site\ProjectSection;
use App\Models\Project;
use Diglactic\Breadcrumbs\Breadcrumbs;
use Illuminate\Support\Collection;
Breadcrumbs::for('home', function ($trail, Project $project, WebsiteTranslations $websiteTranslations) {
$trail->push($websiteTranslations->translate('Home'), ProjectSection::Home->url($project, $websiteTranslations->getLanguage()));
});
Breadcrumbs::for('feedbacks.index', function ($trail, Project $project, WebsiteTranslations $websiteTranslations) {
$trail->parent('home', $project, $websiteTranslations);
$trail->push($websiteTranslations->translate('site.Feedback'), ProjectSection::Feedback->url($project, $websiteTranslations->getLanguage()));
});
// Documentation
Breadcrumbs::for('documentation.no-default-version', function ($trail, Project $project, WebsiteTranslations $websiteTranslations) {
$trail->parent('home', $project, $websiteTranslations);
$trail->push($websiteTranslations->translate('site.Documentation'), ProjectSection::Documentation->url($project, $websiteTranslations->getLanguage()));
});
Breadcrumbs::for('documentation.index', function ($trail, Project $project, WebsiteTranslations $websiteTranslations, DocumentationVersion $version) {
$trail->parent('home', $project, $websiteTranslations);
$trail->push($websiteTranslations->translate('site.Documentation'), ProjectSection::DocumentationVersion->url($project, $websiteTranslations->getLanguage(), ['version' => $version->slug]));
});
Breadcrumbs::for('documentation.category-path', function ($trail, Project $project, WebsiteTranslations $websiteTranslations, DocumentationVersion $version, Collection $categoryPath) {
$trail->parent('documentation.index', $project, $websiteTranslations, $version);
foreach ($categoryPath as $pathItem) {
$trail->push(
$pathItem->content->title,
ProjectSection::DocumentationCategory->url($project, $websiteTranslations->getLanguage(), ['version' => $version->slug, 'slug' => $pathItem->slug])
);
}
});
Breadcrumbs::for('documentation.category', function ($trail, Project $project, WebsiteTranslations $websiteTranslations, DocumentationVersion $version, DocumentationCategory $category, ?Collection $categoryPath) {
$trail->parent('documentation.category-path', $project, $websiteTranslations, $version, $categoryPath ?? collect());
$trail->push(
$category->content->title,
ProjectSection::DocumentationCategory->url($project, $websiteTranslations->getLanguage(), ['version' => $version->slug, 'slug' => $category->slug])
);
});
Breadcrumbs::for('documentation.view', function ($trail, Project $project, WebsiteTranslations $websiteTranslations, DocumentationVersion $version, Documentation $documentation, ?Collection $categoryPath) {
$trail->parent('documentation.category-path', $project, $websiteTranslations, $version, $categoryPath ?? collect());
$trail->push(
$documentation->content->title,
ProjectSection::Documentation->url($project, $websiteTranslations->getLanguage(), ['version' => $version->slug, 'slug' => $documentation->slug])
);
});
// End Documentation
+32 -12
View File
@@ -1,4 +1,5 @@
{
"$schema": "https://getcomposer.org/schema.json",
"name": "laravel/laravel",
"type": "project",
"description": "The skeleton application for the Laravel framework.",
@@ -6,23 +7,23 @@
"license": "MIT",
"require": {
"php": "^8.3",
"intervention/image-laravel": "^1.2",
"diglactic/laravel-breadcrumbs": "^10.1",
"intervention/image-laravel": "^4.0",
"kor-elf/captcha-rule-for-laravel": "^1.0",
"kor-elf/translate-laravel": "1.3.0",
"laravel/framework": "^11.0",
"laravel/tinker": "^2.9",
"staudenmeir/laravel-adjacency-list": "^1.0"
"kor-elf/translate-laravel": "^2.0",
"laravel/framework": "^13.8",
"laravel/tinker": "^3.0",
"staudenmeir/laravel-adjacency-list": "^1.26"
},
"require-dev": {
"barryvdh/laravel-debugbar": "^3.13",
"barryvdh/laravel-debugbar": "^4.3",
"fakerphp/faker": "^1.23",
"laravel-lang/common": "^6.2",
"laravel/pint": "^1.13",
"laravel/sail": "^1.26",
"laravel/pail": "^1.2.5",
"laravel/pao": "^1.0.6",
"laravel/pint": "^1.27",
"mockery/mockery": "^1.6",
"nunomaduro/collision": "^8.0",
"phpunit/phpunit": "^10.5",
"spatie/laravel-ignition": "^2.4"
"nunomaduro/collision": "^8.6",
"phpunit/phpunit": "^12.5.12"
},
"autoload": {
"psr-4": {
@@ -37,6 +38,22 @@
}
},
"scripts": {
"setup": [
"composer install",
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\"",
"@php artisan key:generate",
"@php artisan migrate --force",
"npm install --ignore-scripts",
"npm run build"
],
"dev": [
"Composer\\Config::disableProcessTimeout",
"npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"php artisan serve\" \"php artisan queue:listen --tries=1 --timeout=0\" \"php artisan pail --timeout=0\" \"npm run dev\" --names=server,queue,logs,vite --kill-others"
],
"test": [
"@php artisan config:clear --ansi @no_additional_args",
"@php artisan test"
],
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi"
@@ -51,6 +68,9 @@
"@php artisan key:generate --ansi",
"@php -r \"file_exists('database/database.sqlite') || touch('database/database.sqlite');\"",
"@php artisan migrate --graceful --ansi"
],
"pre-package-uninstall": [
"Illuminate\\Foundation\\ComposerScripts::prePackageUninstall"
]
},
"extra": {
+2377 -3948
View File
File diff suppressed because it is too large Load Diff
+78
View File
@@ -0,0 +1,78 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| View Name
|--------------------------------------------------------------------------
|
| Choose a view to display when Breadcrumbs::render() is called.
| Built in templates are:
|
| - 'breadcrumbs::bootstrap5' - Bootstrap 5
| - 'breadcrumbs::bootstrap4' - Bootstrap 4
| - 'breadcrumbs::bulma' - Bulma
| - 'breadcrumbs::foundation6' - Foundation 6
| - 'breadcrumbs::json-ld' - JSON-LD Structured Data
| - 'breadcrumbs::materialize' - Materialize
| - 'breadcrumbs::tailwind' - Tailwind CSS
| - 'breadcrumbs::uikit' - UIkit
|
| Or a custom view, e.g. '_partials/breadcrumbs'.
|
*/
'view' => 'breadcrumbs.site',
/*
|--------------------------------------------------------------------------
| Breadcrumbs File(s)
|--------------------------------------------------------------------------
|
| The file(s) where breadcrumbs are defined. e.g.
|
| - base_path('routes/breadcrumbs.php')
| - glob(base_path('breadcrumbs/*.php'))
|
*/
'files' => [
base_path('breadcrumbs/site.php'),
base_path('breadcrumbs/admin.php'),
],
/*
|--------------------------------------------------------------------------
| Exceptions
|--------------------------------------------------------------------------
|
| Determine when to throw an exception.
|
*/
// When route-bound breadcrumbs are used but the current route doesn't have a name (UnnamedRouteException)
'unnamed-route-exception' => true,
// When route-bound breadcrumbs are used and the matching breadcrumb doesn't exist (InvalidBreadcrumbException)
'missing-route-bound-breadcrumb-exception' => true,
// When a named breadcrumb is used but doesn't exist (InvalidBreadcrumbException)
'invalid-named-breadcrumb-exception' => true,
/*
|--------------------------------------------------------------------------
| Classes
|--------------------------------------------------------------------------
|
| Subclass the default classes for more advanced customisations.
|
*/
// Manager
'manager-class' => Diglactic\Breadcrumbs\Manager::class,
// Generator
'generator-class' => Diglactic\Breadcrumbs\Generator::class,
];
+3
View File
@@ -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",
@@ -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',
];
+6
View File
@@ -0,0 +1,6 @@
<?php declare(strict_types=1);
return [
'Do not translate' => 'Do not translate',
'Mark as not to translate' => 'Mark as not to translate',
];
+3
View File
@@ -38,6 +38,9 @@
"Connection Timed Out": "Соединение не отвечает",
"Continue": "Продолжай",
"Create": "Создать",
"Create documentation": "Создать документацию",
"Create category": "Создать категорию",
"Create version documentation": "Создать версию документации",
"Create :name": "Создать :name",
"Created": "Создано",
"Delete": "Удалить",
@@ -17,4 +17,6 @@ return [
'Documentation' => 'Документация',
'Categories' => 'Категории',
'Setting up automatic translation' => 'Настройка автоматического перевода',
'Documentation not found' => 'Документация не найдена',
'No categories found' => 'Категории не найдены',
];
+6
View File
@@ -0,0 +1,6 @@
<?php declare(strict_types=1);
return [
'Do not translate' => 'Не переводить',
'Mark as not to translate' => 'Пометить как не переводить',
];
@@ -1,6 +1,7 @@
@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,400;0,700;1,400;1,700&display=swap');
@import "reset";
@import "forms";
@import "breadcrumb";
html,
body {
@@ -0,0 +1,45 @@
.breadcrumb-container {
display: flex;
flex-wrap: wrap;
padding: .5rem 1rem;
margin-bottom: 1rem;
list-style: none;
background-color: #eee;
border-radius: .5rem;
}
.breadcrumb-item+.breadcrumb-item {
padding-left: .5rem
}
.breadcrumb-item+.breadcrumb-item:before {
float: left;
padding-right: .5rem;
color: #4b5563;
content: "/";
}
.breadcrumb-item.active {
color: #4b5563;
font-weight: 400;
}
.breadcrumb-item {
font-size: .75rem
}
.breadcrumb-item,.breadcrumb-item a {
color: #374151;
font-weight: 400;
font-size: .75rem;
}
.breadcrumb-item a:hover {
color: #00040b;
text-decoration: none;
}
@media (min-width: 576px) {
.breadcrumb-item,.breadcrumb-item a {
font-size:.875rem
}
}
@@ -69,3 +69,25 @@
</a>
</li>
@endcan
<li class="d-block d-sm-none">
<span role="separator" class="dropdown-divider my-1 mt-3 d-block"></span>
<ul class="nav flex-column pt-3 pt-md-0">
<li class="nav-item">
<a class="nav-link d-flex align-items-center" href="{{ route('profile.edit') }}">
<span class="sidebar-icon">
<svg class="icon icon-xs me-2" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-6-3a2 2 0 11-4 0 2 2 0 014 0zm-2 4a5 5 0 00-4.546 2.916A5.986 5.986 0 0010 16a5.986 5.986 0 004.546-2.084A5 5 0 0010 11z" clip-rule="evenodd"></path></svg>
</span>
<span class="sidebar-text">{{ __('My Profile') }}</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link d-flex align-items-center" href="{{ route('profile.settings') }}">
<span class="sidebar-icon">
<svg class="icon icon-xs me-2" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M11.49 3.17c-.38-1.56-2.6-1.56-2.98 0a1.532 1.532 0 01-2.286.948c-1.372-.836-2.942.734-2.106 2.106.54.886.061 2.042-.947 2.287-1.561.379-1.561 2.6 0 2.978a1.532 1.532 0 01.947 2.287c-.836 1.372.734 2.942 2.106 2.106a1.532 1.532 0 012.287.947c.379 1.561 2.6 1.561 2.978 0a1.533 1.533 0 012.287-.947c1.372.836 2.942-.734 2.106-2.106a1.533 1.533 0 01.947-2.287c1.561-.379 1.561-2.6 0-2.978a1.532 1.532 0 01-.947-2.287c.836-1.372-.734-2.942-2.106-2.106a1.532 1.532 0 01-2.287-.947zM10 13a3 3 0 100-6 3 3 0 000 6z" clip-rule="evenodd"></path></svg>
</span>
<span class="sidebar-text">{{ __('Settings') }}</span>
</a>
</li>
</ul>
</li>
@@ -1,5 +1,6 @@
@section('meta_title', __('admin-sections.Project') . ': ' . $project->name)
@section('h1', __('admin-sections.Project') . ': ' . $project->name)
@section('breadcrumbs', Breadcrumbs::render('admin.projects.about.edit', $project, $language))
<x-admin.layout>
<div class="row">
<div class="col-12 mb-4">
@@ -1,5 +1,6 @@
@section('meta_title', __('admin-sections.Project') . ': ' . $project->name)
@section('h1', __('admin-sections.Project') . ': ' . $project->name)
@section('breadcrumbs', Breadcrumbs::render('admin.projects.about.languages', $project))
@php
$contents = $project->contents;
@endphp
@@ -1,5 +1,6 @@
@section('meta_title', __('admin-sections.Projects'))
@section('h1', __('admin-sections.Projects'))
@section('breadcrumbs', Breadcrumbs::render('admin.projects.create'))
<x-admin.layout>
@include('admin.projects._top')
<div class="row">
@@ -1,20 +0,0 @@
@section('meta_title', __('admin-sections.Categories'))
@section('h1')
{{ __('admin-sections.Project') . ': ' . $project->name . ' (' . $version->title . ')' }}
@endsection
<x-admin.layout>
@include('admin.projects.documentation-categories._top')
<div class="row">
<div class="col-12 mb-4">
<div class="card border-0 shadow components-section">
<div class="card-body">
<h3 id="category" class="mb-4">{{ __('admin-sections.Categories') }}</h3>
<form method="post" action="{{ route('admin.projects.documentation-versions.categories.update', ['project' => $project->id, 'version' => $version->id, 'category' => $category->id]) }}">
@method('PUT')
@include('admin.projects.documentation-categories._from')
</form>
</div>
</div>
</div>
</div>
</x-admin.layout>
@@ -1,18 +1,34 @@
<div class="mb-4">
<div class="mb-2">
@can('create', \App\Models\DocumentationVersion::class)
<a href="{{ route('admin.projects.documentation-versions.create', ['project' => $project->id]) }}" class="btn btn-secondary d-inline-flex align-items-center me-2">
<a href="{{ route('admin.projects.documentation-versions.create', ['project' => $project->id]) }}" class="btn btn-secondary d-inline-flex align-items-center me-2 mb-3">
<svg class="icon icon-xs me-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path></svg>
{{ __('Create') }}
{{ __('Create version documentation') }}
</a>
@endcan
@can('viewAny', \App\Models\DocumentationVersion::class)
<a href="{{ route('admin.projects.documentation-versions.index', ['project' => $project->id]) }}" class="btn btn-secondary d-inline-flex align-items-center me-2">
<a href="{{ route('admin.projects.documentation-versions.index', ['project' => $project->id]) }}" class="btn btn-secondary d-inline-flex align-items-center me-2 mb-3">
<svg class="icon icon-xs me-2" data-slot="icon" fill="none" stroke-width="1.5" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M3.375 19.5h17.25m-17.25 0a1.125 1.125 0 0 1-1.125-1.125M3.375 19.5h7.5c.621 0 1.125-.504 1.125-1.125m-9.75 0V5.625m0 12.75v-1.5c0-.621.504-1.125 1.125-1.125m18.375 2.625V5.625m0 12.75c0 .621-.504 1.125-1.125 1.125m1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125m0 3.75h-7.5A1.125 1.125 0 0 1 12 18.375m9.75-12.75c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125m19.5 0v1.5c0 .621-.504 1.125-1.125 1.125M2.25 5.625v1.5c0 .621.504 1.125 1.125 1.125m0 0h17.25m-17.25 0h7.5c.621 0 1.125.504 1.125 1.125M3.375 8.25c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125m17.25-3.75h-7.5c-.621 0-1.125.504-1.125 1.125m8.625-1.125c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125M12 10.875v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 10.875c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125M13.125 12h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125M20.625 12c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5M12 14.625v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 14.625c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125m0 1.5v-1.5m0 0c0-.621.504-1.125 1.125-1.125m0 0h7.5"></path>
</svg>
{{ __('List') }}
{{ __('admin-sections.Documentation version') }}
</a>
@endcan
@if(!empty($version) && $version->id)
@can('viewAny', \App\Models\Documentation::class)
<a href="{{ route('admin.projects.documentation-versions.documentations.index', ['project' => $project->id, 'version' => $version->id]) }}" class="btn btn-secondary d-inline-flex align-items-center me-2 mb-3">
<svg class="icon icon-xs me-2" data-slot="icon" fill="none" stroke-width="1.5" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M3.375 19.5h17.25m-17.25 0a1.125 1.125 0 0 1-1.125-1.125M3.375 19.5h7.5c.621 0 1.125-.504 1.125-1.125m-9.75 0V5.625m0 12.75v-1.5c0-.621.504-1.125 1.125-1.125m18.375 2.625V5.625m0 12.75c0 .621-.504 1.125-1.125 1.125m1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125m0 3.75h-7.5A1.125 1.125 0 0 1 12 18.375m9.75-12.75c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125m19.5 0v1.5c0 .621-.504 1.125-1.125 1.125M2.25 5.625v1.5c0 .621.504 1.125 1.125 1.125m0 0h17.25m-17.25 0h7.5c.621 0 1.125.504 1.125 1.125M3.375 8.25c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125m17.25-3.75h-7.5c-.621 0-1.125.504-1.125 1.125m8.625-1.125c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125M12 10.875v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 10.875c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125M13.125 12h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125M20.625 12c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5M12 14.625v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 14.625c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125m0 1.5v-1.5m0 0c0-.621.504-1.125 1.125-1.125m0 0h7.5"></path>
</svg>
{{ __('admin-sections.Documentation') }}
</a>
@endcan
@can('viewAny', \App\Models\DocumentationCategory::class)
<a href="{{ route('admin.projects.documentation-versions.categories.index', ['project' => $project->id, 'version' => $version->id]) }}" class="btn btn-secondary d-inline-flex align-items-center me-2 mb-3">
<svg class="icon icon-xs me-2" data-slot="icon" fill="none" stroke-width="1.5" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M3.375 19.5h17.25m-17.25 0a1.125 1.125 0 0 1-1.125-1.125M3.375 19.5h7.5c.621 0 1.125-.504 1.125-1.125m-9.75 0V5.625m0 12.75v-1.5c0-.621.504-1.125 1.125-1.125m18.375 2.625V5.625m0 12.75c0 .621-.504 1.125-1.125 1.125m1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125m0 3.75h-7.5A1.125 1.125 0 0 1 12 18.375m9.75-12.75c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125m19.5 0v1.5c0 .621-.504 1.125-1.125 1.125M2.25 5.625v1.5c0 .621.504 1.125 1.125 1.125m0 0h17.25m-17.25 0h7.5c.621 0 1.125.504 1.125 1.125M3.375 8.25c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125m17.25-3.75h-7.5c-.621 0-1.125.504-1.125 1.125m8.625-1.125c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125M12 10.875v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 10.875c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125M13.125 12h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125M20.625 12c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5M12 14.625v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 14.625c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125m0 1.5v-1.5m0 0c0-.621.504-1.125 1.125-1.125m0 0h7.5"></path>
</svg>
{{ __('admin-sections.Categories') }}
</a>
@endcan
@endif
</div>
@@ -1,5 +1,6 @@
@section('meta_title', __('admin-sections.Documentation version'))
@section('h1', __('admin-sections.Project') . ': ' . $project->name)
@section('breadcrumbs', Breadcrumbs::render('admin.projects.documentation-versions.create', $project))
<x-admin.layout>
@include('admin.projects.documentation-versions._top')
<div class="row">
@@ -1,12 +1,12 @@
<div class="mb-4">
<div class="mb-2">
@can('create', \App\Models\DocumentationCategory::class)
<a href="{{ route('admin.projects.documentation-versions.categories.create', ['project' => $project->id, 'version' => $version->id]) }}" class="btn btn-secondary d-inline-flex align-items-center me-2">
<a href="{{ route('admin.projects.documentation-versions.categories.create', ['project' => $project->id, 'version' => $version->id]) }}" class="btn btn-secondary d-inline-flex align-items-center me-2 mb-3">
<svg class="icon icon-xs me-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path></svg>
{{ __('Create') }}
</a>
@endcan
@can('viewAny', \App\Models\DocumentationCategory::class)
<a href="{{ route('admin.projects.documentation-versions.categories.index', ['project' => $project->id, 'version' => $version->id]) }}" class="btn btn-secondary d-inline-flex align-items-center me-2">
<a href="{{ route('admin.projects.documentation-versions.categories.index', ['project' => $project->id, 'version' => $version->id]) }}" class="btn btn-secondary d-inline-flex align-items-center me-2 mb-3">
<svg class="icon icon-xs me-2" data-slot="icon" fill="none" stroke-width="1.5" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M3.375 19.5h17.25m-17.25 0a1.125 1.125 0 0 1-1.125-1.125M3.375 19.5h7.5c.621 0 1.125-.504 1.125-1.125m-9.75 0V5.625m0 12.75v-1.5c0-.621.504-1.125 1.125-1.125m18.375 2.625V5.625m0 12.75c0 .621-.504 1.125-1.125 1.125m1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125m0 3.75h-7.5A1.125 1.125 0 0 1 12 18.375m9.75-12.75c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125m19.5 0v1.5c0 .621-.504 1.125-1.125 1.125M2.25 5.625v1.5c0 .621.504 1.125 1.125 1.125m0 0h17.25m-17.25 0h7.5c.621 0 1.125.504 1.125 1.125M3.375 8.25c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125m17.25-3.75h-7.5c-.621 0-1.125.504-1.125 1.125m8.625-1.125c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125M12 10.875v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 10.875c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125M13.125 12h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125M20.625 12c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5M12 14.625v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 14.625c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125m0 1.5v-1.5m0 0c0-.621.504-1.125 1.125-1.125m0 0h7.5"></path>
</svg>
@@ -14,12 +14,20 @@
</a>
@endcan
@can('viewAny', \App\Models\Documentation::class)
<a href="{{ route('admin.projects.documentation-versions.documentations.index', ['project' => $project->id, 'version' => $version->id]) }}" class="btn btn-secondary d-inline-flex align-items-center me-2">
<a href="{{ route('admin.projects.documentation-versions.documentations.index', ['project' => $project->id, 'version' => $version->id]) }}" class="btn btn-secondary d-inline-flex align-items-center me-2 mb-3">
<svg class="icon icon-xs me-2" data-slot="icon" fill="none" stroke-width="1.5" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M3.375 19.5h17.25m-17.25 0a1.125 1.125 0 0 1-1.125-1.125M3.375 19.5h7.5c.621 0 1.125-.504 1.125-1.125m-9.75 0V5.625m0 12.75v-1.5c0-.621.504-1.125 1.125-1.125m18.375 2.625V5.625m0 12.75c0 .621-.504 1.125-1.125 1.125m1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125m0 3.75h-7.5A1.125 1.125 0 0 1 12 18.375m9.75-12.75c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125m19.5 0v1.5c0 .621-.504 1.125-1.125 1.125M2.25 5.625v1.5c0 .621.504 1.125 1.125 1.125m0 0h17.25m-17.25 0h7.5c.621 0 1.125.504 1.125 1.125M3.375 8.25c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125m17.25-3.75h-7.5c-.621 0-1.125.504-1.125 1.125m8.625-1.125c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125M12 10.875v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 10.875c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125M13.125 12h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125M20.625 12c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5M12 14.625v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 14.625c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125m0 1.5v-1.5m0 0c0-.621.504-1.125 1.125-1.125m0 0h7.5"></path>
</svg>
{{ __('admin-sections.Documentation') }}
</a>
@endcan
@can('viewAny', \App\Models\DocumentationVersion::class)
<a href="{{ route('admin.projects.documentation-versions.index', ['project' => $project->id]) }}" class="btn btn-secondary d-inline-flex align-items-center me-2 mb-3">
<svg class="icon icon-xs me-2" data-slot="icon" fill="none" stroke-width="1.5" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M3.375 19.5h17.25m-17.25 0a1.125 1.125 0 0 1-1.125-1.125M3.375 19.5h7.5c.621 0 1.125-.504 1.125-1.125m-9.75 0V5.625m0 12.75v-1.5c0-.621.504-1.125 1.125-1.125m18.375 2.625V5.625m0 12.75c0 .621-.504 1.125-1.125 1.125m1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125m0 3.75h-7.5A1.125 1.125 0 0 1 12 18.375m9.75-12.75c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125m19.5 0v1.5c0 .621-.504 1.125-1.125 1.125M2.25 5.625v1.5c0 .621.504 1.125 1.125 1.125m0 0h17.25m-17.25 0h7.5c.621 0 1.125.504 1.125 1.125M3.375 8.25c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125m17.25-3.75h-7.5c-.621 0-1.125.504-1.125 1.125m8.625-1.125c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125M12 10.875v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 10.875c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125M13.125 12h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125M20.625 12c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5M12 14.625v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 14.625c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125m0 1.5v-1.5m0 0c0-.621.504-1.125 1.125-1.125m0 0h7.5"></path>
</svg>
{{ __('admin-sections.Documentation version') }}
</a>
@endcan
</div>
@@ -2,15 +2,20 @@
@section('h1')
{{ __('admin-sections.Project') . ': ' . $project->name . ' (' . $version->title . ')' }}
@endsection
@if(!empty($categoryPath))
@section('breadcrumbs', Breadcrumbs::render('admin.projects.documentation-versions.category-path.categories.create', $project, $version, $categoryPath))
@else
@section('breadcrumbs', Breadcrumbs::render('admin.projects.documentation-versions.categories.create', $project, $version))
@endif
<x-admin.layout>
@include('admin.projects.documentation-categories._top')
@include('admin.projects.documentation-versions.documentation-categories._top')
<div class="row">
<div class="col-12 mb-4">
<div class="card border-0 shadow components-section">
<div class="card-body">
<h3 id="category" class="mb-4">{{ __('admin-sections.Categories') }}</h3>
<form method="post" action="{{ route('admin.projects.documentation-versions.categories.store', ['project' => $project->id, 'version' => $version->id]) }}">
@include('admin.projects.documentation-categories._from')
@include('admin.projects.documentation-versions.documentation-categories._from')
</form>
</div>
</div>
@@ -0,0 +1,26 @@
@section('meta_title', __('admin-sections.Categories'))
@section('h1')
{{ __('admin-sections.Project') . ': ' . $project->name . ' (' . $version->title . ')' }}
@endsection
@if(!empty($categoryPath))
@section('breadcrumbs', Breadcrumbs::render('admin.projects.documentation-versions.category-path.categories.edit', $project, $version, $category, $categoryPath))
@else
@section('breadcrumbs', Breadcrumbs::render('admin.projects.documentation-versions.categories.edit', $project, $version, $category))
@endif
<x-admin.layout>
@include('admin.projects.documentation-versions.documentation-categories._top')
<div class="row">
<div class="col-12 mb-4">
<div class="card border-0 shadow components-section">
<div class="card-body">
<h3 id="category" class="mb-4">{{ __('admin-sections.Categories') }}</h3>
<form method="post"
action="{{ route('admin.projects.documentation-versions.categories.update', ['project' => $project->id, 'version' => $version->id, 'category' => $category->id]) }}">
@method('PUT')
@include('admin.projects.documentation-versions.documentation-categories._from')
</form>
</div>
</div>
</div>
</div>
</x-admin.layout>
@@ -2,8 +2,9 @@
@section('h1')
{{ __('admin-sections.Project') . ': ' . $project->name . ' (' . $version->title . ')' }}
@endsection
@section('breadcrumbs', Breadcrumbs::render('admin.projects.documentation-versions.categories.index', $project, $version))
<x-admin.layout>
@include('admin.projects.documentation-categories._top')
@include('admin.projects.documentation-versions.documentation-categories._top')
<div class="card border-0 shadow mb-4">
<div class="card-body">
<h3 id="category" class="mb-4">{{ __('admin-sections.Categories') }}</h3>
@@ -1,12 +1,12 @@
<div class="mb-4">
<div class="mb-2">
@can('create', \App\Models\Documentation::class)
<a href="{{ route('admin.projects.documentation-versions.documentations.create', ['project' => $project->id, 'version' => $version->id]) }}" class="btn btn-secondary d-inline-flex align-items-center me-2">
<a href="{{ route('admin.projects.documentation-versions.documentations.create', ['project' => $project->id, 'version' => $version->id]) }}" class="btn btn-secondary d-inline-flex align-items-center me-2 mb-3">
<svg class="icon icon-xs me-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path></svg>
{{ __('Create') }}
</a>
@endcan
@can('viewAny', \App\Models\Documentation::class)
<a href="{{ route('admin.projects.documentation-versions.documentations.index', ['project' => $project->id, 'version' => $version->id]) }}" class="btn btn-secondary d-inline-flex align-items-center me-2">
<a href="{{ route('admin.projects.documentation-versions.documentations.index', ['project' => $project->id, 'version' => $version->id]) }}" class="btn btn-secondary d-inline-flex align-items-center me-2 mb-3">
<svg class="icon icon-xs me-2" data-slot="icon" fill="none" stroke-width="1.5" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M3.375 19.5h17.25m-17.25 0a1.125 1.125 0 0 1-1.125-1.125M3.375 19.5h7.5c.621 0 1.125-.504 1.125-1.125m-9.75 0V5.625m0 12.75v-1.5c0-.621.504-1.125 1.125-1.125m18.375 2.625V5.625m0 12.75c0 .621-.504 1.125-1.125 1.125m1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125m0 3.75h-7.5A1.125 1.125 0 0 1 12 18.375m9.75-12.75c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125m19.5 0v1.5c0 .621-.504 1.125-1.125 1.125M2.25 5.625v1.5c0 .621.504 1.125 1.125 1.125m0 0h17.25m-17.25 0h7.5c.621 0 1.125.504 1.125 1.125M3.375 8.25c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125m17.25-3.75h-7.5c-.621 0-1.125.504-1.125 1.125m8.625-1.125c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125M12 10.875v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 10.875c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125M13.125 12h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125M20.625 12c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5M12 14.625v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 14.625c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125m0 1.5v-1.5m0 0c0-.621.504-1.125 1.125-1.125m0 0h7.5"></path>
</svg>
@@ -14,12 +14,20 @@
</a>
@endcan
@can('viewAny', \App\Models\DocumentationCategory::class)
<a href="{{ route('admin.projects.documentation-versions.categories.index', ['project' => $project->id, 'version' => $version->id]) }}" class="btn btn-secondary d-inline-flex align-items-center me-2">
<a href="{{ route('admin.projects.documentation-versions.categories.index', ['project' => $project->id, 'version' => $version->id]) }}" class="btn btn-secondary d-inline-flex align-items-center me-2 mb-3">
<svg class="icon icon-xs me-2" data-slot="icon" fill="none" stroke-width="1.5" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M3.375 19.5h17.25m-17.25 0a1.125 1.125 0 0 1-1.125-1.125M3.375 19.5h7.5c.621 0 1.125-.504 1.125-1.125m-9.75 0V5.625m0 12.75v-1.5c0-.621.504-1.125 1.125-1.125m18.375 2.625V5.625m0 12.75c0 .621-.504 1.125-1.125 1.125m1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125m0 3.75h-7.5A1.125 1.125 0 0 1 12 18.375m9.75-12.75c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125m19.5 0v1.5c0 .621-.504 1.125-1.125 1.125M2.25 5.625v1.5c0 .621.504 1.125 1.125 1.125m0 0h17.25m-17.25 0h7.5c.621 0 1.125.504 1.125 1.125M3.375 8.25c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125m17.25-3.75h-7.5c-.621 0-1.125.504-1.125 1.125m8.625-1.125c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125M12 10.875v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 10.875c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125M13.125 12h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125M20.625 12c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5M12 14.625v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 14.625c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125m0 1.5v-1.5m0 0c0-.621.504-1.125 1.125-1.125m0 0h7.5"></path>
</svg>
{{ __('admin-sections.Categories') }}
</a>
@endcan
@can('viewAny', \App\Models\DocumentationVersion::class)
<a href="{{ route('admin.projects.documentation-versions.index', ['project' => $project->id]) }}" class="btn btn-secondary d-inline-flex align-items-center me-2 mb-3">
<svg class="icon icon-xs me-2" data-slot="icon" fill="none" stroke-width="1.5" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M3.375 19.5h17.25m-17.25 0a1.125 1.125 0 0 1-1.125-1.125M3.375 19.5h7.5c.621 0 1.125-.504 1.125-1.125m-9.75 0V5.625m0 12.75v-1.5c0-.621.504-1.125 1.125-1.125m18.375 2.625V5.625m0 12.75c0 .621-.504 1.125-1.125 1.125m1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125m0 3.75h-7.5A1.125 1.125 0 0 1 12 18.375m9.75-12.75c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125m19.5 0v1.5c0 .621-.504 1.125-1.125 1.125M2.25 5.625v1.5c0 .621.504 1.125 1.125 1.125m0 0h17.25m-17.25 0h7.5c.621 0 1.125.504 1.125 1.125M3.375 8.25c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125m17.25-3.75h-7.5c-.621 0-1.125.504-1.125 1.125m8.625-1.125c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125M12 10.875v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 10.875c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125M13.125 12h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125M20.625 12c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5M12 14.625v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 14.625c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125m0 1.5v-1.5m0 0c0-.621.504-1.125 1.125-1.125m0 0h7.5"></path>
</svg>
{{ __('admin-sections.Documentation version') }}
</a>
@endcan
</div>
@@ -2,15 +2,20 @@
@section('h1')
{{ __('admin-sections.Project') . ': ' . $project->name . ' (' . $version->title . ')' }}
@endsection
@if(!empty($categoryPath))
@section('breadcrumbs', Breadcrumbs::render('admin.projects.documentation-versions.category-path.documentations.create', $project, $version, $categoryPath))
@else
@section('breadcrumbs', Breadcrumbs::render('admin.projects.documentation-versions.documentations.create', $project, $version))
@endif
<x-admin.layout>
@include('admin.projects.documentations._top')
@include('admin.projects.documentation-versions.documentations._top')
<div class="row">
<div class="col-12 mb-4">
<div class="card border-0 shadow components-section">
<div class="card-body">
<h3 id="category" class="mb-4">{{ __('admin-sections.Documentation') }}</h3>
<form method="post" action="{{ route('admin.projects.documentation-versions.documentations.store', ['project' => $project->id, 'version' => $version->id]) }}">
@include('admin.projects.documentations._from')
@include('admin.projects.documentation-versions.documentations._from')
</form>
</div>
</div>
@@ -2,8 +2,13 @@
@section('h1')
{{ __('admin-sections.Project') . ': ' . $project->name . ' (' . $version->title . ')' }}
@endsection
@if(!empty($categoryPath))
@section('breadcrumbs', Breadcrumbs::render('admin.projects.documentation-versions.category-path.documentations.edit', $project, $version, $documentation, $categoryPath))
@else
@section('breadcrumbs', Breadcrumbs::render('admin.projects.documentation-versions.documentations.edit', $project, $version, $documentation))
@endif
<x-admin.layout>
@include('admin.projects.documentations._top')
@include('admin.projects.documentation-versions.documentations._top')
<div class="row">
<div class="col-12 mb-4">
<div class="card border-0 shadow components-section">
@@ -11,7 +16,7 @@
<h3 id="category" class="mb-4">{{ __('admin-sections.Documentation') }}</h3>
<form method="post" action="{{ route('admin.projects.documentation-versions.documentations.update', ['project' => $project->id, 'version' => $version->id, 'documentation' => $documentation->id]) }}">
@method('PUT')
@include('admin.projects.documentations._from')
@include('admin.projects.documentation-versions.documentations._from')
</form>
</div>
</div>
@@ -2,8 +2,9 @@
@section('h1')
{{ __('admin-sections.Project') . ': ' . $project->name . ' (' . $version->title . ')' }}
@endsection
@section('breadcrumbs', Breadcrumbs::render('admin.projects.documentation-versions.documentations.index', $project, $version))
<x-admin.layout>
@include('admin.projects.documentations._top')
@include('admin.projects.documentation-versions.documentations._top')
<div class="card border-0 shadow mb-4">
<div class="card-body">
<h3 id="category" class="mb-4">{{ __('admin-sections.Documentation') }}</h3>
@@ -1,5 +1,6 @@
@section('meta_title', __('admin-sections.Documentation version'))
@section('h1', __('admin-sections.Project') . ': ' . $project->name)
@section('breadcrumbs', Breadcrumbs::render('admin.projects.documentation-versions.edit', $project, $version))
<x-admin.layout>
@include('admin.projects.documentation-versions._top')
<div class="row">
@@ -1,5 +1,6 @@
@section('meta_title', __('admin-sections.Documentation version'))
@section('h1', __('admin-sections.Project') . ': ' . $project->name)
@section('breadcrumbs', Breadcrumbs::render('admin.projects.documentation-versions.index', $project))
<x-admin.layout>
@include('admin.projects.documentation-versions._top')
<div class="card border-0 shadow mb-4">
@@ -1,45 +1,160 @@
@section('meta_title', __('admin-sections.Documentation version'))
@section('h1', __('admin-sections.Project') . ': ' . $project->name)
@if(!empty($category))
@section('breadcrumbs', Breadcrumbs::render('admin.projects.documentation-versions.show.category', $project, $version, $category, $categoryPath ?? null))
@else
@section('breadcrumbs', Breadcrumbs::render('admin.projects.documentation-versions.show', $project, $version))
@endif
@php
$categoryId = null;
if (!empty($category) && $category->id) {
$categoryId = $category->id;
}
@endphp
<x-admin.layout>
@include('admin.projects.documentation-versions._top')
<div class="card border-0 shadow mb-4">
<div class="card-body">
<h3 id="category" class="mb-4">{{ __('admin-sections.Documentation version') }}: {{ $version->title }}</h3>
<h3 id="category" class="mb-4">
{{ __('admin-sections.Documentation version') }}: {{ $version->title }}
</h3>
@if(!empty($category))
<h3 class="mb-4">
{{ __('admin-sections.Categories') }}: {{ $category->content?->title }}
</h3>
@endif
@can('create', \App\Models\Documentation::class)
<a href="{{ route('admin.projects.documentation-versions.documentations.create', ['project' => $project->id, 'version' => $version->id, 'category' => $categoryId]) }}" class="btn btn-secondary d-inline-flex align-items-center me-2 mb-3">
<svg class="icon icon-xs me-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path></svg>
{{ __('Create documentation') }}
</a>
@endcan
@can('create', \App\Models\DocumentationCategory::class)
<a href="{{ route('admin.projects.documentation-versions.categories.create', ['project' => $project->id, 'version' => $version->id, 'category' => $categoryId]) }}" class="btn btn-secondary d-inline-flex align-items-center me-2 mb-3">
<svg class="icon icon-xs me-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path></svg>
{{ __('Create category') }}
</a>
@endcan
<div class="table-responsive">
<table class="table table-centered table-nowrap mb-0 rounded">
<thead class="thead-light">
<tr>
<th class="border-0">{{ __('admin-sections.Sections') }}</th>
<th class="border-0">{{ __('validation.attributes.type') }}</th>
<th class="border-0">{{ __('validation.attributes.title') }}</th>
<th class="border-0">{{ __('validation.attributes.slug') }}</th>
<th class="border-0">{{ __('validation.attributes.is_public') }}</th>
<th class="border-0 rounded-end" style="width: 150px"></th>
</tr>
</thead>
<tbody>
@can('viewAny', \App\Models\Documentation::class)
@forelse($categories as $category)
<tr>
<td>
<a href="{{ route('admin.projects.documentation-versions.documentations.index', ['project' => $project->id, 'version' => $version->id]) }}" class="fw-bold">
<svg width="16" height="16" class="align-text-top" data-slot="icon" fill="none" stroke-width="1.5" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 12.75V12A2.25 2.25 0 0 1 4.5 9.75h15A2.25 2.25 0 0 1 21.75 12v.75m-8.69-6.44-2.12-2.12a1.5 1.5 0 0 0-1.061-.44H4.5A2.25 2.25 0 0 0 2.25 6v12a2.25 2.25 0 0 0 2.25 2.25h15A2.25 2.25 0 0 0 21.75 18V9a2.25 2.25 0 0 0-2.25-2.25h-5.379a1.5 1.5 0 0 1-1.06-.44Z"></path>
</svg>
{{ __('admin-sections.Documentation') }}
</a>
</td>
</tr>
@endcan
@can('viewAny', \App\Models\DocumentationCategory::class)
<tr>
<td>
<a href="{{ route('admin.projects.documentation-versions.categories.index', ['project' => $project->id, 'version' => $version->id]) }}" class="fw-bold">
<svg width="16" height="16" class="align-text-top" data-slot="icon" fill="none" stroke-width="1.5" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 12.75V12A2.25 2.25 0 0 1 4.5 9.75h15A2.25 2.25 0 0 1 21.75 12v.75m-8.69-6.44-2.12-2.12a1.5 1.5 0 0 0-1.061-.44H4.5A2.25 2.25 0 0 0 2.25 6v12a2.25 2.25 0 0 0 2.25 2.25h15A2.25 2.25 0 0 0 21.75 18V9a2.25 2.25 0 0 0-2.25-2.25h-5.379a1.5 1.5 0 0 1-1.06-.44Z"></path>
</svg>
{{ __('admin-sections.Categories') }}
</td>
<td>
@can('view', $category)
<a href="{{ route('admin.projects.documentation-versions.category.show', ['project' => $project->id, 'version' => $version->id, 'category' => $category->id]) }}" class="text-decoration-none text-dark">
{{ $category->content?->title }}
</a>
@else
{{ $category->content?->title }}
@endcan
</td>
<td>
{{ $category->slug }}
</td>
<td>
@if($category->is_public)
{{ __('Yes') }}
@else
{{ __('No') }}
@endif
</td>
<td>
@can('update', $category)
<a href="{{ route('admin.projects.documentation-versions.categories.edit', ['project' => $project->id, 'version' => $version->id, 'category' => $category->id]) }}" class="btn btn-primary" data-bs-toggle="tooltip" data-bs-placement="top" title="{{ __('Edit') }}">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="align-text-top" viewBox="0 0 16 16">
<path d="M12.854.146a.5.5 0 0 0-.707 0L10.5 1.793 14.207 5.5l1.647-1.646a.5.5 0 0 0 0-.708l-3-3zm.646 6.061L9.793 2.5 3.293 9H3.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.207l6.5-6.5zm-7.468 7.468A.5.5 0 0 1 6 13.5V13h-.5a.5.5 0 0 1-.5-.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.5-.5V10h-.5a.499.499 0 0 1-.175-.032l-.179.178a.5.5 0 0 0-.11.168l-2 5a.5.5 0 0 0 .65.65l5-2a.5.5 0 0 0 .168-.11l.178-.178z"/>
</svg>
</a>
@endcan
@can('delete', $category)
<form method="post" class="d-inline-block" action="{{ route('admin.projects.documentation-versions.categories.destroy', ['project' => $project->id, 'version' => $version->id, 'category' => $category->id]) }}">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger click-confirm" data-bs-toggle="tooltip" data-bs-placement="top" title="{{ __('Delete') }}">
<svg data-slot="icon" fill="currentColor" width="20" height="20" class="align-text-center" stroke-width="1.5" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12"></path>
</svg>
</button>
</form>
@endcan
</td>
</tr>
@empty
<tr>
<td colspan="3">
<div class="text-center">
{{ __('admin-sections.No categories found') }}
</div>
</td>
</tr>
@endforelse
@forelse($documentations as $documentation)
<tr>
<td>
{{ __('admin-sections.Documentation') }}
</td>
<td>
{{ $documentation->content?->title }}
</td>
<td>
{{ $documentation->slug }}
</td>
<td>
@if($documentation->is_public)
{{ __('Yes') }}
@else
{{ __('No') }}
@endif
</td>
<td>
@can('update', $documentation)
<a href="{{ route('admin.projects.documentation-versions.documentations.edit', ['project' => $project->id, 'version' => $version->id, 'documentation' => $documentation->id]) }}" class="btn btn-primary" data-bs-toggle="tooltip" data-bs-placement="top" title="{{ __('Edit') }}">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="align-text-top" viewBox="0 0 16 16">
<path d="M12.854.146a.5.5 0 0 0-.707 0L10.5 1.793 14.207 5.5l1.647-1.646a.5.5 0 0 0 0-.708l-3-3zm.646 6.061L9.793 2.5 3.293 9H3.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.207l6.5-6.5zm-7.468 7.468A.5.5 0 0 1 6 13.5V13h-.5a.5.5 0 0 1-.5-.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.5-.5V10h-.5a.499.499 0 0 1-.175-.032l-.179.178a.5.5 0 0 0-.11.168l-2 5a.5.5 0 0 0 .65.65l5-2a.5.5 0 0 0 .168-.11l.178-.178z"/>
</svg>
</a>
@endcan
@can('delete', $documentation)
<form method="post" class="d-inline-block" action="{{ route('admin.projects.documentation-versions.documentations.destroy', ['project' => $project->id, 'version' => $version->id, 'documentation' => $documentation->id]) }}">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger click-confirm" data-bs-toggle="tooltip" data-bs-placement="top" title="{{ __('Delete') }}">
<svg data-slot="icon" fill="currentColor" width="20" height="20" class="align-text-center" stroke-width="1.5" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12"></path>
</svg>
</button>
</form>
@endcan
</td>
</tr>
@empty
<tr>
<td colspan="3">
<div class="text-center">
{{ __('admin-sections.Documentation not found') }}
</div>
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
</div>
@push('scripts')
@include('admin._scripts._click-confirm', ['alert' => __('Do you want to delete?')])
@endpush
</x-admin.layout>
@@ -1,11 +1,13 @@
@section('meta_title', __('admin-sections.Projects'))
@section('h1', __('admin-sections.Projects'))
@section('breadcrumbs', Breadcrumbs::render('admin.projects.edit', $project))
<x-admin.layout>
@include('admin.projects._top')
<div class="row">
<div class="col-12 mb-4">
<div class="card border-0 shadow components-section">
<div class="card-body">
<h3 id="category" class="mb-4">{{ __('admin-sections.Project') . ': ' . $project->name }}</h3>
<form method="post" action="{{ route('admin.projects.update', $project) }}">
@method('PUT')
@include('admin.projects._from')
@@ -1,5 +1,6 @@
@section('meta_title', __('admin-sections.Feedback'))
@section('h1', __('admin-sections.Feedback'))
@section('breadcrumbs', Breadcrumbs::render('admin.feedbacks.index'))
<x-admin.layout>
<div class="card border-0 shadow mb-4">
<div class="card-body">
@@ -1,5 +1,6 @@
@section('meta_title', __('admin-sections.Project') . ': ' . $project->name . ' - ' . __('admin-sections.Feedback'))
@section('h1', __('admin-sections.Project') . ': ' . $project->name)
@section('breadcrumbs', Breadcrumbs::render('admin.projects.feedbacks.index', $project))
<x-admin.layout>
<div class="card border-0 shadow mb-4">
<div class="card-body">
@@ -1,5 +1,6 @@
@section('meta_title', __('admin-sections.Projects'))
@section('h1', __('admin-sections.Projects'))
@section('breadcrumbs', Breadcrumbs::render('admin.projects.index'))
<x-admin.layout>
@include('admin.projects._top')
<div class="card border-0 shadow mb-4">
@@ -1,5 +1,6 @@
@section('meta_title', __('admin-sections.Links project'))
@section('h1', __('admin-sections.Project') . ': ' . $project->name)
@section('breadcrumbs', Breadcrumbs::render('admin.projects.links.create', $project))
<x-admin.layout>
@include('admin.projects.links._top')
<div class="row">
@@ -1,5 +1,6 @@
@section('meta_title', __('admin-sections.Links project'))
@section('h1', __('admin-sections.Project') . ': ' . $project->name)
@section('breadcrumbs', Breadcrumbs::render('admin.projects.links.edit', $project, $link))
<x-admin.layout>
@include('admin.projects.links._top')
<div class="row">
@@ -1,5 +1,6 @@
@section('meta_title', __('admin-sections.Links project'))
@section('h1', __('admin-sections.Project') . ': ' . $project->name)
@section('breadcrumbs', Breadcrumbs::render('admin.projects.links.index', $project))
<x-admin.layout>
@include('admin.projects.links._top')
<div class="card border-0 shadow mb-4">
@@ -1,10 +1,12 @@
@section('meta_title', __('admin-sections.Setting up automatic translation') . '. ' . __('admin-sections.Project') . ': ' . $project->name)
@section('h1', __('admin-sections.Setting up automatic translation') . '. ' . __('admin-sections.Project') . ': ' . $project->name)
@section('h1', __('admin-sections.Project') . ': ' . $project->name)
@section('breadcrumbs', Breadcrumbs::render('admin.projects.service-translate.view', $project))
<x-admin.layout>
<div class="row">
<div class="col-12 mb-4">
<div class="card border-0 shadow components-section">
<div class="card-body">
<h3 id="category" class="mb-4">{{ __('admin-sections.Setting up automatic translation') }}</h3>
<form method="post" action="{{ route('admin.projects.service-translate.update', ['project' => $project->id]) }}">
@csrf
<div class="table-responsive">
@@ -1,5 +1,6 @@
@section('meta_title', __('admin-sections.Project') . ': ' . $project->name)
@section('h1', __('admin-sections.Project') . ': ' . $project->name)
@section('breadcrumbs', Breadcrumbs::render('admin.projects.show', $project))
<x-admin.layout>
@include('admin.projects._top')
<div class="card border-0 shadow mb-4">
@@ -1,11 +1,12 @@
@section('meta_title', __('admin-sections.Translations'))
@section('h1', __('admin-sections.Project') . ': ' . $project->name)
@section('breadcrumbs', Breadcrumbs::render('admin.projects.translations.edit', $project, $language))
<x-admin.layout>
<div class="row">
<div class="col-12 mb-4">
<div class="card border-0 shadow components-section">
<div class="card-body">
<h3 id="category" class="mb-4">{{ __('admin-sections.Translations') }}</h3>
<h3 id="category" class="mb-4">{{ __('admin-sections.Translations') . ': ' . $language->title }}</h3>
<div class="table-responsive">
<form method="post" action="{{ route('admin.projects.translations.update', ['project' => $project->id, 'language' => $language->id]) }}">
@if($serviceTranslationEnable)
@@ -1,5 +1,6 @@
@section('meta_title', __('admin-sections.Translations'))
@section('h1', __('admin-sections.Project') . ': ' . $project->name)
@section('breadcrumbs', Breadcrumbs::render('admin.projects.translations.languages', $project))
<x-admin.layout>
<div class="row">
<div class="col-12 mb-4">
@@ -1,5 +1,6 @@
@section('meta_title', __('admin-sections.User group'))
@section('h1', __('admin-sections.User group'))
@section('breadcrumbs', Breadcrumbs::render('admin.roles.create'))
<x-admin.layout>
@include('admin.roles._top')
<div class="row">
@@ -1,5 +1,6 @@
@section('meta_title', __('admin-sections.User group'))
@section('h1', __('admin-sections.User group'))
@section('breadcrumbs', Breadcrumbs::render('admin.roles.edit', $role))
<x-admin.layout>
@include('admin.roles._top')
<div class="row">
@@ -1,5 +1,6 @@
@section('meta_title', __('admin-sections.User group'))
@section('h1', __('admin-sections.User group'))
@section('breadcrumbs', Breadcrumbs::render('admin.roles.index'))
<x-admin.layout>
@include('admin.roles._top')
<div class="card border-0 shadow mb-4">
@@ -1,5 +1,6 @@
@section('meta_title', __('admin-sections.Users'))
@section('h1', __('admin-sections.Users'))
@section('breadcrumbs', Breadcrumbs::render('admin.users.create'))
<x-admin.layout>
@include('admin.users._top')
<div class="row">
@@ -1,5 +1,6 @@
@section('meta_title', __('admin-sections.Users'))
@section('h1', __('admin-sections.Users'))
@section('breadcrumbs', Breadcrumbs::render('admin.users.edit', $user))
<x-admin.layout>
@include('admin.users._top')
<div class="row">
@@ -1,5 +1,6 @@
@section('meta_title', __('admin-sections.Users'))
@section('h1', __('admin-sections.Users'))
@section('breadcrumbs', Breadcrumbs::render('admin.users.index'))
<x-admin.layout>
@include('admin.users._top')
<div class="card border-0 shadow mb-4">
@@ -0,0 +1,25 @@
@unless ($breadcrumbs->isEmpty())
<nav aria-label="breadcrumb" class="d-none d-md-inline-block">
<ol class="breadcrumb breadcrumb-dark breadcrumb-transparent">
@foreach ($breadcrumbs as $breadcrumb)
@if ($breadcrumb->url && !$loop->last)
<li class="breadcrumb-item"><a href="{{ $breadcrumb->url }}" aria-label="{{ $breadcrumb->title }}">
@if(!empty($breadcrumb->icon))
{!! $breadcrumb->icon !!}
@else
{{ $breadcrumb->title }}
@endif
</a></li>
@else
<li class="breadcrumb-item active" aria-current="page">
@if(!empty($breadcrumb->icon))
{!! $breadcrumb->icon !!}
@else
{{ $breadcrumb->title }}
@endif
</li>
@endif
@endforeach
</ol>
</nav>
@endunless
@@ -0,0 +1,13 @@
@unless ($breadcrumbs->isEmpty())
<nav aria-label="breadcrumb" class="breadcrumb">
<ol class="breadcrumb-container">
@foreach ($breadcrumbs as $breadcrumb)
@if ($breadcrumb->url && !$loop->last)
<li class="breadcrumb-item"><a href="{{ $breadcrumb->url }}">{{ $breadcrumb->title }}</a></li>
@else
<li class="breadcrumb-item active" aria-current="page">{{ $breadcrumb->title }}</li>
@endif
@endforeach
</ol>
</nav>
@endunless
@@ -12,7 +12,7 @@
@endphp
<div class="mb-3">
<label for="{{ $tinyId }}">{{ $title }}</label>
<textarea class="form-control {{ $attributes->get('class') }} textarea-tinymce @error($requestName) is-invalid @enderror" name="{{ $name }}" id="{{ $tinyId }}" rows="3">{{ $value }}</textarea>
<textarea class="form-control {{ $attributes->get('class') }} textarea-tinymce @error($requestName) is-invalid @enderror" name="{{ $name }}" id="{{ $tinyId }}" style="height: 600px;">{{ $value }}</textarea>
@foreach($images as $image)
@continue( empty($image['file']) )
<input type="hidden" value="{{ $image['file'] }}" name="{{ $storageUpload->getInputName() }}[content_images][][file]';">
@@ -95,14 +95,96 @@
xhr.send(formData);
});
@endif
tinymce.PluginManager.add('translateNo', (editor) => {
const ATTR = 'translate';
const VALUE = 'no';
const isTranslateNo = (node) =>
node && node.nodeType === 1 && node.getAttribute(ATTR) === VALUE;
const toggleTranslateNo = () => {
const selectedNode = editor.selection.getNode();
if (isTranslateNo(selectedNode)) {
// Remove translate="no", expand span
if (selectedNode.tagName === 'SPAN') {
editor.dom.remove(selectedNode, true); // true = сохранить детей
} else {
editor.dom.setAttrib(selectedNode, ATTR, null);
}
return;
}
// If inside translate="no", remove the mark
const wrapper = editor.dom.getParent(selectedNode, `[${ATTR}="${VALUE}"]`);
if (wrapper) {
if (wrapper.tagName === 'SPAN') {
editor.dom.remove(wrapper, true);
} else {
editor.dom.setAttrib(wrapper, ATTR, null);
}
return;
}
// Otherwise, wrap the selection
editor.formatter.register('translateNo', {
inline: 'span',
attributes: { [ATTR]: VALUE },
remove: 'all'
});
editor.formatter.apply('translateNo');
};
editor.ui.registry.addToggleButton('translateNo', {
icon: 'translate',
tooltip: '{{ __('editor.Do not translate') }}',
onAction: toggleTranslateNo,
onSetup: (api) => {
const setActive = () => {
const node = editor.selection.getNode();
api.setActive(
isTranslateNo(node) ||
!!editor.dom.getParent(node, `[${ATTR}="${VALUE}"]`)
);
};
editor.on('NodeChange', setActive);
return () => editor.off('NodeChange', setActive);
}
});
editor.ui.registry.addMenuItem('translateNo', {
text: '{{ __('editor.Mark as not to translate') }}',
icon: 'translate',
onAction: toggleTranslateNo
});
});
tinymce.init({
content_style: `
span[translate="no"] {
background: rgba(255, 215, 0, 0.35);
outline: 1px dashed #e0a800;
position: relative;
}
span[translate="no"]:hover::before {
position: absolute;
content: "{{ __('editor.Do not translate') }}";
left: 0;
bottom: 100%;
background: #e0a800;
white-space: nowrap;
padding: 0.25rem;
border: 1px solid #ddd;
}
`,
selector: '#{{ $tinyId }}',
@if(in_array(app()->getLocale(), ['ru'], true))
language: '{{ app()->getLocale() }}',
@endif
license_key: '{{ $tinymceLicenseKey }}',
plugins: 'advlist code emoticons link lists table codesample media my-image',
toolbar: 'bold italic | bullist numlist | link image emoticons media codesample',
plugins: 'advlist code emoticons link lists table codesample media my-image translateNo',
toolbar: 'bold italic | bullist numlist | link image emoticons media codesample translateNo',
referrer_policy: 'origin',
@if($storageUpload !== null)
images_upload_handler: imageUpload,
@@ -69,11 +69,12 @@
<nav class="navbar navbar-top navbar-expand navbar-dashboard navbar-dark ps-0 pe-2 pb-2 pb-lg-3">
<div class="container-fluid px-0">
<div class="d-flex justify-content-between w-100" id="navbarSupportedContent">
<div class="d-flex align-items-center">
<div>
@yield('breadcrumbs', '')
<h1 class="h3">@yield('h1', '')</h1>
</div>
<!-- Navbar links -->
<ul class="navbar-nav align-items-center">
<ul class="navbar-nav d-none d-lg-flex">
<li class="nav-item dropdown ms-lg-3">
<a class="nav-link dropdown-toggle pt-1 px-0" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<div class="media d-flex align-items-center">
@@ -106,7 +107,6 @@
</div>
</div>
</nav>
@includeWhen($errors->any(), 'layout.private._errors', ['errors' => $errors->all()])
@includeWhen(Session::has('success'), 'layout.private._success', ['success' => Session::get('success')])
@@ -9,6 +9,8 @@
<meta name="description" content="@yield('meta_description', '')" />
@vite('resources/site/scss/app.scss')
@stack('head')
</head>
<body>
<div class="wrapper">
@@ -46,6 +48,7 @@
</nav>
<div class="section-container">
<div class="content">
@yield('breadcrumbs', '')
@if($attributes->has('documentationVersion'))
<x-site.documentation-version :websiteTranslations="$websiteTranslations" :version="$attributes->get('documentationVersion')" />
@endif
@@ -1,6 +1,9 @@
@section('meta_title', $websiteTranslations->translate('site.Feedback'))
@section('h1', $websiteTranslations->translate('site.Feedback'))
@section('breadcrumbs', Breadcrumbs::render('feedbacks.index', $project, $websiteTranslations))
@push('head')
{{ Breadcrumbs::view('breadcrumbs::json-ld', 'feedbacks.index', $project, $websiteTranslations) }}
@endpush
<x-site.layout :project="$project" :websiteTranslations="$websiteTranslations">
@if(Session::has('success') !== true)
<form method="post" action="{{ \App\Enums\Site\ProjectSection::FeedbackSend->url($project, $websiteTranslations->getLanguage()) }}">
@@ -1,6 +1,9 @@
@section('meta_title', $category->content?->title . ' - ' . $project->name . ' ' . $version->title)
@section('h1', $category->content?->title)
@section('breadcrumbs', Breadcrumbs::render('documentation.category', $project, $websiteTranslations, $version, $category, $categoryPath))
@push('head')
{{ Breadcrumbs::view('breadcrumbs::json-ld', 'documentation.category', $project, $websiteTranslations, $version, $category, $categoryPath) }}
@endpush
<x-site.layout :project="$project" :websiteTranslations="$websiteTranslations" :documentationVersion="$version">
@foreach($categories as $category)
@continue(! $category->content?->title)
@@ -1,6 +1,9 @@
@section('meta_title', $websiteTranslations->translate('site.Documentation') . ' - ' . $project->name . ' ' . $version->title)
@section('h1', $websiteTranslations->translate('site.Documentation'))
@section('breadcrumbs', Breadcrumbs::render('documentation.index', $project, $websiteTranslations, $version))
@push('head')
{{ Breadcrumbs::view('breadcrumbs::json-ld', 'documentation.index', $project, $websiteTranslations, $version) }}
@endpush
<x-site.layout :project="$project" :websiteTranslations="$websiteTranslations" :documentationVersion="$version">
@foreach($categories as $category)
@continue(! $category->content?->title)
@@ -1,6 +1,9 @@
@section('meta_title', $websiteTranslations->translate('site.Documentation not created'))
@section('h1', $websiteTranslations->translate('site.Documentation not created'))
@section('breadcrumbs', Breadcrumbs::render('documentation.no-default-version', $project, $websiteTranslations))
@push('head')
{{ Breadcrumbs::view('breadcrumbs::json-ld', 'documentation.no-default-version', $project, $websiteTranslations) }}
@endpush
<x-site.layout :project="$project" :websiteTranslations="$websiteTranslations">
</x-site.layout>
@@ -1,6 +1,9 @@
@section('meta_title', $documentation->content?->title . ' - ' . $project->name . ' ' . $version->title)
@section('h1', $documentation->content?->title)
@section('breadcrumbs', Breadcrumbs::render('documentation.view', $project, $websiteTranslations, $version, $documentation, $categoryPath))
@push('head')
{{ Breadcrumbs::view('breadcrumbs::json-ld', 'documentation.view', $project, $websiteTranslations, $version, $documentation, $categoryPath) }}
@endpush
<x-site.layout :project="$project" :websiteTranslations="$websiteTranslations" :documentationVersion="$version">
<div class="line-numbers">{!! $documentation->content->content !!}</div>
@push('scripts')
@@ -24,6 +24,10 @@
padding: 0;
}
.breadcrumb .icon {
margin-top: -2px;
}
@each $color, $value in $theme-colors {
.breadcrumb-#{$color} {
background: $value;
+1
View File
@@ -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]+']);
+54 -48
View File
@@ -1,23 +1,4 @@
FROM docker.io/php:8.3-zts-alpine3.18 AS unit_builder
ARG UNIT_VERSION=1.31.1
RUN apk --no-cache add pcre2-dev gcc git musl-dev make && \
mkdir -p /usr/lib/unit/modules && \
git clone https://github.com/nginx/unit.git && \
cd unit && \
git checkout $UNIT_VERSION && \
./configure --prefix=/var --statedir=/var/lib/unit --runstatedir=/var/run --control=unix:/run/unit/control.unit.sock --log=/var/log/unit.log --user=www-data --group=www-data --tmpdir=/tmp --modulesdir=/var/lib/unit/modules && \
./configure php && \
make && \
make install
FROM docker.io/php:8.3-zts-alpine3.18 AS build
COPY --from=unit_builder /var/sbin/unitd /usr/sbin/unitd
COPY --from=unit_builder /var/lib/unit/ /var/lib/unit/
COPY docker/unit-config.json /docker-entrypoint.d/config.json
FROM docker.io/php:8.5-fpm-alpine3.23 AS php
RUN apk --no-cache add pcre2 libbz2 libpng libwebp libjpeg-turbo icu-libs freetype oniguruma libzip jq \
&& apk add --no-cache --virtual .phpize-deps icu-dev libpng-dev bzip2-dev libwebp-dev libjpeg-turbo-dev freetype-dev oniguruma-dev libzip-dev pcre2-dev ${PHPIZE_DEPS} \
@@ -30,7 +11,7 @@ RUN apk --no-cache add pcre2 libbz2 libpng libwebp libjpeg-turbo icu-libs freety
mysqli pdo_mysql \
intl mbstring \
zip pcntl \
exif opcache bz2 \
exif bz2 \
calendar \
&& pear update-channels && pecl update-channels \
&& pecl install redis && docker-php-ext-enable redis \
@@ -44,68 +25,89 @@ RUN apk --no-cache add pcre2 libbz2 libpng libwebp libjpeg-turbo icu-libs freety
&& mkdir -p /tmp/php/upload \
&& mkdir -p /tmp/php/sys \
&& mkdir -p /tmp/php/session \
&& chown -R www-data:www-data /tmp/php \
&& ln -sf /dev/stdout /var/log/unit.log \
&& addgroup -S unit && adduser -S unit -G unit
&& chown -R www-data:www-data /tmp/php
FROM build AS app_build_for_production
COPY docker/php/conf/app-fpm.conf /usr/local/etc/php-fpm.d/app-fpm.conf
FROM docker.io/nginx:1.31-alpine AS nginx
COPY docker/web/conf/default.conf.template /etc/nginx/templates/default.conf.template
COPY docker/web/conf/fastcgi_params /etc/nginx/fastcgi_params
COPY docker/web/start.sh /usr/local/bin/start
RUN chmod 755 /usr/local/bin/start
FROM nginx AS web_build_for_production
WORKDIR /home/app
COPY application /home/app
RUN apk --no-cache add git nodejs npm \
&& npm install && npm run build \
&& rm -rf /home/app/node_modules
FROM php AS app_build_for_production
WORKDIR /home/app
COPY application /home/app
RUN apk --no-cache add git nodejs npm \
RUN apk --no-cache add git \
&& curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer \
&& composer install --optimize-autoloader --no-dev \
&& npm install && npm run build \
&& rm -rf /home/app/node_modules /home/app/.env
&& rm -f /home/app/.env
FROM build AS production
FROM php AS app_production
COPY --from=app_build_for_production /home/app /var/www/html
COPY docker/docker-entrypoint_prod.sh /home/unit/docker-entrypoint.sh
COPY docker/start.sh /usr/local/bin/start
COPY --from=web_build_for_production /home/app/public/build/ /var/www/html/public/build
COPY docker/php/start.sh /usr/local/bin/start
WORKDIR /var/www/html
RUN chmod 755 /home/unit/docker-entrypoint.sh \
RUN chown -R www-data:www-data /var/www/html \
&& chmod 755 /usr/local/bin/start
STOPSIGNAL SIGTERM
ENTRYPOINT ["/home/unit/docker-entrypoint.sh"]
USER www-data
EXPOSE 9000
CMD ["/usr/local/bin/start"]
FROM nginx AS web_production
FROM build AS develop
COPY --from=web_build_for_production /home/app/public /usr/share/nginx/html
RUN rm -f /usr/share/nginx/html/50x.html /usr/share/nginx/html/index.php /usr/share/nginx/html/.htaccess
WORKDIR /usr/share/nginx/html
EXPOSE 80
CMD ["/usr/local/bin/start"]
# develop
FROM php AS app_develop
WORKDIR /var/www/html
COPY docker/docker-entrypoint_dev.sh /home/unit/docker-entrypoint.sh
COPY docker/start.sh /usr/local/bin/start
COPY docker/php/start.sh /usr/local/bin/start
STOPSIGNAL SIGTERM
RUN chmod 755 /home/unit/docker-entrypoint.sh \
&& chmod 755 /usr/local/bin/start \
RUN chmod 755 /usr/local/bin/start \
&& apk --no-cache add git nodejs npm \
&& curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
ENTRYPOINT ["/home/unit/docker-entrypoint.sh"]
USER www-data
EXPOSE 9000
CMD ["/usr/local/bin/start"]
FROM build AS artisan
FROM php AS artisan
WORKDIR /var/www/html
STOPSIGNAL SIGTERM
ENTRYPOINT ["php", "/var/www/html/artisan"]
FROM build AS composer
FROM php AS composer
WORKDIR /var/www/html
STOPSIGNAL SIGTERM
RUN apk --no-cache add git \
@@ -113,11 +115,15 @@ RUN apk --no-cache add git \
RUN mkdir "/.composer" && chmod -R 0777 "/.composer"
ENTRYPOINT ["composer"]
FROM build AS npm
FROM php AS npm
RUN mkdir "/.npm" && chmod -R 0777 "/.npm"
WORKDIR /var/www/html
STOPSIGNAL SIGTERM
RUN apk --no-cache add nodejs npm
ENTRYPOINT ["npm"]
FROM nginx AS web_develop
WORKDIR /usr/share/nginx/html
EXPOSE 80
CMD ["/usr/local/bin/start"]
-112
View File
@@ -1,112 +0,0 @@
#!/bin/sh
set -euo pipefail
WAITLOOPS=5
SLEEPSEC=1
unitd="unitd"
role=${CONTAINER_ROLE:-app}
curl_put()
{
RET=$(/usr/bin/curl -s -w '%{http_code}' -X PUT --data-binary @$1 --unix-socket /var/run/control.unit.sock http://localhost/$2)
RET_BODY=$(echo $RET | /bin/sed '$ s/...$//')
RET_STATUS=$(echo $RET | /usr/bin/tail -c 4)
if [ "$RET_STATUS" -ne "200" ]; then
echo "$0: Error: HTTP response status code is '$RET_STATUS'"
echo "$RET_BODY"
return 1
else
echo "$0: OK: HTTP response status code is '$RET_STATUS'"
echo "$RET_BODY"
fi
return 0
}
if [ "$role" = "app" ]; then
echo "$0: Launching Unit daemon to perform initial configuration..."
/usr/sbin/$unitd --control unix:/var/run/control.unit.sock
for i in $(/usr/bin/seq $WAITLOOPS); do
if [ ! -S /var/run/control.unit.sock ]; then
echo "$0: Waiting for control socket to be created..."
/bin/sleep $SLEEPSEC
else
break
fi
done
# even when the control socket exists, it does not mean unit has finished initialisation
# this curl call will get a reply once unit is fully launched
/usr/bin/curl -s -X GET --unix-socket /var/run/control.unit.sock http://localhost/
if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
echo "$0: /docker-entrypoint.d/ is not empty, applying initial configuration..."
if [[ -n "${UNIT_SOURCE:-}" ]]; then
config="/docker-entrypoint.d/config.json"
tmp="$(mktemp)"
jq --arg src "${UNIT_SOURCE}" '
.listeners["*:9000"].forwarded.source =
( $src
| split(",")
| map( gsub("^\\s+|\\s+$"; "") ) # trim пробелы
| map( select(. != "") ) # убрать пустые
)
' "$config" > "$tmp"
mv "$tmp" "$config"
fi
echo "$0: Looking for certificate bundles in /docker-entrypoint.d/..."
for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.pem"); do
echo "$0: Uploading certificates bundle: $f"
curl_put $f "certificates/$(basename $f .pem)"
done
echo "$0: Looking for JavaScript modules in /docker-entrypoint.d/..."
for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.js"); do
echo "$0: Uploading JavaScript module: $f"
curl_put $f "js_modules/$(basename $f .js)"
done
echo "$0: Looking for configuration snippets in /docker-entrypoint.d/..."
for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.json"); do
echo "$0: Applying configuration $f";
curl_put $f "config"
done
echo "$0: Looking for shell scripts in /docker-entrypoint.d/..."
for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.sh"); do
echo "$0: Launching $f";
"$f"
done
# warn on filetypes we don't know what to do with
for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -not -name "*.sh" -not -name "*.json" -not -name "*.pem" -not -name "*.js"); do
echo "$0: Ignoring $f";
done
fi
echo "$0: Stopping Unit daemon after initial configuration..."
kill -TERM $(/bin/cat /var/run/unit.pid)
for i in $(/usr/bin/seq $WAITLOOPS); do
if [ -S /var/run/control.unit.sock ]; then
echo "$0: Waiting for control socket to be removed..."
/bin/sleep $SLEEPSEC
else
break
fi
done
if [ -S /var/run/control.unit.sock ]; then
kill -KILL $(/bin/cat /var/run/unit.pid)
rm -f /var/run/control.unit.sock
fi
echo
echo "$0: Unit initial configuration complete; ready for start up..."
echo
fi
chmod -R 777 /var/www/html/storage /var/www/html/bootstrap/cache
exec "$@"
-122
View File
@@ -1,122 +0,0 @@
#!/bin/sh
set -euo pipefail
WAITLOOPS=5
SLEEPSEC=1
unitd="unitd"
role=${CONTAINER_ROLE:-app}
curl_put()
{
RET=$(/usr/bin/curl -s -w '%{http_code}' -X PUT --data-binary @$1 --unix-socket /var/run/control.unit.sock http://localhost/$2)
RET_BODY=$(echo $RET | /bin/sed '$ s/...$//')
RET_STATUS=$(echo $RET | /usr/bin/tail -c 4)
if [ "$RET_STATUS" -ne "200" ]; then
echo "$0: Error: HTTP response status code is '$RET_STATUS'"
echo "$RET_BODY"
return 1
else
echo "$0: OK: HTTP response status code is '$RET_STATUS'"
echo "$RET_BODY"
fi
return 0
}
if [ "$role" = "app" ]; then
echo "$0: Launching Unit daemon to perform initial configuration..."
/usr/sbin/$unitd --control unix:/var/run/control.unit.sock
for i in $(/usr/bin/seq $WAITLOOPS); do
if [ ! -S /var/run/control.unit.sock ]; then
echo "$0: Waiting for control socket to be created..."
/bin/sleep $SLEEPSEC
else
break
fi
done
# even when the control socket exists, it does not mean unit has finished initialisation
# this curl call will get a reply once unit is fully launched
/usr/bin/curl -s -X GET --unix-socket /var/run/control.unit.sock http://localhost/
if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
echo "$0: /docker-entrypoint.d/ is not empty, applying initial configuration..."
if [[ -n "${UNIT_SOURCE:-}" ]]; then
config="/docker-entrypoint.d/config.json"
tmp="$(mktemp)"
jq --arg src "${UNIT_SOURCE}" '
.listeners["*:9000"].forwarded.source =
( $src
| split(",")
| map( gsub("^\\s+|\\s+$"; "") ) # trim пробелы
| map( select(. != "") ) # убрать пустые
)
' "$config" > "$tmp"
mv "$tmp" "$config"
fi
echo "$0: Looking for certificate bundles in /docker-entrypoint.d/..."
for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.pem"); do
echo "$0: Uploading certificates bundle: $f"
curl_put $f "certificates/$(basename $f .pem)"
done
echo "$0: Looking for JavaScript modules in /docker-entrypoint.d/..."
for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.js"); do
echo "$0: Uploading JavaScript module: $f"
curl_put $f "js_modules/$(basename $f .js)"
done
echo "$0: Looking for configuration snippets in /docker-entrypoint.d/..."
for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.json"); do
echo "$0: Applying configuration $f";
curl_put $f "config"
done
echo "$0: Looking for shell scripts in /docker-entrypoint.d/..."
for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.sh"); do
echo "$0: Launching $f";
"$f"
done
# warn on filetypes we don't know what to do with
for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -not -name "*.sh" -not -name "*.json" -not -name "*.pem" -not -name "*.js"); do
echo "$0: Ignoring $f";
done
fi
echo "$0: Stopping Unit daemon after initial configuration..."
kill -TERM $(/bin/cat /var/run/unit.pid)
for i in $(/usr/bin/seq $WAITLOOPS); do
if [ -S /var/run/control.unit.sock ]; then
echo "$0: Waiting for control socket to be removed..."
/bin/sleep $SLEEPSEC
else
break
fi
done
if [ -S /var/run/control.unit.sock ]; then
kill -KILL $(/bin/cat /var/run/unit.pid)
rm -f /var/run/control.unit.sock
fi
echo
echo "$0: Unit initial configuration complete; ready for start up..."
echo
fi
php artisan config:cache
php artisan event:cache
php artisan route:cache
php artisan view:cache
php artisan storage:link
if [ "$role" = "app" ]; then
php artisan migrate --force
fi
chown -R unit:unit /var/www/html
chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache
chmod -R 777 /var/www/html/storage /var/www/html/bootstrap/cache
exec "$@"
+26
View File
@@ -0,0 +1,26 @@
[www]
php_admin_value[upload_tmp_dir] = "/tmp/php/upload"
php_admin_value[sys_temp_dir] = "/tmp/php/sys"
php_admin_value[session.save_path] = "/tmp/php/session"
php_admin_value[open_basedir] = "/var/www/html:/tmp/php:."
php_admin_value[expose_php] = 0
php_admin_value[memory_limit] = ${PHP_FPM_MEMORY_LIMIT}
php_admin_value[upload_max_filesize] = ${PHP_FPM_UPLOAD_MAX_FILESIZE}
php_admin_value[post_max_size] = ${PHP_FPM_POST_MAX_SIZE}
php_admin_value[display_errors] = ${PHP_FPM_DISPLAY_ERRORS}
php_admin_value[opcache.enable] = ${PHP_FPM_OPCACHE_ENABLE}
php_admin_value[opcache.validate_timestamps] = ${PHP_FPM_OPCACHE_VALIDATE_TIMESTAMPS}
pm = dynamic
pm.max_children = ${PHP_FPM_PM_MAX_CHILDREN}
pm.start_servers = ${PHP_FPM_PM_START_SERVERS}
pm.min_spare_servers = ${PHP_FPM_PM_MIN_SPARE_SERVERS}
pm.max_spare_servers = ${PHP_FPM_PM_MAX_SPARE_SERVERS}
pm.max_requests = ${PHP_FPM_PM_MAX_REQUESTS}
listen = 127.0.0.1:9000
listen.mode = 0660
listen.owner = www-data
listen.group = www-data
security.limit_extensions = .php
+59
View File
@@ -0,0 +1,59 @@
#!/usr/bin/env sh
set -e
role=${CONTAINER_ROLE:-app}
if [ "$APP_ENV" = "production" ]; then
php artisan config:cache
php artisan event:cache
php artisan route:cache
php artisan view:cache
php artisan storage:link
fi
if [ "$role" = "app" ]; then
export PHP_FPM_MEMORY_LIMIT="${PHP_FPM_MEMORY_LIMIT:-256m}"
export PHP_FPM_UPLOAD_MAX_FILESIZE="${PHP_FPM_UPLOAD_MAX_FILESIZE:-20m}"
export PHP_FPM_POST_MAX_SIZE="${PHP_FPM_POST_MAX_SIZE:-20m}"
export PHP_FPM_PM_MAX_CHILDREN="${PHP_FPM_PM_MAX_CHILDREN:-10}"
export PHP_FPM_PM_START_SERVERS="${PHP_FPM_PM_START_SERVERS:-5}"
export PHP_FPM_PM_MIN_SPARE_SERVERS="${PHP_FPM_PM_MIN_SPARE_SERVERS:-2}"
export PHP_FPM_PM_MAX_SPARE_SERVERS="${PHP_FPM_PM_MAX_SPARE_SERVERS:-5}"
export PHP_FPM_PM_MAX_REQUESTS="${PHP_FPM_PM_MAX_REQUESTS:-500}"
if [ "$APP_ENV" = "production" ]; then
export PHP_FPM_DISPLAY_ERRORS="${PHP_FPM_DISPLAY_ERRORS:-0}"
export PHP_FPM_OPCACHE_ENABLE="${PHP_FPM_OPCACHE_ENABLE:-1}"
export PHP_FPM_OPCACHE_VALIDATE_TIMESTAMPS="${PHP_FPM_OPCACHE_VALIDATE_TIMESTAMPS:-0}"
php artisan migrate --force
else
export PHP_FPM_DISPLAY_ERRORS="${PHP_FPM_DISPLAY_ERRORS:-1}"
export PHP_FPM_OPCACHE_ENABLE="${PHP_FPM_OPCACHE_ENABLE:-0}"
export PHP_FPM_OPCACHE_VALIDATE_TIMESTAMPS="${PHP_FPM_OPCACHE_VALIDATE_TIMESTAMPS:-1}"
fi
if [ ! -w /var/www/html/storage ]; then
echo "ERROR: /var/www/html/storage must be writable."
echo "Fix permissions on host/volume for the www-data user."
exit 1
fi
exec php-fpm
elif [ "$role" = "queue" ]; then
echo "Running the queue..."
while [ true ]
do
php /var/www/html/artisan queue:work --verbose --sleep=5 --tries=100 --backoff=10 --max-time=3600 --queue=high,normal,low,default
done
elif [ "$role" = "scheduler" ]; then
while [ true ]
do
php /var/www/html/artisan schedule:run --verbose --no-interaction &
sleep 60
done
else
echo "Could not match the container role \"$role\""
exit 1
fi
-21
View File
@@ -1,21 +0,0 @@
#!/usr/bin/env sh
set -e
role=${CONTAINER_ROLE:-app}
if [ "$role" = "app" ]; then
exec unitd --no-daemon --control unix:/var/run/control.unit.sock --user unit --group unit
elif [ "$role" = "queue" ]; then
echo "Running the queue..."
while [ true ]
do
php /var/www/html/artisan queue:work --verbose --sleep=5 --tries=100 --backoff=10 --max-time=3600 --queue=high,normal,low,default
done
elif [ "$role" = "scheduler" ]; then
while [ true ]
do
php /var/www/html/artisan schedule:run --verbose --no-interaction &
sleep 60
done
else
echo "Could not match the container role \"$role\""
exit 1
fi
-69
View File
@@ -1,69 +0,0 @@
{
"listeners": {
"*:9000": {
"pass": "routes",
"forwarded": {
"client_ip": "X-Forwarded-For",
"recursive": false,
"source": [
]
}
}
},
"routes": [
{
"match": {
"uri": [
"/index.php/",
"~^/index\\.php/.*",
"~\\.php$"
]
},
"action": {
"return": 404
}
},
{
"action": {
"share": "/var/www/html/public$uri",
"fallback": {
"pass": "applications/laravel"
}
}
}
],
"applications": {
"laravel": {
"type": "php",
"root": "/var/www/html/public",
"working_directory": "/var/www/html",
"user": "www-data",
"group": "www-data",
"script": "index.php",
"processes": {
"max": 10,
"spare": 5,
"idle_timeout": 20
},
"options": {
"file": "/usr/local/etc/php/php.ini",
"admin": {
"upload_tmp_dir": "/tmp/php/upload",
"sys_temp_dir": "/tmp/php/sys",
"session.save_path": "/tmp/php/session",
"open_basedir": "/var/www/html:/tmp/php:.",
"memory_limit": "256M",
"upload_max_filesize": "20M",
"post_max_size": "20M",
"expose_php": "0"
},
"user": {
"display_errors": "0"
}
}
}
}
}
+3
View File
@@ -0,0 +1,3 @@
application/public/*.php
application/public/**/*.php
application/public/.htaccess

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