From 1ced1b16496cce82eb2d774777808e21a5e0a516 Mon Sep 17 00:00:00 2001 From: M_Kececi Date: Thu, 19 Feb 2026 12:27:59 +0300 Subject: [PATCH] Merge remote-tracking branch 'origin/master' --- svc/main.go | 20 ++++---- ui/src/layouts/MainLayout.vue | 10 ++-- ui/src/pages/RoleDepartmentPermissionList.vue | 48 +++++++++++++++---- ui/src/router/index.js | 14 ++++++ ui/src/router/routes.js | 14 +++--- ui/src/stores/authStore.js | 10 +--- 6 files changed, 76 insertions(+), 40 deletions(-) diff --git a/svc/main.go b/svc/main.go index c4748ed..3b6ffc4 100644 --- a/svc/main.go +++ b/svc/main.go @@ -212,19 +212,19 @@ func InitRoutes(pgDB *sql.DB, mssql *sql.DB, ml *mailer.GraphMailer) *mux.Router // ============================================================ bindV3(r, pgDB, "/api/password/change", "POST", - "system", "update", + "auth", "update", wrapV3(http.HandlerFunc(routes.FirstPasswordChangeHandler(pgDB))), ) bindV3(r, pgDB, "/api/activity-logs", "GET", - "user", "view", + "system", "read", wrapV3(routes.AdminActivityLogsHandler(pgDB)), ) bindV3(r, pgDB, "/api/test-mail", "POST", - "user", "insert", + "system", "update", wrapV3(routes.TestMailHandler(ml)), ) @@ -235,12 +235,12 @@ func InitRoutes(pgDB *sql.DB, mssql *sql.DB, ml *mailer.GraphMailer) *mux.Router bindV3(r, pgDB, rolePerm, "GET", - "user", "update", + "system", "update", wrapV3(routes.GetRolePermissionMatrix(pgDB)), ) bindV3(r, pgDB, rolePerm, "POST", - "user", "update", + "system", "update", wrapV3(routes.SaveRolePermissionMatrix(pgDB)), ) @@ -248,12 +248,12 @@ func InitRoutes(pgDB *sql.DB, mssql *sql.DB, ml *mailer.GraphMailer) *mux.Router bindV3(r, pgDB, userPerm, "GET", - "user", "update", + "system", "update", wrapV3(routes.GetUserPermissionsHandler(pgDB)), ) bindV3(r, pgDB, userPerm, "POST", - "user", "update", + "system", "update", wrapV3(routes.SaveUserPermissionsHandler(pgDB)), ) @@ -286,17 +286,17 @@ func InitRoutes(pgDB *sql.DB, mssql *sql.DB, ml *mailer.GraphMailer) *mux.Router bindV3(r, pgDB, "/api/role-dept-permissions/list", "GET", - "user", "update", + "system", "update", wrapV3(http.HandlerFunc(rdHandler.List)), ) bindV3(r, pgDB, rdPerm, "GET", - "user", "update", + "system", "update", wrapV3(http.HandlerFunc(rdHandler.Get)), ) bindV3(r, pgDB, rdPerm, "POST", - "user", "update", + "system", "update", wrapV3(http.HandlerFunc(rdHandler.Save)), ) diff --git a/ui/src/layouts/MainLayout.vue b/ui/src/layouts/MainLayout.vue index 313403f..36e2f86 100644 --- a/ui/src/layouts/MainLayout.vue +++ b/ui/src/layouts/MainLayout.vue @@ -226,25 +226,25 @@ const menuItems = [ { label: 'Rol + Departman Yetkileri', to: '/app/role-dept-permissions', - permission: 'user:update' + permission: 'system:update' }, { label: 'Kullanıcı Yetkileri', to: '/app/user-permissions', - permission: 'user:update' + permission: 'system:update' }, { label: 'Loglar', to: '/app/activity-logs', - permission: 'user:view' + permission: 'system:read' }, { label: 'Test Mail', to: '/app/test-mail', - permission: 'user:insert' + permission: 'system:update' } ] @@ -258,7 +258,7 @@ const menuItems = [ { label: 'Kullanıcılar', to: '/app/users', - permission: 'user:view' + permission: 'system:read' } ] } diff --git a/ui/src/pages/RoleDepartmentPermissionList.vue b/ui/src/pages/RoleDepartmentPermissionList.vue index fcba1a9..0b0d1f7 100644 --- a/ui/src/pages/RoleDepartmentPermissionList.vue +++ b/ui/src/pages/RoleDepartmentPermissionList.vue @@ -46,6 +46,9 @@ Tümünü Seç + + Tümünü Temizle + Tümünü Seç + + Tümünü Temizle + availableModules.includes(m)) - selectedModules.value = selected.length ? selected : [...availableModules] + if (selected.length) { + selectedModules.value = selected + } else { + selectedModules.value = allowEmptySelection.value ? [] : [...availableModules] + } - if (!selectedModules.value.includes(activeModuleCode.value)) { + if (!selectedModules.value.length) { + activeModuleCode.value = '' + } else if (!selectedModules.value.includes(activeModuleCode.value)) { activeModuleCode.value = selectedModules.value[0] } @@ -295,7 +308,7 @@ function syncSelections () { const allActions = actionsByModule.value[m] || [] const prev = selectedActionsByModule.value[m] || [] const filtered = prev.filter((a) => allActions.includes(a)) - next[m] = filtered.length ? filtered : [...allActions] + next[m] = filtered.length ? filtered : (allowEmptySelection.value ? [] : [...allActions]) }) selectedActionsByModule.value = next } @@ -313,6 +326,7 @@ function isModuleSelected (moduleCode) { } function toggleModule (moduleCode, checked) { + allowEmptySelection.value = false const set = new Set(selectedModules.value) if (checked) { set.add(moduleCode) @@ -321,9 +335,8 @@ function toggleModule (moduleCode, checked) { } selectedModules.value = [...set] if (!selectedModules.value.length) { - selectedModules.value = [moduleCode] - } - if (!selectedModules.value.includes(activeModuleCode.value)) { + activeModuleCode.value = '' + } else if (!selectedModules.value.includes(activeModuleCode.value)) { activeModuleCode.value = selectedModules.value[0] } syncSelections() @@ -334,24 +347,31 @@ function onModuleRowClick (moduleCode) { } function selectAllModules () { + allowEmptySelection.value = false selectedModules.value = (store.modules || []).map((m) => m.value) syncSelections() } +function clearAllModules () { + allowEmptySelection.value = true + selectedModules.value = [] + selectedActionsByModule.value = {} + activeModuleCode.value = '' + syncSelections() +} + function isActionSelected (moduleCode, action) { return (selectedActionsByModule.value[moduleCode] || []).includes(action) } function toggleAction (moduleCode, action, checked) { + allowEmptySelection.value = false const current = new Set(selectedActionsByModule.value[moduleCode] || []) if (checked) { current.add(action) } else { current.delete(action) } - if (current.size === 0) { - current.add(action) - } selectedActionsByModule.value = { ...selectedActionsByModule.value, [moduleCode]: [...current] @@ -359,6 +379,7 @@ function toggleAction (moduleCode, action, checked) { } function selectAllActionsForActive () { + allowEmptySelection.value = false if (!activeModuleCode.value) return selectedActionsByModule.value = { ...selectedActionsByModule.value, @@ -366,6 +387,15 @@ function selectAllActionsForActive () { } } +function clearAllActionsForActive () { + allowEmptySelection.value = true + if (!activeModuleCode.value) return + selectedActionsByModule.value = { + ...selectedActionsByModule.value, + [activeModuleCode.value]: [] + } +} + const permissionColumns = computed(() => { const cols = [] selectedModules.value.forEach((m) => { diff --git a/ui/src/router/index.js b/ui/src/router/index.js index c74e02c..d82e2e7 100644 --- a/ui/src/router/index.js +++ b/ui/src/router/index.js @@ -14,6 +14,9 @@ export default route(function () { routes }) + if (typeof window !== 'undefined' && process.env.DEV) { + window.__router = router + } /* ============================================================ 🔐 GLOBAL GUARD @@ -23,6 +26,17 @@ export default route(function () { const auth = useAuthStore() const perm = usePermissionStore() + if (typeof window !== 'undefined') { + console.warn('🧭 ROUTE GUARD HIT:', { + path: to.fullPath, + meta: to.meta + }) + } + + if (typeof window !== 'undefined' && process.env.DEV) { + window.__auth = auth + window.__perm = perm + } /* ================= PUBLIC ================= */ diff --git a/ui/src/router/routes.js b/ui/src/router/routes.js index e2fa415..47076ee 100644 --- a/ui/src/router/routes.js +++ b/ui/src/router/routes.js @@ -69,7 +69,7 @@ const routes = [ path: '', name: 'dashboard', component: () => import('pages/Dashboard.vue'), - meta: { permission: 'system:read' } + meta: {} }, @@ -86,28 +86,28 @@ const routes = [ path: 'role-dept-permissions', name: 'role-dept-permissions', component: () => import('pages/RoleDepartmentPermissionGateway.vue'), - meta: { permission: 'user:update' } + meta: { permission: 'system:update' } }, { path: 'role-dept-permissions/list', name: 'role-dept-permissions-list', component: () => import('pages/RoleDepartmentPermissionList.vue'), - meta: { permission: 'user:update' } + meta: { permission: 'system:update' } }, { path: 'role-dept-permissions/editor', name: 'role-dept-permissions-editor', component: () => import('pages/RoleDepartmentPermissionPage.vue'), - meta: { permission: 'user:update' } + meta: { permission: 'system:update' } }, { path: 'user-permissions', name: 'user-permissions', component: () => import('pages/UserPermissionPage.vue'), - meta: { permission: 'user:update' } + meta: { permission: 'system:update' } }, @@ -190,7 +190,7 @@ const routes = [ path: 'activity-logs', name: 'activity-logs', component: () => import('pages/ActivityLogs.vue'), - meta: { permission: 'user:view' } + meta: { permission: 'system:read' } }, @@ -200,7 +200,7 @@ const routes = [ path: 'test-mail', name: 'test-mail', component: () => import('pages/TestMail.vue'), - meta: { permission: 'user:insert' } + meta: { permission: 'system:update' } }, diff --git a/ui/src/stores/authStore.js b/ui/src/stores/authStore.js index 82e0557..3dc7a87 100644 --- a/ui/src/stores/authStore.js +++ b/ui/src/stores/authStore.js @@ -78,15 +78,7 @@ export const useAuthStore = defineStore('auth', { ========================================================= */ setSession ({ token, user }) { this.token = token - if (user) { - // Keep prior role fields if backend returns partial user payload. - this.user = { - ...(this.user || {}), - ...user - } - } else { - this.user = null - } + this.user = user || null this.forcePasswordChange = !!user?.force_password_change localStorage.setItem('token', token)