Sync System Settings tabs with the URL query
All checks were successful
CI / backend (push) Successful in 1m12s
CI / naming (push) Successful in 1s
CI / frontend (push) Successful in 7s

activeTab read ?tab= only once at mount, so settings-rail links that
change just the query (Branding, Floor Map) updated the URL without
switching the panel. The query param is now the source of truth: a
watcher applies rail/back/forward navigation and tab clicks write the
query via router.replace.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
cproudlock
2026-07-12 06:12:58 -04:00
parent 4fd110a33d
commit 5a192f3100
2 changed files with 22 additions and 2 deletions

View File

@@ -76,6 +76,9 @@ ADR-007 and ADR-002.
### Fixed
- System Settings tabs follow the URL: clicking a settings-rail link that
only changes the ?tab= query (Branding, Floor Map) now switches the right
panel, tab clicks update the URL, and browser back/forward restore tabs.
- Following a relationship link between two assets of the same type now loads
the destination page instead of stale content (router-view keyed on path;
query-only URL changes still avoid a remount).

View File

@@ -15,7 +15,7 @@
:key="tab.key"
class="settings-tab"
:class="{ active: activeTab === tab.key }"
@click="activeTab = tab.key"
@click="selectTab(tab.key)"
>{{ tab.label }}</button>
<p v-if="!visibleTabs.length" class="settings-tab-empty">No matching settings</p>
</nav>
@@ -923,7 +923,7 @@
<script setup>
import { ref, reactive, onMounted, computed, watch } from 'vue'
import { useRoute } from 'vue-router'
import { useRoute, useRouter } from 'vue-router'
import { settingsApi, computersApi } from '../../api'
import { setIdentifierFlag } from '../../composables/identifierSettings'
import { apiError } from '../../utils/apiError'
@@ -944,6 +944,7 @@ const SETTINGS_TABS = [
]
const settingsSearch = ref('')
const route = useRoute()
const router = useRouter()
// Allow deep-linking to a tab, e.g. /settings/system?tab=map (Floor Map)
const activeTab = ref(
route.query.tab && SETTINGS_TABS.some(t => t.key === route.query.tab)
@@ -951,6 +952,22 @@ const activeTab = ref(
: 'integrations'
)
// The query param is the source of truth so the settings rail (which links
// to /settings/system?tab=...) switches the pane without a remount, and
// back/forward + deep links behave.
watch(() => route.query.tab, (tab) => {
if (tab && SETTINGS_TABS.some(t => t.key === tab) && tab !== activeTab.value) {
activeTab.value = String(tab)
}
})
function selectTab(key) {
activeTab.value = key
if (route.query.tab !== key) {
router.replace({ query: { ...route.query, tab: key } })
}
}
const visibleTabs = computed(() => {
const term = settingsSearch.value.trim().toLowerCase()
if (!term) return SETTINGS_TABS