mirror of
https://github.com/nextcloud/server.git
synced 2026-02-20 00:12:30 -05:00
refactor(files): port file list headers to new files registry
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
This commit is contained in:
parent
1fa470ef99
commit
d669e6ed2b
3 changed files with 56 additions and 27 deletions
|
|
@ -9,7 +9,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import type { Folder, Header, View } from '@nextcloud/files'
|
||||
import type { Folder, IFileListHeader, View } from '@nextcloud/files'
|
||||
import type { PropType } from 'vue'
|
||||
|
||||
import PQueue from 'p-queue'
|
||||
|
|
@ -25,7 +25,7 @@ export default {
|
|||
name: 'FilesListHeader',
|
||||
props: {
|
||||
header: {
|
||||
type: Object as PropType<Header>,
|
||||
type: Object as PropType<IFileListHeader>,
|
||||
required: true,
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -3,39 +3,59 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { Header } from '@nextcloud/files'
|
||||
import type { IFileListHeader } from '@nextcloud/files'
|
||||
import type { registerFileListHeader } from '@nextcloud/files'
|
||||
import type { ComputedRef } from 'vue'
|
||||
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { useFileListHeaders } from './useFileListHeaders.ts'
|
||||
import { nextTick } from 'vue'
|
||||
|
||||
const getFileListHeaders = vi.hoisted(() => vi.fn())
|
||||
|
||||
vi.mock('@nextcloud/files', async (originalModule) => {
|
||||
return {
|
||||
...(await originalModule()),
|
||||
getFileListHeaders,
|
||||
}
|
||||
})
|
||||
interface Context {
|
||||
useFileListHeaders: () => ComputedRef<IFileListHeader[]>
|
||||
registerFileListHeader: typeof registerFileListHeader
|
||||
}
|
||||
|
||||
describe('useFileListHeaders', () => {
|
||||
beforeEach(() => vi.resetAllMocks())
|
||||
beforeEach(async (context: Context) => {
|
||||
delete globalThis._nc_files_scope
|
||||
// reset modules to reset internal variables (the headers ref) of the composable and the library (the scoped globals)
|
||||
vi.resetModules()
|
||||
context.useFileListHeaders = (await import('./useFileListHeaders.ts')).useFileListHeaders
|
||||
context.registerFileListHeader = (await import('@nextcloud/files')).registerFileListHeader
|
||||
})
|
||||
|
||||
it('gets the headers', () => {
|
||||
const header = new Header({ id: '1', order: 5, render: vi.fn(), updated: vi.fn() })
|
||||
getFileListHeaders.mockImplementationOnce(() => [header])
|
||||
it<Context>('gets the headers', ({ useFileListHeaders, registerFileListHeader }) => {
|
||||
const header: IFileListHeader = { id: '1', order: 5, render: vi.fn(), updated: vi.fn() }
|
||||
registerFileListHeader(header)
|
||||
|
||||
const headers = useFileListHeaders()
|
||||
expect(headers.value).toEqual([header])
|
||||
expect(getFileListHeaders).toHaveBeenCalledOnce()
|
||||
})
|
||||
|
||||
it('headers are sorted', () => {
|
||||
const header = new Header({ id: '1', order: 10, render: vi.fn(), updated: vi.fn() })
|
||||
const header2 = new Header({ id: '2', order: 5, render: vi.fn(), updated: vi.fn() })
|
||||
getFileListHeaders.mockImplementationOnce(() => [header, header2])
|
||||
it<Context>('headers are sorted', ({ useFileListHeaders, registerFileListHeader }) => {
|
||||
const header: IFileListHeader = { id: '1', order: 10, render: vi.fn(), updated: vi.fn() }
|
||||
const header2: IFileListHeader = { id: '2', order: 5, render: vi.fn(), updated: vi.fn() }
|
||||
registerFileListHeader(header)
|
||||
registerFileListHeader(header2)
|
||||
|
||||
const headers = useFileListHeaders()
|
||||
// lower order first
|
||||
expect(headers.value.map(({ id }) => id)).toStrictEqual(['2', '1'])
|
||||
expect(getFileListHeaders).toHaveBeenCalledOnce()
|
||||
})
|
||||
|
||||
it<Context>('composable is reactive', async ({ useFileListHeaders, registerFileListHeader }) => {
|
||||
const header: IFileListHeader = { id: 'a', order: 10, render: vi.fn(), updated: vi.fn() }
|
||||
registerFileListHeader(header)
|
||||
await nextTick()
|
||||
|
||||
const headers = useFileListHeaders()
|
||||
expect(headers.value.map(({ id }) => id)).toStrictEqual(['a'])
|
||||
// now add a new header
|
||||
const header2: IFileListHeader = { id: 'b', order: 5, render: vi.fn(), updated: vi.fn() }
|
||||
registerFileListHeader(header2)
|
||||
|
||||
// reactive update, lower order first
|
||||
await nextTick()
|
||||
expect(headers.value.map(({ id }) => id)).toStrictEqual(['b', 'a'])
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -2,18 +2,27 @@
|
|||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
import type { Header } from '@nextcloud/files'
|
||||
|
||||
import type { IFileListHeader } from '@nextcloud/files'
|
||||
import type { ComputedRef } from 'vue'
|
||||
|
||||
import { getFileListHeaders } from '@nextcloud/files'
|
||||
import { getFileListHeaders, getFilesRegistry } from '@nextcloud/files'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
const headers = ref<IFileListHeader[]>()
|
||||
const sorted = computed(() => [...(headers.value ?? [])].sort((a, b) => a.order - b.order) as IFileListHeader[])
|
||||
|
||||
/**
|
||||
* Get the registered and sorted file list headers.
|
||||
*/
|
||||
export function useFileListHeaders(): ComputedRef<Header[]> {
|
||||
const headers = ref(getFileListHeaders())
|
||||
const sorted = computed(() => [...headers.value].sort((a, b) => a.order - b.order) as Header[])
|
||||
export function useFileListHeaders(): ComputedRef<IFileListHeader[]> {
|
||||
if (!headers.value) {
|
||||
// if not initialized by other component yet, initialize and subscribe to registry changes
|
||||
headers.value = getFileListHeaders()
|
||||
getFilesRegistry().addEventListener('register:listHeader', () => {
|
||||
headers.value = getFileListHeaders()
|
||||
})
|
||||
}
|
||||
|
||||
return sorted
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue