From 63aa7894d131c37c6bc9082e7b9fce0e5856ffd0 Mon Sep 17 00:00:00 2001 From: Tajim Date: Mon, 24 Aug 2026 22:12:43 +0600 Subject: [PATCH 1/3] feat: add optional slug input for node create and edit --- app/Http/Controllers/Admin/NodeController.php | 16 ++++++--- app/Http/Requests/Node/StoreNodeRequest.php | 1 + app/Http/Requests/Node/UpdateNodeRequest.php | 2 +- resources/js/pages/admin/NodeCreateOrEdit.vue | 34 +++++++++++++++++++ 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/Admin/NodeController.php b/app/Http/Controllers/Admin/NodeController.php index a2391e6..85e59c6 100644 --- a/app/Http/Controllers/Admin/NodeController.php +++ b/app/Http/Controllers/Admin/NodeController.php @@ -94,7 +94,9 @@ public function store(StoreNodeRequest $request, Subject $subject) ->firstOrFail(); } - $slug = Str::slug($validated['name']); + $slug = !empty($validated['slug']) + ? Str::slug($validated['slug']) + : Str::slug($validated['name']); $exists = Node::where('subject_id', $subject->id) ->where('parent_id', $parent?->id) @@ -104,7 +106,7 @@ public function store(StoreNodeRequest $request, Subject $subject) if ($exists) { return back() ->withErrors([ - 'name' => 'Folder already exists in this location.', + 'slug' => 'Folder with this slug already exists in this location.', ]) ->withInput(); } @@ -143,8 +145,14 @@ public function update(UpdateNodeRequest $request, Subject $subject, Node $node) if (array_key_exists('name', $validated)) { $node->name = $validated['name']; + } + + if (array_key_exists('name', $validated) || array_key_exists('slug', $validated) || array_key_exists('parent_id', $validated)) { + $rawSlug = !empty($validated['slug']) + ? $validated['slug'] + : ($validated['name'] ?? $node->name); - $slug = Str::slug($validated['name']); + $slug = Str::slug($rawSlug); $parentId = array_key_exists('parent_id', $validated) ? $validated['parent_id'] @@ -158,7 +166,7 @@ public function update(UpdateNodeRequest $request, Subject $subject, Node $node) if ($exists) { return back()->withErrors([ - 'name' => 'Folder already exists in this location.', + 'slug' => 'Folder with this slug already exists in this location.', ])->withInput(); } diff --git a/app/Http/Requests/Node/StoreNodeRequest.php b/app/Http/Requests/Node/StoreNodeRequest.php index 3e2e85e..e0c50b1 100644 --- a/app/Http/Requests/Node/StoreNodeRequest.php +++ b/app/Http/Requests/Node/StoreNodeRequest.php @@ -24,6 +24,7 @@ public function rules(): array { return [ 'name' => ['required', 'string', 'max:200', 'min:2'], + 'slug' => ['nullable', 'string', 'max:200'], 'parent_id' => ['nullable', 'integer'], 'sort_order' => ['sometimes', 'integer'], 'redirect' => ['nullable', 'string'], diff --git a/app/Http/Requests/Node/UpdateNodeRequest.php b/app/Http/Requests/Node/UpdateNodeRequest.php index 6a5fe4b..7322a5b 100644 --- a/app/Http/Requests/Node/UpdateNodeRequest.php +++ b/app/Http/Requests/Node/UpdateNodeRequest.php @@ -23,8 +23,8 @@ public function authorize(): bool public function rules(): array { return [ - 'name' => ['sometimes', 'required', 'string', 'max:200', 'min:2'], + 'slug' => ['sometimes', 'nullable', 'string', 'max:200'], 'parent_id' => ['sometimes', 'nullable', 'integer'], 'sort_order' => ['sometimes', 'nullable', 'integer'], 'redirect' => ['nullable', 'string'], diff --git a/resources/js/pages/admin/NodeCreateOrEdit.vue b/resources/js/pages/admin/NodeCreateOrEdit.vue index 454e2ee..0770036 100644 --- a/resources/js/pages/admin/NodeCreateOrEdit.vue +++ b/resources/js/pages/admin/NodeCreateOrEdit.vue @@ -11,6 +11,7 @@ const props = defineProps({ const form = useForm({ name: props.node?.name || '', + slug: props.node?.slug || '', parent_id: props.node?.parent_id || props.parent?.id || null, sort_order: props.node?.sort_order ?? 0, redirect: props.redirect, @@ -160,6 +161,39 @@ const goBack = () => { Lower numbers will appear first in the list.

+ +
+ + +

+ {{ form.errors.slug }} +

+

+ Leave empty to automatically generate from the + folder name. +

+
Date: Mon, 24 Aug 2026 22:24:51 +0600 Subject: [PATCH 2/3] feat: collapse custom slug field behind advanced toggle --- resources/js/pages/admin/NodeCreateOrEdit.vue | 86 +++++++++++++------ 1 file changed, 58 insertions(+), 28 deletions(-) diff --git a/resources/js/pages/admin/NodeCreateOrEdit.vue b/resources/js/pages/admin/NodeCreateOrEdit.vue index 0770036..4a3c79e 100644 --- a/resources/js/pages/admin/NodeCreateOrEdit.vue +++ b/resources/js/pages/admin/NodeCreateOrEdit.vue @@ -1,6 +1,7 @@