Skip to content

Commit 24da851

Browse files
authored
Merge pull request #1027 from nextcloud-libraries/feat/file-list-filters
2 parents 35d001f + aeffba3 commit 24da851

File tree

9 files changed

+195
-69
lines changed

9 files changed

+195
-69
lines changed

.config/typedoc.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"$schema": "https://typedoc.org/schema.json",
3+
"entryPoints": ["../lib/index.ts"],
4+
"out": "../dist/doc",
5+
"basePath": "../lib",
6+
"plugin": [
7+
"typedoc-plugin-missing-exports"
8+
]
9+
}

REUSE.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ SPDX-PackageSupplier = "Nextcloud <info@nextcloud.com>"
66
SPDX-PackageDownloadLocation = "https://github.com/nextcloud-libraries/nextcloud-files"
77

88
[[annotations]]
9-
path = ["package-lock.json", "package.json", "tsconfig.json"]
9+
path = ["package-lock.json", "package.json", "tsconfig.json", ".config/typedoc.json"]
1010
precedence = "aggregate"
1111
SPDX-FileCopyrightText = "2019-2024 Nextcloud GmbH and Nextcloud contributors"
1212
SPDX-License-Identifier = "AGPL-3.0-or-later"

lib/fileListFilters.ts

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/*!
2+
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
6+
import { emit } from '@nextcloud/event-bus'
7+
import { TypedEventTarget } from 'typescript-event-target'
8+
import { INode } from './files/node'
9+
10+
/**
11+
* Active filters can provide one or more "chips" to show the currently active state.
12+
* Must at least provide a text representing the filters state and a callback to unset that state (disable this filter).
13+
*/
14+
export interface IFileListFilterChip {
15+
/**
16+
* Text of the chip
17+
*/
18+
text: string
19+
/**
20+
* Optional icon to be used on the chip (inline SVG as string)
21+
*/
22+
icon?: string
23+
/**
24+
* Handler to be called on click
25+
*/
26+
onclick: () => void
27+
}
28+
29+
/**
30+
* This event is emitted when the the filter value changed and the file list needs to be updated
31+
*/
32+
export interface FilterUpdateEvent extends CustomEvent<never> {
33+
type: 'update:filter'
34+
}
35+
36+
/**
37+
* This event is emitted when the the filter value changed and the file list needs to be updated
38+
*/
39+
export interface FilterUpdateChipsEvent extends CustomEvent<IFileListFilterChip[]> {
40+
type: 'update:chips'
41+
}
42+
43+
interface IFileListFilterEvents {
44+
[name: string]: CustomEvent,
45+
'update:filter': FilterUpdateEvent
46+
'update:chips' : FilterUpdateChipsEvent
47+
}
48+
49+
export interface IFileListFilter extends TypedEventTarget<IFileListFilterEvents> {
50+
51+
/**
52+
* Unique ID of this filter
53+
*/
54+
readonly id: string
55+
56+
/**
57+
* Order of the filter
58+
*
59+
* Use a low number to make this filter ordered in front.
60+
*/
61+
readonly order: number
62+
63+
/**
64+
* If the filter needs a visual element for settings it can provide a function to mount it.
65+
*/
66+
readonly mount?: (el: HTMLElement) => void
67+
68+
/**
69+
* Filter function to decide if a node is shown
70+
* @return The nodes to be shown
71+
*/
72+
filter(node: INode[]): INode[]
73+
}
74+
75+
export class FileListFilter extends TypedEventTarget<IFileListFilterEvents> implements IFileListFilter {
76+
77+
public id: string
78+
79+
public order: number
80+
81+
constructor(id: string, order: number = 100) {
82+
super()
83+
this.id = id
84+
this.order = order
85+
}
86+
87+
public filter(nodes: INode[]): INode[] {
88+
throw new Error('Not implemented')
89+
return nodes
90+
}
91+
92+
protected updateChips(chips: IFileListFilterChip[]) {
93+
this.dispatchTypedEvent('update:chips', new CustomEvent('update:chips', { detail: chips }) as FilterUpdateChipsEvent)
94+
}
95+
96+
protected filterUpdated() {
97+
this.dispatchTypedEvent('update:filter', new CustomEvent('update:filter') as FilterUpdateEvent)
98+
}
99+
100+
}
101+
102+
/**
103+
* Register a new filter on the file list
104+
*
105+
* This only must be called once to register the filter,
106+
* when the filter state changes you need to call `filterUpdated` on the filter instead.
107+
*
108+
* @param filter The filter to register on the file list
109+
*/
110+
export function registerFileListFilter(filter: IFileListFilter): void {
111+
if (!window._nc_filelist_filters) {
112+
window._nc_filelist_filters = new Map<string, IFileListFilter>()
113+
}
114+
if (window._nc_filelist_filters.has(filter.id)) {
115+
throw new Error(`File list filter "${filter.id}" already registered`)
116+
}
117+
window._nc_filelist_filters.set(filter.id, filter)
118+
emit('files:filter:added', filter)
119+
}
120+
121+
/**
122+
* Remove a registered filter from the file list
123+
* @param filterId The unique ID of the filter to remove
124+
*/
125+
export function unregisterFileListFilter(filterId: string): void {
126+
if (window._nc_filelist_filters && window._nc_filelist_filters.has(filterId)) {
127+
window._nc_filelist_filters.delete(filterId)
128+
emit('files:filter:removed', filterId)
129+
}
130+
}
131+
132+
/**
133+
* Get all registered file list filters
134+
*/
135+
export function getFileListFilters(): IFileListFilter[] {
136+
if (!window._nc_filelist_filters) {
137+
return []
138+
}
139+
return [...window._nc_filelist_filters.values()]
140+
}

lib/globals.d.ts

Lines changed: 0 additions & 16 deletions
This file was deleted.

lib/index.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,8 @@ export { formatFileSize, parseFileSize } from './utils/fileSize'
2626
export { orderBy, type SortingOrder } from './utils/sorting'
2727
export { sortNodes, FilesSortingMode, type FilesSortingOptions } from './utils/fileSorting'
2828

29-
export * from './navigation/navigation'
30-
export * from './navigation/column'
31-
export * from './navigation/view'
29+
export * from './navigation/index'
30+
export * from './fileListFilters'
3231

3332
/**
3433
* Add a new menu entry to the upload manager menu

lib/navigation/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/*!
2+
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
6+
export * from './navigation'
7+
export * from './column'
8+
export * from './view'

0 commit comments

Comments
 (0)