Dissolve System Settings into individual settings pages
Some checks failed
CI / backend (push) Successful in 1m13s
CI / naming (push) Successful in 1s
CI / frontend (push) Has been cancelled

The monolithic tab page competed with the settings rail as a second
navigation system, and its Integrations tab was a dumping ground. Each
section is now its own routed rail page (ServiceNow, Zabbix Supplies,
Dell Warranty, Collector PC Types, Branding, Floor Map, Printing and
Labels, Email/SMTP, Audit, Authentication, Asset Identifiers, Global
Search), thin over a shared useSystemSettings composable, grouped
logically in the rail with system groups clustered last. Old
/settings/system?tab= URLs redirect to the right page.

Also fixes the post-login redirect: the auth guard now remembers the
intended destination and Login returns there (same-site paths only).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
cproudlock
2026-07-12 07:52:21 -04:00
parent 5393846b8d
commit 1e93b3d570
25 changed files with 1924 additions and 1720 deletions

View File

@@ -105,7 +105,8 @@ router.beforeEach(async (to, from, next) => {
const authStore = useAuthStore()
if (to.meta.requiresAuth && !authStore.isAuthenticated) {
return next('/login')
// Remember where they were headed so login can send them back there.
return next({ path: '/login', query: { redirect: to.fullPath } })
}
if (to.meta.requiresAdmin && !authStore.isAdmin) {
return next('/')

View File

@@ -161,10 +161,101 @@ export default [
component: () => import('../../views/settings/EmployeeDirectory.vue'),
meta: { requiresAuth: true, requiresAdmin: true }
},
// The old monolithic System Settings tab page is split into one routed page
// per section (below). This redirect keeps old bookmarks working: bare
// /settings/system and every /settings/system?tab=<key> land on the right page.
{
path: 'settings/system',
name: 'system-settings',
component: () => import('../../views/settings/SystemSettings.vue'),
redirect: to => {
const tabRedirects = {
integrations: '/settings/servicenow',
branding: '/settings/branding',
printing: '/settings/printing',
email: '/settings/email',
audit: '/settings/audit',
auth: '/settings/authentication',
identifiers: '/settings/assetidentifiers',
search: '/settings/globalsearch',
map: '/settings/floormap',
pctype: '/settings/pctypemapping'
}
// vue-router carries the original ?tab= query onto the target; harmless
// since the new pages ignore it, and the path is what routes the view.
return tabRedirects[to.query.tab] || '/settings/servicenow'
},
meta: { requiresAuth: true, requiresAdmin: true }
},
{
path: 'settings/servicenow',
name: 'servicenow-settings',
component: () => import('../../views/settings/ServiceNowSettings.vue'),
meta: { requiresAuth: true, requiresAdmin: true }
},
{
path: 'settings/zabbix',
name: 'zabbix-settings',
component: () => import('../../views/settings/ZabbixSettings.vue'),
meta: { requiresAuth: true, requiresAdmin: true }
},
{
path: 'settings/dellwarranty',
name: 'dell-warranty-settings',
component: () => import('../../views/settings/DellWarrantySettings.vue'),
meta: { requiresAuth: true, requiresAdmin: true }
},
{
path: 'settings/pctypemapping',
name: 'pctype-mapping-settings',
component: () => import('../../views/settings/PCTypeMappingSettings.vue'),
meta: { requiresAuth: true, requiresAdmin: true }
},
{
path: 'settings/branding',
name: 'branding-settings',
component: () => import('../../views/settings/BrandingSettings.vue'),
meta: { requiresAuth: true, requiresAdmin: true }
},
{
path: 'settings/printing',
name: 'printing-settings',
component: () => import('../../views/settings/PrintingSettings.vue'),
meta: { requiresAuth: true, requiresAdmin: true }
},
{
path: 'settings/email',
name: 'email-settings',
component: () => import('../../views/settings/EmailSettings.vue'),
meta: { requiresAuth: true, requiresAdmin: true }
},
{
path: 'settings/audit',
name: 'audit-settings',
component: () => import('../../views/settings/AuditSettings.vue'),
meta: { requiresAuth: true, requiresAdmin: true }
},
{
path: 'settings/authentication',
name: 'authentication-settings',
component: () => import('../../views/settings/AuthenticationSettings.vue'),
meta: { requiresAuth: true, requiresAdmin: true }
},
{
path: 'settings/assetidentifiers',
name: 'asset-identifiers-settings',
component: () => import('../../views/settings/AssetIdentifiersSettings.vue'),
meta: { requiresAuth: true, requiresAdmin: true }
},
{
path: 'settings/globalsearch',
name: 'global-search-settings',
component: () => import('../../views/settings/GlobalSearchSettings.vue'),
meta: { requiresAuth: true, requiresAdmin: true }
},
{
path: 'settings/floormap',
name: 'floor-map-settings',
component: () => import('../../views/settings/FloorMapSettings.vue'),
meta: { requiresAuth: true, requiresAdmin: true }
},
{