Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions apps/files/src/components/FilesNavigationListItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type { IView } from '@nextcloud/files'

import { getCanonicalLocale, getLanguage } from '@nextcloud/l10n'
import { computed, onMounted, ref } from 'vue'
import { useRoute } from 'vue-router/composables'
import NcAppNavigationItem from '@nextcloud/vue/components/NcAppNavigationItem'
import NcIconSvgWrapper from '@nextcloud/vue/components/NcIconSvgWrapper'
import { useVisibleViews } from '../composables/useViews.ts'
Expand All @@ -24,9 +25,22 @@ const props = withDefaults(defineProps<{
const maxLevel = 6 // Limit nesting to not exceed max call stack size
const viewConfigStore = useViewConfigStore()
const viewConfig = computed(() => viewConfigStore.viewConfigs[props.view.id])
const route = useRoute()
const isExpanded = computed(() => viewConfig.value
? (viewConfig.value.expanded === true)
: (props.view.expanded === true))
const isFolderTreeNode = computed(() => props.view.id.startsWith(`${folderTreeId}::`))
const isDirectoryActive = computed(() => {
if (!isFolderTreeNode.value) {
return false
}

const currentView = String(route.params?.view ?? '')
const currentDir = normalizeDir(route.query?.dir)
const viewDir = normalizeDir(props.view.params?.dir)

return currentView === folderTreeId && currentDir === viewDir
})

const views = useVisibleViews()
const childViews = computed(() => {
Expand Down Expand Up @@ -66,7 +80,13 @@ const hasChildViews = computed(() => childViews.value.length > 0)
const navigationRoute = computed(() => {
if (props.view.params) {
const { dir } = props.view.params
return { name: 'filelist', params: { ...props.view.params }, query: { dir } }
const params = { ...props.view.params }
// Keep folder-tree selection bound to directory instead of selected file.
// This prevents extra highlighted entries when opening Details for a child folder.
if (isFolderTreeNode.value) {
delete params.fileid
}
return { name: 'filelist', params, query: { dir } }
}
return { name: 'filelist', params: { view: props.view.id } }
})
Expand Down Expand Up @@ -121,6 +141,18 @@ async function loadChildViews() {
}
}
}

/**
* Normalize directory paths for route comparisons.
*
* @param dir - the route directory to normalize
*/
function normalizeDir(dir: unknown): string {
if (typeof dir !== 'string' || dir.length === 0) {
return '/'
}
return dir.replace(/^(.+)\/$/, '$1')
}
</script>

<script lang="ts">
Expand All @@ -141,7 +173,8 @@ export default {
allow-collapse
:loading="isLoading"
:data-cy-files-navigation-item="view.id"
:exact="hasChildViews /* eslint-disable-line @nextcloud/vue/no-deprecated-props */"
:exact="isFolderTreeNode || hasChildViews /* eslint-disable-line @nextcloud/vue/no-deprecated-props */"
:active="isDirectoryActive"
:name="view.name"
:open="isExpanded"
:pinned="view.sticky"
Expand Down
2 changes: 1 addition & 1 deletion apps/settings/src/components/UserList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
</template>

<template #header>
<UserListHeader :has-obfuscated="hasObfuscated" />
<UserListHeader />
</template>

<template #footer>
Expand Down
24 changes: 1 addition & 23 deletions apps/settings/src/components/Users/UserListHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,14 @@
{{ t('settings', 'Account name') }}
</span>
</th>
<th
class="header__cell"
:class="{ 'header__cell--obfuscated': hasObfuscated }"
data-cy-user-list-header-password
scope="col">
<span>{{ passwordLabel }}</span>
</th>
<th
class="header__cell"
data-cy-user-list-header-email
scope="col">
<span>{{ t('settings', 'Email') }}</span>
</th>
<th
class="header__cell header__cell--large"
class="header__cell header__cell--groups"
data-cy-user-list-header-groups
scope="col">
<span>{{ t('settings', 'Groups') }}</span>
Expand Down Expand Up @@ -121,13 +114,6 @@ import Vue from 'vue'
export default Vue.extend({
name: 'UserListHeader',

props: {
hasObfuscated: {
type: Boolean,
required: true,
},
},

computed: {
showConfig() {
// @ts-expect-error: allow untyped $store
Expand All @@ -138,14 +124,6 @@ export default Vue.extend({
// @ts-expect-error: allow untyped $store
return this.$store.getters.getServerData
},

passwordLabel(): string {
if (this.hasObfuscated) {
// TRANSLATORS This string is for a column header labelling either a password or a message that the current user has insufficient permissions
return t('settings', 'Password or insufficient permissions message')
}
return t('settings', 'Password')
},
},

methods: {
Expand Down
32 changes: 1 addition & 31 deletions apps/settings/src/components/Users/UserRow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -49,36 +49,6 @@
<span class="row__subtitle">{{ user.id }}</span>
</td>

<td
data-cy-user-list-cell-password
class="row__cell"
:class="{ 'row__cell--obfuscated': hasObfuscated }">
<template v-if="editing && settings.canChangePassword && user.backendCapabilities.setPassword">
<NcTextField
v-model="editedPassword"
class="user-row-text-field"
data-cy-user-list-input-password
:data-loading="loading.password || undefined"
:trailing-button-label="t('settings', 'Submit')"
:class="{ 'icon-loading-small': loading.password }"
:show-trailing-button="true"
:disabled="loading.password || isLoadingField"
:minlength="minPasswordLength"
maxlength="469"
:label="t('settings', 'Set new password')"
trailing-button-icon="arrowEnd"
autocapitalize="off"
autocomplete="new-password"
required
spellcheck="false"
type="password"
@trailing-button-click="updatePassword" />
</template>
<span v-else-if="isObfuscated">
{{ t('settings', 'You do not have permissions to see the details of this account') }}
</span>
</td>

<td class="row__cell" data-cy-user-list-cell-email>
<template v-if="editing">
<NcTextField
Expand All @@ -105,7 +75,7 @@
</span>
</td>

<td class="row__cell row__cell--large row__cell--multiline" data-cy-user-list-cell-groups>
<td class="row__cell row__cell--groups row__cell--multiline" data-cy-user-list-cell-groups>
<template v-if="editing">
<label
class="hidden-visually"
Expand Down
1 change: 1 addition & 0 deletions apps/settings/src/components/Users/VirtualList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ export default Vue.extend({
--cell-padding: 7px;
--cell-width: 200px;
--cell-width-large: 300px;
--cell-width-groups: 380px;
--cell-min-width: calc(var(--cell-width) - (2 * var(--cell-padding)));
--sticky-column-z-index: calc(var(--vs-dropdown-z-index) + 1); // Keep the sticky column on top of the select dropdown

Expand Down
5 changes: 5 additions & 0 deletions apps/settings/src/components/Users/shared/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@
width: var(--cell-width-large);
}

&--groups {
min-width: var(--cell-width-groups);
width: var(--cell-width-groups);
}

&--obfuscated {
min-width: 400px;
width: 400px;
Expand Down