@@ -8,6 +8,7 @@ import type { IView } from '@nextcloud/files'
88
99import { getCanonicalLocale , getLanguage } from ' @nextcloud/l10n'
1010import { computed , onMounted , ref } from ' vue'
11+ import { useRoute } from ' vue-router/composables'
1112import NcAppNavigationItem from ' @nextcloud/vue/components/NcAppNavigationItem'
1213import NcIconSvgWrapper from ' @nextcloud/vue/components/NcIconSvgWrapper'
1314import { useVisibleViews } from ' ../composables/useViews.ts'
@@ -24,9 +25,22 @@ const props = withDefaults(defineProps<{
2425const maxLevel = 6 // Limit nesting to not exceed max call stack size
2526const viewConfigStore = useViewConfigStore ()
2627const viewConfig = computed (() => viewConfigStore .viewConfigs [props .view .id ])
28+ const route = useRoute ()
2729const isExpanded = computed (() => viewConfig .value
2830 ? (viewConfig .value .expanded === true )
2931 : (props .view .expanded === true ))
32+ const isFolderTreeNode = computed (() => props .view .id .startsWith (` ${folderTreeId }:: ` ))
33+ const isDirectoryActive = computed (() => {
34+ if (! isFolderTreeNode .value ) {
35+ return false
36+ }
37+
38+ const currentView = String (route .params ?.view ?? ' ' )
39+ const currentDir = normalizeDir (route .query ?.dir )
40+ const viewDir = normalizeDir (props .view .params ?.dir )
41+
42+ return currentView === folderTreeId && currentDir === viewDir
43+ })
3044
3145const views = useVisibleViews ()
3246const childViews = computed (() => {
@@ -66,7 +80,13 @@ const hasChildViews = computed(() => childViews.value.length > 0)
6680const navigationRoute = computed (() => {
6781 if (props .view .params ) {
6882 const { dir } = props .view .params
69- return { name: ' filelist' , params: { ... props .view .params }, query: { dir } }
83+ const params = { ... props .view .params }
84+ // Keep folder-tree selection bound to directory instead of selected file.
85+ // This prevents extra highlighted entries when opening Details for a child folder.
86+ if (isFolderTreeNode .value ) {
87+ delete params .fileid
88+ }
89+ return { name: ' filelist' , params , query: { dir } }
7090 }
7191 return { name: ' filelist' , params: { view: props .view .id } }
7292})
@@ -121,6 +141,18 @@ async function loadChildViews() {
121141 }
122142 }
123143}
144+
145+ /**
146+ * Normalize directory paths for route comparisons.
147+ *
148+ * @param dir - the route directory to normalize
149+ */
150+ function normalizeDir(dir : unknown ): string {
151+ if (typeof dir !== ' string' || dir .length === 0 ) {
152+ return ' /'
153+ }
154+ return dir .replace (/ ^ (. + )\/ $ / , ' $1' )
155+ }
124156 </script >
125157
126158<script lang="ts">
@@ -141,7 +173,8 @@ export default {
141173 allow-collapse
142174 :loading =" isLoading"
143175 :data-cy-files-navigation-item =" view.id"
144- :exact =" hasChildViews /* eslint-disable-line @nextcloud/vue/no-deprecated-props */"
176+ :exact =" isFolderTreeNode || hasChildViews /* eslint-disable-line @nextcloud/vue/no-deprecated-props */"
177+ :active =" isDirectoryActive"
145178 :name =" view.name"
146179 :open =" isExpanded"
147180 :pinned =" view.sticky"
0 commit comments