aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files/src
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files/src')
-rw-r--r--apps/files/src/actions/deleteUtils.ts28
-rw-r--r--apps/files/src/components/FileEntry.vue7
-rw-r--r--apps/files/src/components/FileEntry/FileEntryActions.vue10
-rw-r--r--apps/files/src/components/FileEntry/FileEntryName.vue9
-rw-r--r--apps/files/src/components/FileEntryGrid.vue3
-rw-r--r--apps/files/src/components/FileEntryMixin.ts6
-rw-r--r--apps/files/src/components/FilesListVirtual.vue7
-rw-r--r--apps/files/src/components/LegacyView.vue2
-rw-r--r--apps/files/src/components/TemplatePreview.vue2
-rw-r--r--apps/files/src/components/TransferOwnershipDialogue.vue3
-rw-r--r--apps/files/src/composables/useNavigation.spec.ts18
-rw-r--r--apps/files/src/composables/useNavigation.ts9
-rw-r--r--apps/files/src/store/files.ts2
-rw-r--r--apps/files/src/store/renaming.ts79
-rw-r--r--apps/files/src/views/FilesList.vue26
-rw-r--r--apps/files/src/views/Navigation.vue20
-rw-r--r--apps/files/src/views/Sidebar.vue2
-rw-r--r--apps/files/src/views/TemplatePicker.vue4
18 files changed, 159 insertions, 78 deletions
diff --git a/apps/files/src/actions/deleteUtils.ts b/apps/files/src/actions/deleteUtils.ts
index b781be0ff16..ef395bae5b7 100644
--- a/apps/files/src/actions/deleteUtils.ts
+++ b/apps/files/src/actions/deleteUtils.ts
@@ -43,20 +43,6 @@ export const isAllFolders = (nodes: Node[]) => {
export const displayName = (nodes: Node[], view: View) => {
/**
- * If we're in the trashbin, we can only delete permanently
- */
- if (view.id === 'trashbin' || !isTrashbinEnabled()) {
- return t('files', 'Delete permanently')
- }
-
- /**
- * If we're in the sharing view, we can only unshare
- */
- if (isMixedUnshareAndDelete(nodes)) {
- return t('files', 'Delete and unshare')
- }
-
- /**
* If those nodes are all the root node of a
* share, we can only unshare them.
*/
@@ -79,6 +65,20 @@ export const displayName = (nodes: Node[], view: View) => {
}
/**
+ * If we're in the trashbin, we can only delete permanently
+ */
+ if (view.id === 'trashbin' || !isTrashbinEnabled()) {
+ return t('files', 'Delete permanently')
+ }
+
+ /**
+ * If we're in the sharing view, we can only unshare
+ */
+ if (isMixedUnshareAndDelete(nodes)) {
+ return t('files', 'Delete and unshare')
+ }
+
+ /**
* If we're only selecting files, use proper wording
*/
if (isAllFiles(nodes)) {
diff --git a/apps/files/src/components/FileEntry.vue b/apps/files/src/components/FileEntry.vue
index f6f93be1dc8..fc5c7fb97f6 100644
--- a/apps/files/src/components/FileEntry.vue
+++ b/apps/files/src/components/FileEntry.vue
@@ -74,7 +74,7 @@
<!-- View columns -->
<td v-for="column in columns"
:key="column.id"
- :class="`files-list__row-${currentView?.id}-${column.id}`"
+ :class="`files-list__row-${currentView.id}-${column.id}`"
class="files-list__row-column-custom"
:data-cy-files-list-row-column-custom="column.id"
@click="openDetailsIfAvailable">
@@ -135,7 +135,8 @@ export default defineComponent({
const filesStore = useFilesStore()
const renamingStore = useRenamingStore()
const selectionStore = useSelectionStore()
- const { currentView } = useNavigation()
+ // The file list is guaranteed to be only shown with active view - thus we can set the `loaded` flag
+ const { currentView } = useNavigation(true)
const {
directory: currentDir,
fileId: currentFileId,
@@ -180,7 +181,7 @@ export default defineComponent({
if (this.filesListWidth < 512 || this.compact) {
return []
}
- return this.currentView?.columns || []
+ return this.currentView.columns || []
},
size() {
diff --git a/apps/files/src/components/FileEntry/FileEntryActions.vue b/apps/files/src/components/FileEntry/FileEntryActions.vue
index 06b447295eb..8c150b78087 100644
--- a/apps/files/src/components/FileEntry/FileEntryActions.vue
+++ b/apps/files/src/components/FileEntry/FileEntryActions.vue
@@ -77,8 +77,8 @@
</template>
<script lang="ts">
-import type { PropType, ShallowRef } from 'vue'
-import type { FileAction, Node, View } from '@nextcloud/files'
+import type { PropType } from 'vue'
+import type { FileAction, Node } from '@nextcloud/files'
import { DefaultType, NodeStatus } from '@nextcloud/files'
import { showError, showSuccess } from '@nextcloud/dialogs'
@@ -133,12 +133,12 @@ export default defineComponent({
},
setup() {
- const { currentView } = useNavigation()
+ // The file list is guaranteed to be only shown with active view - thus we can set the `loaded` flag
+ const { currentView } = useNavigation(true)
const enabledFileActions = inject<FileAction[]>('enabledFileActions', [])
return {
- // The file list is guaranteed to be only shown with active view
- currentView: currentView as ShallowRef<View>,
+ currentView,
enabledFileActions,
}
},
diff --git a/apps/files/src/components/FileEntry/FileEntryName.vue b/apps/files/src/components/FileEntry/FileEntryName.vue
index 34092a54201..e4cffba32b7 100644
--- a/apps/files/src/components/FileEntry/FileEntryName.vue
+++ b/apps/files/src/components/FileEntry/FileEntryName.vue
@@ -94,7 +94,8 @@ export default defineComponent({
},
setup() {
- const { currentView } = useNavigation()
+ // The file list is guaranteed to be only shown with active view - thus we can set the `loaded` flag
+ const { currentView } = useNavigation(true)
const { directory } = useRouteParameters()
const renamingStore = useRenamingStore()
@@ -143,7 +144,7 @@ export default defineComponent({
}
}
- if (this.defaultFileAction && this.currentView) {
+ if (this.defaultFileAction) {
const displayName = this.defaultFileAction.displayName([this.source], this.currentView)
return {
is: 'button',
@@ -247,8 +248,8 @@ export default defineComponent({
if (status) {
showSuccess(t('files', 'Renamed "{oldName}" to "{newName}"', { oldName, newName }))
this.$nextTick(() => {
- const nameContainter = this.$refs.basename as HTMLElement | undefined
- nameContainter?.focus()
+ const nameContainer = this.$refs.basename as HTMLElement | undefined
+ nameContainer?.focus()
})
} else {
// Was cancelled - meaning the renaming state is just reset
diff --git a/apps/files/src/components/FileEntryGrid.vue b/apps/files/src/components/FileEntryGrid.vue
index 6d31542a15b..f0b086ac891 100644
--- a/apps/files/src/components/FileEntryGrid.vue
+++ b/apps/files/src/components/FileEntryGrid.vue
@@ -107,7 +107,8 @@ export default defineComponent({
const filesStore = useFilesStore()
const renamingStore = useRenamingStore()
const selectionStore = useSelectionStore()
- const { currentView } = useNavigation()
+ // The file list is guaranteed to be only shown with active view - thus we can set the `loaded` flag
+ const { currentView } = useNavigation(true)
const {
directory: currentDir,
fileId: currentFileId,
diff --git a/apps/files/src/components/FileEntryMixin.ts b/apps/files/src/components/FileEntryMixin.ts
index e5d6a27e96c..4a4e4f497b5 100644
--- a/apps/files/src/components/FileEntryMixin.ts
+++ b/apps/files/src/components/FileEntryMixin.ts
@@ -13,7 +13,7 @@ import { generateUrl } from '@nextcloud/router'
import { isPublicShare } from '@nextcloud/sharing/public'
import { vOnClickOutside } from '@vueuse/components'
import { extname } from 'path'
-import Vue, { defineComponent } from 'vue'
+import Vue, { computed, defineComponent } from 'vue'
import { action as sidebarAction } from '../actions/sidebarAction.ts'
import { getDragAndDropPreview } from '../utils/dragUtils.ts'
@@ -52,8 +52,8 @@ export default defineComponent({
provide() {
return {
- defaultFileAction: this.defaultFileAction,
- enabledFileActions: this.enabledFileActions,
+ defaultFileAction: computed(() => this.defaultFileAction),
+ enabledFileActions: computed(() => this.enabledFileActions),
}
},
diff --git a/apps/files/src/components/FilesListVirtual.vue b/apps/files/src/components/FilesListVirtual.vue
index 95bd0f6c571..d4c3d9495b7 100644
--- a/apps/files/src/components/FilesListVirtual.vue
+++ b/apps/files/src/components/FilesListVirtual.vue
@@ -350,7 +350,6 @@ export default defineComponent({
--icon-preview-size: 32px;
--fixed-block-start-position: var(--default-clickable-area);
-
overflow: auto;
height: 100%;
will-change: scroll-position;
@@ -453,7 +452,6 @@ export default defineComponent({
display: flex;
align-items: center;
width: 100%;
- user-select: none;
border-block-end: 1px solid var(--color-border);
box-sizing: border-box;
user-select: none;
@@ -764,7 +762,6 @@ tbody.files-list__tbody.files-list__tbody--grid {
--row-width: calc(var(--icon-preview-size) + var(--item-padding) * 2);
--row-height: calc(var(--icon-preview-size) + var(--name-height) + var(--mtime-height) + var(--item-padding) * 2);
--checkbox-padding: 0px;
-
display: grid;
grid-template-columns: repeat(auto-fill, var(--row-width));
@@ -787,8 +784,8 @@ tbody.files-list__tbody.files-list__tbody--grid {
.files-list__row-checkbox {
position: absolute;
z-index: 9;
- top: calc(var(--item-padding)/2);
- inset-inline-start: calc(var(--item-padding)/2);
+ top: calc(var(--item-padding) / 2);
+ inset-inline-start: calc(var(--item-padding) / 2);
overflow: hidden;
--checkbox-container-size: 44px;
width: var(--checkbox-container-size);
diff --git a/apps/files/src/components/LegacyView.vue b/apps/files/src/components/LegacyView.vue
index b3ec4095fc2..d9baeeb1b07 100644
--- a/apps/files/src/components/LegacyView.vue
+++ b/apps/files/src/components/LegacyView.vue
@@ -38,5 +38,3 @@ export default {
},
}
</script>
-<style>
-</style>
diff --git a/apps/files/src/components/TemplatePreview.vue b/apps/files/src/components/TemplatePreview.vue
index 57af0bf9b64..46e141c6b3b 100644
--- a/apps/files/src/components/TemplatePreview.vue
+++ b/apps/files/src/components/TemplatePreview.vue
@@ -198,7 +198,7 @@ export default {
&__title {
overflow: hidden;
// also count preview border
- max-width: calc(var(--width) + 2*2px);
+ max-width: calc(var(--width) + 2 * 2px);
padding: var(--margin);
white-space: nowrap;
text-overflow: ellipsis;
diff --git a/apps/files/src/components/TransferOwnershipDialogue.vue b/apps/files/src/components/TransferOwnershipDialogue.vue
index 5496c9edc92..6b8e0eb77ba 100644
--- a/apps/files/src/components/TransferOwnershipDialogue.vue
+++ b/apps/files/src/components/TransferOwnershipDialogue.vue
@@ -206,10 +206,12 @@ export default {
.middle-align {
vertical-align: middle;
}
+
p {
margin-top: 12px;
margin-bottom: 12px;
}
+
.new-owner-row {
display: flex;
flex-wrap: wrap;
@@ -229,6 +231,7 @@ p {
max-width: 280px;
}
}
+
.transfer-select-row {
span {
margin-inline-end: 8px;
diff --git a/apps/files/src/composables/useNavigation.spec.ts b/apps/files/src/composables/useNavigation.spec.ts
index efea7103126..569e61825e1 100644
--- a/apps/files/src/composables/useNavigation.spec.ts
+++ b/apps/files/src/composables/useNavigation.spec.ts
@@ -2,6 +2,8 @@
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
+import type { Navigation, View } from '@nextcloud/files'
+
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { mount } from '@vue/test-utils'
import { defineComponent } from 'vue'
@@ -9,8 +11,6 @@ import { defineComponent } from 'vue'
import { useNavigation } from './useNavigation'
import * as nextcloudFiles from '@nextcloud/files'
-const { Navigation, View } = nextcloudFiles
-
// Just a wrapper so we can test the composable
const TestComponent = defineComponent({
template: '<div></div>',
@@ -29,7 +29,7 @@ describe('Composables: useNavigation', () => {
describe('currentView', () => {
beforeEach(() => {
- navigation = new Navigation()
+ navigation = new nextcloudFiles.Navigation()
spy.mockImplementation(() => navigation)
})
@@ -39,7 +39,7 @@ describe('Composables: useNavigation', () => {
})
it('should return already active navigation', async () => {
- const view = new View({ getContents: () => Promise.reject(new Error()), icon: '<svg></svg>', id: 'view-1', name: 'My View 1', order: 0 })
+ const view = new nextcloudFiles.View({ getContents: () => Promise.reject(new Error()), icon: '<svg></svg>', id: 'view-1', name: 'My View 1', order: 0 })
navigation.register(view)
navigation.setActive(view)
// Now the navigation is already set it should take the active navigation
@@ -48,7 +48,7 @@ describe('Composables: useNavigation', () => {
})
it('should be reactive on updating active navigation', async () => {
- const view = new View({ getContents: () => Promise.reject(new Error()), icon: '<svg></svg>', id: 'view-1', name: 'My View 1', order: 0 })
+ const view = new nextcloudFiles.View({ getContents: () => Promise.reject(new Error()), icon: '<svg></svg>', id: 'view-1', name: 'My View 1', order: 0 })
navigation.register(view)
const wrapper = mount(TestComponent)
@@ -63,7 +63,7 @@ describe('Composables: useNavigation', () => {
describe('views', () => {
beforeEach(() => {
- navigation = new Navigation()
+ navigation = new nextcloudFiles.Navigation()
spy.mockImplementation(() => navigation)
})
@@ -73,7 +73,7 @@ describe('Composables: useNavigation', () => {
})
it('should return already registered views', () => {
- const view = new View({ getContents: () => Promise.reject(new Error()), icon: '<svg></svg>', id: 'view-1', name: 'My View 1', order: 0 })
+ const view = new nextcloudFiles.View({ getContents: () => Promise.reject(new Error()), icon: '<svg></svg>', id: 'view-1', name: 'My View 1', order: 0 })
// register before mount
navigation.register(view)
// now mount and check that the view is listed
@@ -82,8 +82,8 @@ describe('Composables: useNavigation', () => {
})
it('should be reactive on registering new views', () => {
- const view = new View({ getContents: () => Promise.reject(new Error()), icon: '<svg></svg>', id: 'view-1', name: 'My View 1', order: 0 })
- const view2 = new View({ getContents: () => Promise.reject(new Error()), icon: '<svg></svg>', id: 'view-2', name: 'My View 2', order: 1 })
+ const view = new nextcloudFiles.View({ getContents: () => Promise.reject(new Error()), icon: '<svg></svg>', id: 'view-1', name: 'My View 1', order: 0 })
+ const view2 = new nextcloudFiles.View({ getContents: () => Promise.reject(new Error()), icon: '<svg></svg>', id: 'view-2', name: 'My View 2', order: 1 })
// register before mount
navigation.register(view)
diff --git a/apps/files/src/composables/useNavigation.ts b/apps/files/src/composables/useNavigation.ts
index 714b3a6d7b2..2a6f22a1232 100644
--- a/apps/files/src/composables/useNavigation.ts
+++ b/apps/files/src/composables/useNavigation.ts
@@ -11,18 +11,21 @@ import { onMounted, onUnmounted, shallowRef, triggerRef } from 'vue'
/**
* Composable to get the currently active files view from the files navigation
+ * @param _loaded If set enforce a current view is loaded
*/
-export function useNavigation() {
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+export function useNavigation<T extends boolean>(_loaded?: T) {
+ type MaybeView = T extends true ? View : (View | null);
const navigation = getNavigation()
const views: ShallowRef<View[]> = shallowRef(navigation.views)
- const currentView: ShallowRef<View | null> = shallowRef(navigation.active)
+ const currentView: ShallowRef<MaybeView> = shallowRef(navigation.active as MaybeView)
/**
* Event listener to update the `currentView`
* @param event The update event
*/
function onUpdateActive(event: CustomEvent<View|null>) {
- currentView.value = event.detail
+ currentView.value = event.detail as MaybeView
}
/**
diff --git a/apps/files/src/store/files.ts b/apps/files/src/store/files.ts
index 952e3cd41c5..f2079bb1d4d 100644
--- a/apps/files/src/store/files.ts
+++ b/apps/files/src/store/files.ts
@@ -58,7 +58,7 @@ export const useFilesStore = function(...args) {
*
* @param service The service (files view)
* @param path The path relative within the service
- * @returns Array of cached nodes within the path
+ * @return Array of cached nodes within the path
*/
getNodesByPath(service: string, path?: string): Node[] {
const pathsStore = usePathsStore()
diff --git a/apps/files/src/store/renaming.ts b/apps/files/src/store/renaming.ts
index ff8ac3ba8da..2ec73837f82 100644
--- a/apps/files/src/store/renaming.ts
+++ b/apps/files/src/store/renaming.ts
@@ -8,11 +8,77 @@ import type { RenamingStore } from '../types'
import axios, { isAxiosError } from '@nextcloud/axios'
import { emit, subscribe } from '@nextcloud/event-bus'
import { NodeStatus } from '@nextcloud/files'
+import { DialogBuilder } from '@nextcloud/dialogs'
import { t } from '@nextcloud/l10n'
-import { basename, dirname } from 'path'
+import { basename, dirname, extname } from 'path'
import { defineStore } from 'pinia'
import logger from '../logger'
import Vue from 'vue'
+import IconCancel from '@mdi/svg/svg/cancel.svg?raw'
+import IconCheck from '@mdi/svg/svg/check.svg?raw'
+
+let isDialogVisible = false
+
+const showWarningDialog = (oldExtension: string, newExtension: string): Promise<boolean> => {
+ if (isDialogVisible) {
+ return Promise.resolve(false)
+ }
+
+ isDialogVisible = true
+
+ let message
+
+ if (!oldExtension && newExtension) {
+ message = t(
+ 'files',
+ 'Adding the file extension "{new}" may render the file unreadable.',
+ { new: newExtension },
+ )
+ } else if (!newExtension) {
+ message = t(
+ 'files',
+ 'Removing the file extension "{old}" may render the file unreadable.',
+ { old: oldExtension },
+ )
+ } else {
+ message = t(
+ 'files',
+ 'Changing the file extension from "{old}" to "{new}" may render the file unreadable.',
+ { old: oldExtension, new: newExtension },
+ )
+ }
+
+ return new Promise((resolve) => {
+ const dialog = new DialogBuilder()
+ .setName(t('files', 'Change file extension'))
+ .setText(message)
+ .setButtons([
+ {
+ label: t('files', 'Keep {oldextension}', { oldextension: oldExtension }),
+ icon: IconCancel,
+ type: 'secondary',
+ callback: () => {
+ isDialogVisible = false
+ resolve(false)
+ },
+ },
+ {
+ label: newExtension.length ? t('files', 'Use {newextension}', { newextension: newExtension }) : t('files', 'Remove extension'),
+ icon: IconCheck,
+ type: 'primary',
+ callback: () => {
+ isDialogVisible = false
+ resolve(true)
+ },
+ },
+ ])
+ .build()
+
+ dialog.show().then(() => {
+ dialog.hide()
+ })
+ })
+}
export const useRenamingStore = function(...args) {
const store = defineStore('renaming', {
@@ -36,6 +102,17 @@ export const useRenamingStore = function(...args) {
const newName = this.newName.trim?.() || ''
const oldName = this.renamingNode.basename
const oldEncodedSource = this.renamingNode.encodedSource
+
+ // Check for extension change
+ const oldExtension = extname(oldName)
+ const newExtension = extname(newName)
+ if (oldExtension !== newExtension) {
+ const proceed = await showWarningDialog(oldExtension, newExtension)
+ if (!proceed) {
+ return false
+ }
+ }
+
if (oldName === newName) {
return false
}
diff --git a/apps/files/src/views/FilesList.vue b/apps/files/src/views/FilesList.vue
index 23aab26f839..56907db3feb 100644
--- a/apps/files/src/views/FilesList.vue
+++ b/apps/files/src/views/FilesList.vue
@@ -17,7 +17,7 @@
type="tertiary"
@click="openSharingSidebar">
<template #icon>
- <LinkIcon v-if="shareButtonType === Type.SHARE_TYPE_LINK" />
+ <LinkIcon v-if="shareButtonType === ShareType.Link" />
<AccountPlusIcon v-else :size="20" />
</template>
</NcButton>
@@ -141,7 +141,7 @@
</template>
<script lang="ts">
-import type { ContentsWithRoot, INode } from '@nextcloud/files'
+import type { ContentsWithRoot, Folder, INode } from '@nextcloud/files'
import type { Upload } from '@nextcloud/upload'
import type { CancelablePromise } from 'cancelable-promise'
import type { ComponentPublicInstance } from 'vue'
@@ -150,11 +150,11 @@ import type { UserConfig } from '../types.ts'
import { getCapabilities } from '@nextcloud/capabilities'
import { emit, subscribe, unsubscribe } from '@nextcloud/event-bus'
-import { Folder, Node, Permission, sortNodes, getFileListActions } from '@nextcloud/files'
+import { Node, Permission, sortNodes, getFileListActions } from '@nextcloud/files'
import { translate as t } from '@nextcloud/l10n'
import { join, dirname, normalize } from 'path'
import { showError, showWarning } from '@nextcloud/dialogs'
-import { Type } from '@nextcloud/sharing'
+import { ShareType } from '@nextcloud/sharing'
import { UploadPicker, UploadStatus } from '@nextcloud/upload'
import { loadState } from '@nextcloud/initial-state'
import { defineComponent } from 'vue'
@@ -261,7 +261,7 @@ export default defineComponent({
// non reactive data
enableGridView,
forbiddenCharacters,
- Type,
+ ShareType,
}
},
@@ -391,22 +391,22 @@ export default defineComponent({
return t('files', 'Share')
}
- if (this.shareButtonType === Type.SHARE_TYPE_LINK) {
+ if (this.shareButtonType === ShareType.Link) {
return t('files', 'Shared by link')
}
return t('files', 'Shared')
},
- shareButtonType(): Type | null {
+ shareButtonType(): ShareType | null {
if (!this.shareTypesAttributes) {
return null
}
// If all types are links, show the link icon
- if (this.shareTypesAttributes.some(type => type === Type.SHARE_TYPE_LINK)) {
- return Type.SHARE_TYPE_LINK
+ if (this.shareTypesAttributes.some(type => type === ShareType.Link)) {
+ return ShareType.Link
}
- return Type.SHARE_TYPE_USER
+ return ShareType.User
},
gridViewButtonLabel() {
@@ -454,7 +454,11 @@ export default defineComponent({
if (action.enabled === undefined) {
return true
}
- return action.enabled(this.currentView, this.dirContents, { folder: this.currentFolder })
+ return action.enabled(
+ this.currentView!,
+ this.dirContents,
+ { folder: this.currentFolder! },
+ )
})
.toSorted((a, b) => a.order - b.order)
return enabledActions
diff --git a/apps/files/src/views/Navigation.vue b/apps/files/src/views/Navigation.vue
index 9570cb1be66..1420e8e1d9e 100644
--- a/apps/files/src/views/Navigation.vue
+++ b/apps/files/src/views/Navigation.vue
@@ -201,19 +201,15 @@ export default defineComponent({
</script>
<style scoped lang="scss">
-// TODO: remove when https://github.com/nextcloud/nextcloud-vue/pull/3539 is in
-.app-navigation::v-deep .app-navigation-entry-icon {
- background-repeat: no-repeat;
- background-position: center;
-}
-
-.app-navigation::v-deep .app-navigation-entry.active .button-vue.icon-collapse:not(:hover) {
- color: var(--color-primary-element-text);
-}
+.app-navigation {
+ :deep(.app-navigation-entry.active .button-vue.icon-collapse:not(:hover)) {
+ color: var(--color-primary-element-text);
+ }
-.app-navigation > ul.app-navigation__list {
- // Use flex gap value for more elegant spacing
- padding-bottom: var(--default-grid-baseline, 4px);
+ > ul.app-navigation__list {
+ // Use flex gap value for more elegant spacing
+ padding-bottom: var(--default-grid-baseline, 4px);
+ }
}
.app-navigation-entry__settings {
diff --git a/apps/files/src/views/Sidebar.vue b/apps/files/src/views/Sidebar.vue
index ca7afac7780..6bf558181d2 100644
--- a/apps/files/src/views/Sidebar.vue
+++ b/apps/files/src/views/Sidebar.vue
@@ -612,7 +612,7 @@ export default {
}
.svg-icon {
- ::v-deep svg {
+ :deep(svg) {
width: 20px;
height: 20px;
fill: currentColor;
diff --git a/apps/files/src/views/TemplatePicker.vue b/apps/files/src/views/TemplatePicker.vue
index a62b6f76c6a..f3c7aadf2e2 100644
--- a/apps/files/src/views/TemplatePicker.vue
+++ b/apps/files/src/views/TemplatePicker.vue
@@ -313,7 +313,7 @@ export default defineComponent({
padding: calc(var(--margin) * 2) var(--margin);
position: sticky;
bottom: 0;
- background-image: linear-gradient(0, var(--gradient-main-background));
+ background-image: linear-gradient(0deg, var(--gradient-main-background));
button, input[type='submit'] {
height: 44px;
@@ -321,7 +321,7 @@ export default defineComponent({
}
// Make sure we're relative for the loading emptycontent on top
- ::v-deep .modal-container {
+ :deep(.modal-container) {
position: relative;
}