Skip to content

Commit

Permalink
fixup! feat(FileAction): add file action support
Browse files Browse the repository at this point in the history
Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
  • Loading branch information
skjnldsv committed Mar 24, 2023
1 parent 36a5c10 commit ca1b66d
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 28 deletions.
16 changes: 8 additions & 8 deletions __tests__/fileAction.spec.ts
Expand Up @@ -27,8 +27,8 @@ describe('FileActions init', () => {
})

expect(action.id).toBe('test')
expect(action.displayName([])).toBe('Test')
expect(action.iconSvgInline([])).toBe('<svg></svg>')
expect(action.displayName([], {})).toBe('Test')
expect(action.iconSvgInline([], {})).toBe('<svg></svg>')

registerFileAction(action)

Expand Down Expand Up @@ -204,14 +204,14 @@ describe('FileActions creation', () => {
})

expect(action.id).toBe('test')
expect(action.displayName([])).toBe('Test')
expect(action.iconSvgInline([])).toBe('<svg></svg>')
await expect(action.exec({} as any)).resolves.toBe(true)
await expect(action.execBatch?.([])).resolves.toStrictEqual([true])
expect(action.displayName([], {})).toBe('Test')
expect(action.iconSvgInline([], {})).toBe('<svg></svg>')
await expect(action.exec({} as any, {})).resolves.toBe(true)
await expect(action.execBatch?.([], {})).resolves.toStrictEqual([true])
expect(action.enabled?.({} as any, {})).toBe(true)
expect(action.order).toBe(100)
expect(action.default).toBe(true)
expect(action.inline?.({} as any)).toBe(true)
expect(action.renderInline?.({} as any).outerHTML).toBe('<span>test</span>')
expect(action.inline?.({} as any, {})).toBe(true)
expect(action.renderInline?.({} as any, {}).outerHTML).toBe('<span>test</span>')
})
})
17 changes: 16 additions & 1 deletion __tests__/index.spec.ts
Expand Up @@ -15,8 +15,8 @@ import { File as FileSource } from '../lib/files/file'
import { Folder as FolderSource } from '../lib/files/folder'
import { Permission as PermissionSource } from '../lib/permissions'
import { FileType as FileTypeSource } from '../lib/files/fileType'

import { Entry, NewFileMenu } from '../lib/newFileMenu';
import { FileAction, registerFileAction, getFileActions } from '../lib/fileAction'

declare global {
interface Window {
Expand Down Expand Up @@ -75,6 +75,21 @@ describe('Exports checks', () => {
expect(Node).toBeTruthy()
expect(typeof Node).toBe('function')
})

test('FileAction', () => {
expect(FileAction).toBeTruthy()
expect(typeof FileAction).toBe('function')
})

test('registerFileAction', () => {
expect(registerFileAction).toBeTruthy()
expect(typeof Node).toBe('function')
})

test('getFileActions', () => {
expect(getFileActions).toBeTruthy()
expect(typeof Node).toBe('function')
})
})


Expand Down
65 changes: 46 additions & 19 deletions lib/fileAction.ts
Expand Up @@ -27,53 +27,84 @@ interface FileActionData {
/** Unique ID */
id: string
/** Translatable string displayed in the menu */
displayName: (files: Node[]) => string
displayName: (files: Node[], view) => string
/** Svg as inline string. <svg><path fill="..." /></svg> */
iconSvgInline: (files: Node[]) => string
iconSvgInline: (files: Node[], view) => string
/** Condition wether this action is shown or not */
enabled?: (files: Node[], view) => boolean
/**
* Function executed on single file action
* @returns true if the action was executed, false otherwise
* @throws Error if the action failed
*/
exec: (file: Node) => Promise<boolean>,
exec: (file: Node, view) => Promise<boolean>,
/**
* Function executed on multiple files action
* @returns true if the action was executed, false otherwise
* @throws Error if the action failed
*/
execBatch?: (files: Node[]) => Promise<boolean[]>
execBatch?: (files: Node[], view) => Promise<boolean[]>
/** This action order in the list */
order?: number,
/** Make this action the default */
default?: boolean,
/**
* If true, the renderInline function will be called
*/
inline?: (file: Node) => boolean,
inline?: (file: Node, view) => boolean,
/**
* If defined, the returned html element will be
* appended before the actions menu.
*/
renderInline?: (file: Node) => HTMLElement,
renderInline?: (file: Node, view) => HTMLElement,
}

// Allow class/interface merging and proxying
export interface FileAction extends FileActionData {}
export class FileAction {
private _action: FileActionData

constructor(action: FileActionData) {
this.validateAction(action)
this._action = action
}

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

get displayName() {
return this._action.displayName
}

get iconSvgInline() {
return this._action.iconSvgInline
}

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

get exec() {
return this._action.exec
}

// Forward any getter to action data
return new Proxy(this, {
get(target, property: string) {
return Reflect.get(target._action, property)
}
})
get execBatch() {
return this._action.execBatch
}

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

get default() {
return this._action.default
}

get inline() {
return this._action.inline
}

get renderInline() {
return this._action.renderInline
}

private validateAction(action: FileActionData) {
Expand All @@ -94,7 +125,7 @@ export class FileAction {
}

// Optional properties --------------------------------------------
if ('enabled' in action && typeof action.execBatch !== 'function') {
if ('enabled' in action && typeof action.enabled !== 'function') {
throw new Error('Invalid enabled function')
}

Expand All @@ -117,10 +148,6 @@ export class FileAction {
if ('renderInline' in action && typeof action.renderInline !== 'function') {
throw new Error('Invalid renderInline function')
}

if ('inline' in action && !('renderInline' in action)) {
throw new Error('renderInline is required when inline is defined')
}
}
}

Expand Down
1 change: 1 addition & 0 deletions lib/index.ts
Expand Up @@ -31,6 +31,7 @@ export { File } from './files/file'
export { Folder } from './files/folder'
export { Node } from './files/node'
export { Permission, parseWebdavPermissions } from './permissions'
export { FileAction, registerFileAction, getFileActions } from './fileAction'

declare global {
interface Window {
Expand Down

0 comments on commit ca1b66d

Please sign in to comment.