Skip to content

Commit

Permalink
feat: migrate Navigation from server
Browse files Browse the repository at this point in the history
Signed-off-by: John Molakvoæ <[email protected]>
  • Loading branch information
skjnldsv committed Aug 18, 2023
1 parent 848391c commit fcfe9a3
Show file tree
Hide file tree
Showing 10 changed files with 432 additions and 14 deletions.
15 changes: 8 additions & 7 deletions lib/fileAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,44 +21,45 @@
*/

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

interface FileActionData {
/** Unique ID */
id: string
/** Translatable string displayed in the menu */
displayName: (files: Node[], view) => string
displayName: (files: Node[], view: View) => string
/** Svg as inline string. <svg><path fill="..." /></svg> */
iconSvgInline: (files: Node[], view) => string
iconSvgInline: (files: Node[], view: View) => string
/** Condition wether this action is shown or not */
enabled?: (files: Node[], view) => boolean
enabled?: (files: Node[], view: View) => boolean
/**
* Function executed on single file action
* @return true if the action was executed successfully,
* false otherwise and null if the action is silent/undefined.
* @throws Error if the action failed
*/
exec: (file: Node, view, dir: string) => Promise<boolean|null>,
exec: (file: Node, view: View, dir: string) => Promise<boolean|null>,
/**
* Function executed on multiple files action
* @return true if the action was executed successfully,
* false otherwise and null if the action is silent/undefined.
* @throws Error if the action failed
*/
execBatch?: (files: Node[], view, dir: string) => Promise<(boolean|null)[]>
execBatch?: (files: Node[], view: View, dir: string) => Promise<(boolean|null)[]>
/** 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, view) => boolean,
inline?: (file: Node, view: View) => boolean,
/**
* If defined, the returned html element will be
* appended before the actions menu.
*/
renderInline?: (file: Node, view) => HTMLElement,
renderInline?: (file: Node, view: View) => HTMLElement,
}

export class FileAction {
Expand Down
7 changes: 4 additions & 3 deletions lib/fileListHeaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*/

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

export interface HeaderData {
Expand All @@ -29,11 +30,11 @@ export interface HeaderData {
/** Order */
order: number
/** Condition wether this header is shown or not */
enabled?: (folder: Folder, view) => boolean
enabled?: (folder: Folder, view: View) => boolean
/** Executed when file list is initialized */
render: (el: HTMLElement, folder: Folder, view) => void
render: (el: HTMLElement, folder: Folder, view: View) => void
/** Executed when root folder changed */
updated(folder: Folder, view)
updated(folder: Folder, view: View)
}

export class Header {
Expand Down
4 changes: 3 additions & 1 deletion lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ export { File } from './files/file'
export { Folder } from './files/folder'
export { Node } from './files/node'

// TODO: Add FileInfo type!
export * from './navigation/navigation'
export * from './navigation/column'
export * from './navigation/view'

/**
* Add a new menu entry to the upload manager menu
Expand Down
102 changes: 102 additions & 0 deletions lib/navigation/column.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/**
* @copyright Copyright (c) 2022 John Molakvoæ <[email protected]>
*
* @author John Molakvoæ <[email protected]>
*
* @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 { View } from './view'
import { Node } from '../files/node'

interface ColumnData {
/** Unique column ID */
id: string
/** Translated column title */
title: string
/** The content of the cell. The element will be appended within */
render: (node: Node, view: View) => HTMLElement
/** Function used to sort Nodes between them */
sort?: (nodeA: Node, nodeB: Node) => number
/**
* Custom summary of the column to display at the end of the list.
* Will not be displayed if nothing is provided
*/
summary?: (node: Node[], view: View) => string
}

export class Column implements ColumnData {

private _column: ColumnData

constructor(column: ColumnData) {
isValidColumn(column)
this._column = column
}

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

get title() {
return this._column.title
}

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

get sort() {
return this._column.sort
}

get summary() {
return this._column.summary
}

}

/**
* Typescript cannot validate an interface.
* Please keep in sync with the Column interface requirements.
*
* @param {ColumnData} column the column to check
* @return {boolean} true if the column is valid
*/
const isValidColumn = function(column: ColumnData): boolean {
if (!column.id || typeof column.id !== 'string') {
throw new Error('A column id is required')
}

if (!column.title || typeof column.title !== 'string') {
throw new Error('A column title is required')
}

if (!column.render || typeof column.render !== 'function') {
throw new Error('A render function is required')
}

// Optional properties
if (column.sort && typeof column.sort !== 'function') {
throw new Error('Column sortFunction must be a function')
}

if (column.summary && typeof column.summary !== 'function') {
throw new Error('Column summary must be a function')
}

return true
}
66 changes: 66 additions & 0 deletions lib/navigation/navigation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**
* @copyright Copyright (c) 2022 John Molakvoæ <[email protected]>
*
* @author John Molakvoæ <[email protected]>
*
* @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 { View } from './view'
import logger from '../utils/logger'

export class Navigation {

private _views: View[] = []
private _currentView: View | null = null

register(view: View) {
if (this._views.find(search => search.id === view.id)) {
throw new Error(`View id ${view.id} is already registered`)
}

this._views.push(view)
}

remove(id: string) {
const index = this._views.findIndex(view => view.id === id)
if (index !== -1) {
this._views.splice(index, 1)
}
}

get views(): View[] {
return this._views
}

setActive(view: View | null) {
this._currentView = view
}

get active(): View | null {
return this._currentView
}

}

export const getNavigation = function(): Navigation {
if (typeof window._nc_navigation === 'undefined') {
window._nc_navigation = new Navigation()
logger.debug('Navigation service initialized')
}

return window._nc_navigation
}
Loading

0 comments on commit fcfe9a3

Please sign in to comment.