Skip to content

Commit

Permalink
feat: add FileListHeader
Browse files Browse the repository at this point in the history
Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
  • Loading branch information
skjnldsv committed Aug 4, 2023
1 parent 7648d4b commit 195ae95
Show file tree
Hide file tree
Showing 4 changed files with 184 additions and 5 deletions.
67 changes: 67 additions & 0 deletions __tests__/fileListHeaders.spec.ts
@@ -0,0 +1,67 @@
import { describe, expect, test, beforeEach, vi } from 'vitest'
import { Header, getFileListHeaders, registerFileListHeaders } from '../lib/fileListHeaders'
import logger from '../lib/utils/logger'
import { Folder } from '../lib/files/folder'

describe('FileListHeader init', () => {

beforeEach(() => {
delete window._nc_filelistheader
})

test('Getting empty uninitialized FileListHeader', () => {
logger.debug = vi.fn()
const headers = getFileListHeaders()
expect(window._nc_filelistheader).toBeUndefined()
expect(headers).toHaveLength(0)
expect(logger.debug).toHaveBeenCalledTimes(0)
})

test('Initializing FileListHeader', () => {
logger.debug = vi.fn()
const header = new Header({
id: 'test',
order: 1,
enabled: () => true,
render: () => {},
updated: () => {},
})

expect(header.id).toBe('test')
expect(header.order).toBe(1)
expect(header.enabled!({} as Folder, {})).toBe(true)

Check warning on line 32 in __tests__/fileListHeaders.spec.ts

View workflow job for this annotation

GitHub Actions / eslint

Forbidden non-null assertion

registerFileListHeaders(header)

expect(window._nc_filelistheader).toHaveLength(1)
expect(getFileListHeaders()).toHaveLength(1)
expect(getFileListHeaders()[0]).toStrictEqual(header)
expect(logger.debug).toHaveBeenCalled()
})

test('Duplicate Header gets rejected', () => {
logger.error = vi.fn()
const header = new Header({
id: 'test',
order: 1,
render: () => {},
updated: () => {},
})

registerFileListHeaders(header)
expect(getFileListHeaders()).toHaveLength(1)
expect(getFileListHeaders()[0]).toStrictEqual(header)

const header2 = new Header({
id: 'test',
order: 2,
render: () => {},
updated: () => {},
})

registerFileListHeaders(header2)
expect(getFileListHeaders()).toHaveLength(1)
expect(getFileListHeaders()[0]).toStrictEqual(header)
expect(logger.error).toHaveBeenCalledWith('Header test already registered', { header: header2 })
})
})
109 changes: 109 additions & 0 deletions lib/fileListHeaders.ts
@@ -0,0 +1,109 @@
/**
* @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com>
*
* @author John Molakvoæ <skjnldsv@protonmail.com>
*
* @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

import { Folder } from './files/folder'
import logger from './utils/logger'

export interface HeaderData {
/** Unique ID */
id: string
/** Order */
order: number
/** Condition wether this header is shown or not */
enabled?: (folder: Folder, view) => boolean
/** Executed when file list is initialized */
render: (el: HTMLElement, folder: Folder, view) => void
/** Executed when root folder changed */
updated(folder: Folder, view)
}

export class Header {

private _header: HeaderData

constructor(header: HeaderData) {
this.validateHeader(header)
this._header = header
}

get id() {
return this._header.id
}

get order() {
return this._header.order
}

get enabled() {
return this._header.enabled
}

get render() {
return this._header.render
}

get updated() {
return this._header.updated
}

private validateHeader(header: HeaderData) {
if (!header.id || !header.render || !header.updated) {
throw new Error('Invalid header: id, render and updated are required')
}

if (typeof header.id !== 'string') {
throw new Error('Invalid id property')
}

if (header.enabled !== undefined && typeof header.enabled !== 'function') {
throw new Error('Invalid enabled property')
}

if (header.render && typeof header.render !== 'function') {
throw new Error('Invalid render property')
}

if (header.updated && typeof header.updated !== 'function') {
throw new Error('Invalid updated property')
}
}

}

export const registerFileListHeaders = function(header: Header): void {
if (typeof window._nc_filelistheader === 'undefined') {
window._nc_filelistheader = []
logger.debug('FileActions initialized')
}

// Check duplicates
if (window._nc_filelistheader.find(search => search.id === header.id)) {
logger.error(`Header ${header.id} already registered`, { header })
return
}

window._nc_filelistheader.push(header)
}

export const getFileListHeaders = function(): Header[] {
return window._nc_filelistheader || []
}
3 changes: 2 additions & 1 deletion lib/index.ts
Expand Up @@ -24,7 +24,8 @@
import { type Entry, getNewFileMenu } from './newFileMenu'

export { formatFileSize } from './humanfilesize'
export { FileAction, registerFileAction, getFileActions } from './fileAction'
export { FileAction, getFileActions, registerFileAction } from './fileAction'
export { Header, getFileListHeaders, registerFileListHeaders } from './fileListHeaders'
export { type Entry } from './newFileMenu'
export { Permission } from './permissions'

Expand Down
10 changes: 6 additions & 4 deletions window.d.ts
@@ -1,17 +1,19 @@
/// <reference types="@nextcloud/typings" />

import type { DavProperty } from './lib/dav/davProperties'
import type { FileAction } from './lib/fileAction'
import type { Header } from './lib/fileListHeaders'
import type { NewFileMenu } from './lib/newFileMenu'
import type { DavProperty } from './lib/dav/davProperties'

export {}

declare global {
interface Window {
OC: Nextcloud.v25.OC | Nextcloud.v26.OC | Nextcloud.v27.OC;
_nc_newfilemenu?: NewFileMenu
_nc_fileactions?: FileAction[]
_nc_dav_properties?: string[]
_nc_dav_namespaces?: DavProperty
_nc_dav_properties?: string[]
_nc_fileactions?: FileAction[]
_nc_filelistheader?: Header[]
_nc_newfilemenu?: NewFileMenu
}
}

0 comments on commit 195ae95

Please sign in to comment.