Skip to content

Commit

Permalink
refactor(files): Provide useFileListWidth composable
Browse files Browse the repository at this point in the history
Replace the mixin with a composable, this is better typed and works in
both: Options- and Composition API.
Also added component tests for it.

Signed-off-by: Ferdinand Thiessen <[email protected]>
  • Loading branch information
susnux committed Nov 15, 2024
1 parent ca4be91 commit 2c81114
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 72 deletions.
16 changes: 7 additions & 9 deletions apps/files/src/components/BreadCrumbs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
v-bind="section"
dir="auto"
:to="section.to"
:force-icon-text="index === 0 && filesListWidth >= 486"
:force-icon-text="index === 0 && fileListWidth >= 486"
:title="titleForSection(index, section)"
:aria-description="ariaForSection(section)"
@click.native="onClick(section.to)"
Expand Down Expand Up @@ -46,15 +46,15 @@ import NcBreadcrumb from '@nextcloud/vue/dist/Components/NcBreadcrumb.js'
import NcBreadcrumbs from '@nextcloud/vue/dist/Components/NcBreadcrumbs.js'
import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js'
import { useNavigation } from '../composables/useNavigation'
import { onDropInternalFiles, dataTransferToFileTree, onDropExternalFiles } from '../services/DropService'
import { useNavigation } from '../composables/useNavigation.ts'
import { onDropInternalFiles, dataTransferToFileTree, onDropExternalFiles } from '../services/DropService.ts'
import { useFileListWidth } from '../composables/useFileListWidth.ts'
import { showError } from '@nextcloud/dialogs'
import { useDragAndDropStore } from '../store/dragging.ts'
import { useFilesStore } from '../store/files.ts'
import { usePathsStore } from '../store/paths.ts'
import { useSelectionStore } from '../store/selection.ts'
import { useUploaderStore } from '../store/uploader.ts'
import filesListWidthMixin from '../mixins/filesListWidth.ts'
import logger from '../logger'
export default defineComponent({
Expand All @@ -66,10 +66,6 @@ export default defineComponent({
NcIconSvgWrapper,
},
mixins: [
filesListWidthMixin,
],
props: {
path: {
type: String,
Expand All @@ -83,6 +79,7 @@ export default defineComponent({
const pathsStore = usePathsStore()
const selectionStore = useSelectionStore()
const uploaderStore = useUploaderStore()
const fileListWidth = useFileListWidth()
const { currentView, views } = useNavigation()
return {
Expand All @@ -93,6 +90,7 @@ export default defineComponent({
uploaderStore,
currentView,
fileListWidth,
views,
}
},
Expand Down Expand Up @@ -129,7 +127,7 @@ export default defineComponent({
wrapUploadProgressBar(): boolean {
// if an upload is ongoing, and on small screens / mobile, then
// show the progress bar for the upload below breadcrumbs
return this.isUploadInProgress && this.filesListWidth < 512
return this.isUploadInProgress && this.fileListWidth < 512
},
// used to show the views icon for the first breadcrumb
Expand Down
14 changes: 6 additions & 8 deletions apps/files/src/components/FilesListTableHeaderActions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js
import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'
import { useRouteParameters } from '../composables/useRouteParameters.ts'
import { useFileListWidth } from '../composables/useFileListWidth.ts'
import { useActionsMenuStore } from '../store/actionsmenu.ts'
import { useFilesStore } from '../store/files.ts'
import { useSelectionStore } from '../store/selection.ts'
import filesListWidthMixin from '../mixins/filesListWidth.ts'
import logger from '../logger.ts'
// The registered actions list
Expand All @@ -62,10 +62,6 @@ export default defineComponent({
NcLoadingIcon,
},
mixins: [
filesListWidthMixin,
],
props: {
currentView: {
type: Object as PropType<View>,
Expand All @@ -81,10 +77,12 @@ export default defineComponent({
const actionsMenuStore = useActionsMenuStore()
const filesStore = useFilesStore()
const selectionStore = useSelectionStore()
const fileListWidth = useFileListWidth()
const { directory } = useRouteParameters()
return {
directory,
fileListWidth,
actionsMenuStore,
filesStore,
Expand Down Expand Up @@ -126,13 +124,13 @@ export default defineComponent({
},
inlineActions() {
if (this.filesListWidth < 512) {
if (this.fileListWidth < 512) {
return 0
}
if (this.filesListWidth < 768) {
if (this.fileListWidth < 768) {
return 1
}
if (this.filesListWidth < 1024) {
if (this.fileListWidth < 1024) {
return 2
}
return 3
Expand Down
18 changes: 8 additions & 10 deletions apps/files/src/components/FilesListVirtual.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
isMtimeAvailable,
isSizeAvailable,
nodes,
filesListWidth,
fileListWidth,
}"
:scroll-to-index="scrollToIndex"
:caption="caption">
Expand All @@ -39,7 +39,7 @@
<template #header>
<!-- Table header and sort buttons -->
<FilesListTableHeader ref="thead"
:files-list-width="filesListWidth"
:files-list-width="fileListWidth"
:is-mtime-available="isMtimeAvailable"
:is-size-available="isSizeAvailable"
:nodes="nodes" />
Expand All @@ -48,7 +48,7 @@
<!-- Tfoot-->
<template #footer>
<FilesListTableFooter :current-view="currentView"
:files-list-width="filesListWidth"
:files-list-width="fileListWidth"
:is-mtime-available="isMtimeAvailable"
:is-size-available="isSizeAvailable"
:nodes="nodes"
Expand All @@ -69,6 +69,7 @@ import { subscribe, unsubscribe } from '@nextcloud/event-bus'
import { defineComponent } from 'vue'
import { action as sidebarAction } from '../actions/sidebarAction.ts'
import { useFileListWidth } from '../composables/useFileListWidth.ts'
import { useRouteParameters } from '../composables/useRouteParameters.ts'
import { getSummaryFor } from '../utils/fileUtils'
import { useSelectionStore } from '../store/selection.js'
Expand All @@ -79,7 +80,6 @@ import FileEntryGrid from './FileEntryGrid.vue'
import FilesListHeader from './FilesListHeader.vue'
import FilesListTableFooter from './FilesListTableFooter.vue'
import FilesListTableHeader from './FilesListTableHeader.vue'
import filesListWidthMixin from '../mixins/filesListWidth.ts'
import VirtualList from './VirtualList.vue'
import logger from '../logger.ts'
import FilesListTableHeaderActions from './FilesListTableHeaderActions.vue'
Expand All @@ -97,10 +97,6 @@ export default defineComponent({
FilesListTableHeaderActions,
},
mixins: [
filesListWidthMixin,
],
props: {
currentView: {
type: View,
Expand All @@ -119,10 +115,12 @@ export default defineComponent({
setup() {
const userConfigStore = useUserConfigStore()
const selectionStore = useSelectionStore()
const fileListWidth = useFileListWidth()
const { fileId, openFile } = useRouteParameters()
return {
fileId,
fileListWidth,
openFile,
userConfigStore,
Expand Down Expand Up @@ -151,14 +149,14 @@ export default defineComponent({
isMtimeAvailable() {
// Hide mtime column on narrow screens
if (this.filesListWidth < 768) {
if (this.fileListWidth < 768) {
return false
}
return this.nodes.some(node => node.mtime !== undefined)
},
isSizeAvailable() {
// Hide size column on narrow screens
if (this.filesListWidth < 768) {
if (this.fileListWidth < 768) {
return false
}
return this.nodes.some(node => node.size !== undefined)
Expand Down
21 changes: 13 additions & 8 deletions apps/files/src/components/VirtualList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,9 @@
import type { File, Folder, Node } from '@nextcloud/files'
import type { PropType } from 'vue'
import { useFileListWidth } from '../composables/useFileListWidth.ts'
import { defineComponent } from 'vue'
import debounce from 'debounce'
import Vue from 'vue'
import filesListWidthMixin from '../mixins/filesListWidth.ts'
import logger from '../logger.ts'
interface RecycledPoolItem {
Expand All @@ -70,11 +69,9 @@ type DataSource = File | Folder
type DataSourceKey = keyof DataSource
export default Vue.extend({
export default defineComponent({
name: 'VirtualList',
mixins: [filesListWidthMixin],
props: {
dataComponent: {
type: [Object, Function],
Expand All @@ -101,14 +98,22 @@ export default Vue.extend({
default: false,
},
/**
* Visually hidden caption for the table accesibility
* Visually hidden caption for the table accessibility
*/
caption: {
type: String,
default: '',
},
},
setup() {
const fileListWidth = useFileListWidth()
return {
fileListWidth,
}
},
data() {
return {
index: this.scrollToIndex,
Expand Down Expand Up @@ -151,7 +156,7 @@ export default Vue.extend({
if (!this.gridMode) {
return 1
}
return Math.floor(this.filesListWidth / this.itemWidth)
return Math.floor(this.fileListWidth / this.itemWidth)
},
/**
Expand Down
56 changes: 56 additions & 0 deletions apps/files/src/composables/useFileListWidth.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*!
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import { defineComponent } from 'vue'
import { useFileListWidth } from './useFileListWidth.ts'

const ComponentMock = defineComponent({
template: '<div id="test-component" style="width: 100%;background: white;">{{ fileListWidth }}</div>',
setup() {
return {
fileListWidth: useFileListWidth(),
}
},
})
const FileListMock = defineComponent({
template: '<main id="app-content-vue" style="width: 100%;"><component-mock /></main>',
components: {
ComponentMock,
},
})

describe('composable: fileListWidth', () => {

it('Has initial value', () => {
cy.viewport(600, 400)

cy.mount(FileListMock, {})
cy.get('#app-content-vue')
.should('be.visible')
.and('contain.text', '600')
})

it('Is reactive to size change', () => {
cy.viewport(600, 400)
cy.mount(FileListMock)
cy.get('#app-content-vue').should('contain.text', '600')

cy.viewport(800, 400)
cy.screenshot()
cy.get('#app-content-vue').should('contain.text', '800')
})

it('Is reactive to style changes', () => {
cy.viewport(600, 400)
cy.mount(FileListMock)
cy.get('#app-content-vue')
.should('be.visible')
.and('contain.text', '600')
.invoke('attr', 'style', 'width: 100px')

cy.get('#app-content-vue')
.should('contain.text', '100')
})
})
20 changes: 20 additions & 0 deletions apps/files/src/composables/useFileListWidth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*!
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import type { Ref } from 'vue'
import { useElementSize } from '@vueuse/core'
import { onMounted, onUnmounted, ref } from 'vue'

/**
* Get the reactive width of the file list
*/
export function useFileListWidth(): Readonly<Ref<number>> {
const element = ref(document.querySelector<HTMLElement>('#app-content-vue') ?? document.body)
onMounted(() => { element.value = document.querySelector('#app-content-vue')! })

const { width, stop } = useElementSize(element)
onUnmounted(stop)

return width
}
33 changes: 0 additions & 33 deletions apps/files/src/mixins/filesListWidth.ts

This file was deleted.

Loading

0 comments on commit 2c81114

Please sign in to comment.