Skip to content

Commit

Permalink
feat: Allow registering actions for a view
Browse files Browse the repository at this point in the history
Signed-off-by: Christopher Ng <[email protected]>
  • Loading branch information
Pytal committed Oct 15, 2024
1 parent 18614e6 commit 59955fd
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 3 deletions.
1 change: 1 addition & 0 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { type Entry, getNewFileMenu } from './newFileMenu'
import { type Folder } from './files/folder'

export { FileAction, getFileActions, registerFileAction, DefaultType } from './fileAction'
export { ViewAction } from './viewAction.ts'
export { Header, getFileListHeaders, registerFileListHeaders } from './fileListHeaders'
export { type Entry, NewMenuEntryCategory } from './newFileMenu'
export { Permission } from './permissions'
Expand Down
23 changes: 20 additions & 3 deletions lib/navigation/view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import type { Folder } from '../files/folder'
import type { Node } from '../files/node'

import type { Folder } from '../files/folder.ts'
import type { Node } from '../files/node.ts'
import isSvg from 'is-svg'

import { Column } from './column.js'
import { Column } from './column.ts'
import { ViewAction } from '../viewAction.ts'

export type ContentsWithRoot = {
folder: Folder,
Expand Down Expand Up @@ -80,6 +82,11 @@ interface ViewData {
*/
// eslint-disable-next-line no-use-before-define
loadChildViews?: (view: View) => Promise<void>

/**
* The view actions.
*/
actions?: ViewAction[],
}

export class View implements ViewData {
Expand Down Expand Up @@ -171,6 +178,10 @@ export class View implements ViewData {
return this._view.loadChildViews
}

get actions() {
return this._view.actions

Check warning on line 182 in lib/navigation/view.ts

View check run for this annotation

Codecov / codecov/patch

lib/navigation/view.ts#L182

Added line #L182 was not covered by tests
}

}

/**
Expand Down Expand Up @@ -240,5 +251,11 @@ const isValidView = function(view: ViewData): boolean {
throw new Error('View loadChildViews must be a function')
}

if (view.actions) {
if (!view.actions.every((action) => action instanceof ViewAction)) {
throw new Error('View actions must be an array of ViewAction. Invalid action found.')

Check warning on line 256 in lib/navigation/view.ts

View check run for this annotation

Codecov / codecov/patch

lib/navigation/view.ts#L256

Added line #L256 was not covered by tests
}
}

return true
}
99 changes: 99 additions & 0 deletions lib/viewAction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import { Node } from './files/node.ts'
import { View } from './navigation/view.ts'

export interface ViewActionData {
/** Unique ID */
id: string

/** Translated name of the action */
displayName: (view: View) => string

/** Translated title of the action */
title?: (view: View) => string

/** Raw svg string */
iconSvgInline: (view: View) => string

/** Returns true if this action shoud be shown */
show?: (view: View, nodes: Node[]) => boolean

/** Returns true if the action should be disabled */
disabled?: (view: View, nodes: Node[]) => boolean

/** Function to execute */
exec: (view: View, nodes: Node[]) => Promise<void>,
}

export class ViewAction {

private _action: ViewActionData

constructor(action: ViewActionData) {
this.validateAction(action)
this._action = action

Check warning on line 38 in lib/viewAction.ts

View check run for this annotation

Codecov / codecov/patch

lib/viewAction.ts#L37-L38

Added lines #L37 - L38 were not covered by tests
}

get id() {
return this._action.id

Check warning on line 42 in lib/viewAction.ts

View check run for this annotation

Codecov / codecov/patch

lib/viewAction.ts#L42

Added line #L42 was not covered by tests
}

get displayName() {
return this._action.displayName

Check warning on line 46 in lib/viewAction.ts

View check run for this annotation

Codecov / codecov/patch

lib/viewAction.ts#L46

Added line #L46 was not covered by tests
}

get title() {
return this._action.title

Check warning on line 50 in lib/viewAction.ts

View check run for this annotation

Codecov / codecov/patch

lib/viewAction.ts#L50

Added line #L50 was not covered by tests
}

get iconSvgInline() {
return this._action.iconSvgInline

Check warning on line 54 in lib/viewAction.ts

View check run for this annotation

Codecov / codecov/patch

lib/viewAction.ts#L54

Added line #L54 was not covered by tests
}

get show() {
return this._action.show

Check warning on line 58 in lib/viewAction.ts

View check run for this annotation

Codecov / codecov/patch

lib/viewAction.ts#L58

Added line #L58 was not covered by tests
}

get disabled() {
return this._action.disabled

Check warning on line 62 in lib/viewAction.ts

View check run for this annotation

Codecov / codecov/patch

lib/viewAction.ts#L62

Added line #L62 was not covered by tests
}

get exec() {
return this._action.exec

Check warning on line 66 in lib/viewAction.ts

View check run for this annotation

Codecov / codecov/patch

lib/viewAction.ts#L66

Added line #L66 was not covered by tests
}

private validateAction(action: ViewActionData) {
if (!action.id || typeof action.id !== 'string') {
throw new Error('Invalid id')

Check warning on line 71 in lib/viewAction.ts

View check run for this annotation

Codecov / codecov/patch

lib/viewAction.ts#L71

Added line #L71 was not covered by tests
}

if (!action.displayName || typeof action.displayName !== 'function') {
throw new Error('Invalid displayName function')

Check warning on line 75 in lib/viewAction.ts

View check run for this annotation

Codecov / codecov/patch

lib/viewAction.ts#L75

Added line #L75 was not covered by tests
}

if ('title' in action && typeof action.title !== 'function') {
throw new Error('Invalid title function')

Check warning on line 79 in lib/viewAction.ts

View check run for this annotation

Codecov / codecov/patch

lib/viewAction.ts#L79

Added line #L79 was not covered by tests
}

if (!action.iconSvgInline || typeof action.iconSvgInline !== 'function') {
throw new Error('Invalid iconSvgInline function')

Check warning on line 83 in lib/viewAction.ts

View check run for this annotation

Codecov / codecov/patch

lib/viewAction.ts#L83

Added line #L83 was not covered by tests
}

if ('show' in action && typeof action.show !== 'function') {
throw new Error('Invalid show function')

Check warning on line 87 in lib/viewAction.ts

View check run for this annotation

Codecov / codecov/patch

lib/viewAction.ts#L87

Added line #L87 was not covered by tests
}

if ('disabled' in action && typeof action.disabled !== 'function') {
throw new Error('Invalid disabled function')

Check warning on line 91 in lib/viewAction.ts

View check run for this annotation

Codecov / codecov/patch

lib/viewAction.ts#L91

Added line #L91 was not covered by tests
}

if (!action.exec || typeof action.exec !== 'function') {
throw new Error('Invalid exec function')

Check warning on line 95 in lib/viewAction.ts

View check run for this annotation

Codecov / codecov/patch

lib/viewAction.ts#L95

Added line #L95 was not covered by tests
}
}

}

0 comments on commit 59955fd

Please sign in to comment.