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 @@