From 7e04742dd72ebbd6ec632168457f3b6d511ce74c Mon Sep 17 00:00:00 2001 From: numen-bot Date: Mon, 16 Mar 2026 05:14:20 +0000 Subject: [PATCH] =?UTF-8?q?hotfix:=20round=203=20=E2=80=94=20fix=204=20pro?= =?UTF-8?q?duction=20UI=20bugs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug 1: Spaces pages double-rendered MainLayout - Remove wrapper from templates in Index/Create/Edit.vue - Add defineOptions({ layout: MainLayout }) to each page - Remove duplicate Spaces nav entry in MainLayout.vue (keep 🏢, remove 🌐) Bug 2: Media upload URL was overcorrected to /api/media (404) - Fix MediaUploadZone.vue: xhr.open to /api/v1/media - Fix Media/Index.vue: fetch URLs to /api/v1/media and /api/v1/media/:id - Add X-Requested-With header to XHR upload Bug 3: Knowledge Graph still 401 - Fix KnowledgeGraphViewer.vue: credentials 'same-origin' -> 'include' - Add decodeURIComponent() to XSRF token extraction Bug 4: Locales page redirects instead of staying on page - Replace ALL router.post/patch/delete with fetch() API calls - Use router.reload({ only: ['locales'] }) after successful ops - Add proper Sanctum auth headers (X-XSRF-TOKEN, X-Requested-With) --- .../Components/Graph/KnowledgeGraphViewer.vue | 4 +- .../js/Components/Media/MediaUploadZone.vue | 3 +- resources/js/Layouts/MainLayout.vue | 1 - resources/js/Pages/Admin/Spaces/Create.vue | 142 ++++++------- resources/js/Pages/Admin/Spaces/Edit.vue | 138 ++++++------ resources/js/Pages/Admin/Spaces/Index.vue | 198 +++++++++--------- resources/js/Pages/Media/Index.vue | 4 +- resources/js/Pages/Settings/Locales.vue | 100 +++++++-- 8 files changed, 323 insertions(+), 267 deletions(-) diff --git a/resources/js/Components/Graph/KnowledgeGraphViewer.vue b/resources/js/Components/Graph/KnowledgeGraphViewer.vue index 599b98e..a594e55 100644 --- a/resources/js/Components/Graph/KnowledgeGraphViewer.vue +++ b/resources/js/Components/Graph/KnowledgeGraphViewer.vue @@ -43,9 +43,9 @@ async function fetchGraph() { const url = props.contentId ? `/api/v1/graph/node/${props.contentId}` : `/api/v1/graph/space/${props.spaceId}`; - const xsrfToken = document.cookie.match(/XSRF-TOKEN=([^;]+)/)?.[1] ?? ''; + const xsrfToken = decodeURIComponent(document.cookie.match(/XSRF-TOKEN=([^;]+)/)?.[1] ?? ''); const res = await fetch(url, { - credentials: 'same-origin', + credentials: 'include', headers: { 'Accept': 'application/json', 'X-Requested-With': 'XMLHttpRequest', diff --git a/resources/js/Components/Media/MediaUploadZone.vue b/resources/js/Components/Media/MediaUploadZone.vue index 6509afb..28382af 100644 --- a/resources/js/Components/Media/MediaUploadZone.vue +++ b/resources/js/Components/Media/MediaUploadZone.vue @@ -76,8 +76,9 @@ async function uploadFile(file) { resolve({ ok: false }); }); - xhr.open('POST', '/api/media'); + xhr.open('POST', '/api/v1/media'); xhr.setRequestHeader('Accept', 'application/json'); + xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); xhr.setRequestHeader('X-XSRF-TOKEN', xsrfToken()); xhr.withCredentials = true; xhr.send(formData); diff --git a/resources/js/Layouts/MainLayout.vue b/resources/js/Layouts/MainLayout.vue index ae80b40..7b7c1d2 100644 --- a/resources/js/Layouts/MainLayout.vue +++ b/resources/js/Layouts/MainLayout.vue @@ -41,7 +41,6 @@ const navigation = [ { name: 'API Tokens', href: '/admin/tokens', icon: '🔑' }, { name: 'Webhooks', href: '/admin/webhooks', icon: '🔗' }, { name: 'Spaces', href: '/admin/spaces', icon: '🏢' }, - { name: 'Spaces', href: '/admin/spaces', icon: '🌐' }, { name: 'Settings', href: '/admin/settings', icon: '⚙️' }, { name: 'Languages', href: '/admin/settings/locales', icon: '🌐' }, { name: 'Plugins', href: '/admin/plugins', icon: '🧩' }, diff --git a/resources/js/Pages/Admin/Spaces/Create.vue b/resources/js/Pages/Admin/Spaces/Create.vue index a0a1d31..a79f7ca 100644 --- a/resources/js/Pages/Admin/Spaces/Create.vue +++ b/resources/js/Pages/Admin/Spaces/Create.vue @@ -34,85 +34,85 @@ watch(() => form.name, (value) => { function submit() { form.post('/admin/spaces') } + +defineOptions({ layout: MainLayout })