Skip to content

Commit b04ede2

Browse files
committed
refactor(files): migrate favorite sidebar action to new Sidebar API
Signed-off-by: Ferdinand Thiessen <[email protected]>
1 parent ab35c11 commit b04ede2

File tree

6 files changed

+75
-18
lines changed

6 files changed

+75
-18
lines changed

apps/files/src/actions/favoriteAction.spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ describe('Favorite action execute tests', () => {
217217

218218
// Check node change propagation
219219
expect(file.attributes.favorite).toBe(1)
220-
expect(eventBus.emit).toBeCalledTimes(1)
220+
expect(eventBus.emit).toHaveBeenCalled()
221221
expect(eventBus.emit).toBeCalledWith('files:favorites:added', file)
222222
})
223223

@@ -251,7 +251,7 @@ describe('Favorite action execute tests', () => {
251251

252252
// Check node change propagation
253253
expect(file.attributes.favorite).toBe(0)
254-
expect(eventBus.emit).toBeCalledTimes(1)
254+
expect(eventBus.emit).toHaveBeenCalled()
255255
expect(eventBus.emit).toBeCalledWith('files:favorites:removed', file)
256256
})
257257

@@ -285,9 +285,9 @@ describe('Favorite action execute tests', () => {
285285

286286
// Check node change propagation
287287
expect(file.attributes.favorite).toBe(0)
288-
expect(eventBus.emit).toBeCalledTimes(2)
289-
expect(eventBus.emit).toHaveBeenNthCalledWith(1, 'files:node:deleted', file)
290-
expect(eventBus.emit).toHaveBeenNthCalledWith(2, 'files:favorites:removed', file)
288+
expect(eventBus.emit).toHaveBeenCalled()
289+
expect(eventBus.emit).toHaveBeenCalledWith('files:node:deleted', file)
290+
expect(eventBus.emit).toHaveBeenCalledWith('files:favorites:removed', file)
291291
})
292292

293293
test('Favorite does NOT triggers node removal if favorite view but NOT root dir', async () => {
@@ -320,7 +320,7 @@ describe('Favorite action execute tests', () => {
320320

321321
// Check node change propagation
322322
expect(file.attributes.favorite).toBe(0)
323-
expect(eventBus.emit).toBeCalledTimes(1)
323+
expect(eventBus.emit).toHaveBeenCalled()
324324
expect(eventBus.emit).toBeCalledWith('files:favorites:removed', file)
325325
})
326326

apps/files/src/actions/favoriteAction.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
/**
1+
/*
22
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
33
* SPDX-License-Identifier: AGPL-3.0-or-later
44
*/
5-
import type { Node, View } from '@nextcloud/files'
5+
6+
import type { INode, IView } from '@nextcloud/files'
67

78
import StarOutlineSvg from '@mdi/svg/svg/star-outline.svg?raw'
89
import StarSvg from '@mdi/svg/svg/star.svg?raw'
@@ -26,17 +27,18 @@ const queue = new PQueue({ concurrency: 5 })
2627
*
2728
* @param nodes - The nodes to check
2829
*/
29-
function shouldFavorite(nodes: Node[]): boolean {
30+
function shouldFavorite(nodes: INode[]): boolean {
3031
return nodes.some((node) => node.attributes.favorite !== 1)
3132
}
3233

3334
/**
35+
* Favorite or unfavorite a node
3436
*
35-
* @param node
36-
* @param view
37-
* @param willFavorite
37+
* @param node - The node to favorite/unfavorite
38+
* @param view - The current view
39+
* @param willFavorite - Whether to favorite or unfavorite the node
3840
*/
39-
export async function favoriteNode(node: Node, view: View, willFavorite: boolean): Promise<boolean> {
41+
export async function favoriteNode(node: INode, view: IView, willFavorite: boolean): Promise<boolean> {
4042
try {
4143
// TODO: migrate to webdav tags plugin
4244
const url = generateUrl('/apps/files/api/v1/files') + encodePath(node.path)
@@ -55,6 +57,7 @@ export async function favoriteNode(node: Node, view: View, willFavorite: boolean
5557

5658
// Update the node webdav attribute
5759
Vue.set(node.attributes, 'favorite', willFavorite ? 1 : 0)
60+
emit('files:node:updated', node)
5861

5962
// Dispatch event to whoever is interested
6063
if (willFavorite) {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
6+
import starOutlineSvg from '@mdi/svg/svg/star-outline.svg?raw'
7+
import starSvg from '@mdi/svg/svg/star.svg?raw'
8+
import { registerSidebarAction } from '@nextcloud/files'
9+
import { t } from '@nextcloud/l10n'
10+
import { favoriteNode } from './favoriteAction.ts'
11+
12+
/**
13+
* Register the favorite/unfavorite action in the sidebar
14+
*/
15+
export function registerSidebarFavoriteAction() {
16+
registerSidebarAction({
17+
id: 'files-favorite',
18+
order: 0,
19+
20+
enabled({ node }) {
21+
return node.isDavResource && node.root.startsWith('/files/')
22+
},
23+
24+
displayName({ node }) {
25+
if (node.attributes.favorite) {
26+
return t('files', 'Unfavorite')
27+
}
28+
return t('files', 'Favorite')
29+
},
30+
31+
iconSvgInline({ node }) {
32+
if (node.attributes.favorite) {
33+
return starSvg
34+
}
35+
return starOutlineSvg
36+
},
37+
38+
onClick({ node, view }) {
39+
favoriteNode(node, view, !node.attributes.favorite)
40+
},
41+
})
42+
}

apps/files/src/init.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { action as openInFilesAction } from './actions/openInFilesAction.ts'
1616
import { action as editLocallyAction } from './actions/openLocallyAction.ts'
1717
import { action as renameAction } from './actions/renameAction.ts'
1818
import { action as sidebarAction } from './actions/sidebarAction.ts'
19+
import { registerSidebarFavoriteAction } from './actions/sidebarFavoriteAction.ts'
1920
import { action as viewInFolderAction } from './actions/viewInFolderAction.ts'
2021
import { registerFilenameFilter } from './filters/FilenameFilter.ts'
2122
import { registerHiddenFilesFilter } from './filters/HiddenFilesFilter.ts'
@@ -69,6 +70,9 @@ registerModifiedFilter()
6970
registerFilenameFilter()
7071
registerFilterToSearchToggle()
7172

73+
// Register sidebar action
74+
registerSidebarFavoriteAction()
75+
7276
// Register preview service worker
7377
registerPreviewServiceWorker()
7478

apps/files/src/views/favorites.spec.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,9 @@ describe('Favorites view definition', () => {
130130

131131
describe('Dynamic update of favorite folders', () => {
132132
let Navigation
133+
133134
beforeEach(() => {
134135
vi.restoreAllMocks()
135-
136136
delete window._nc_navigation
137137
Navigation = getNavigation()
138138
})
@@ -167,8 +167,9 @@ describe('Dynamic update of favorite folders', () => {
167167
contents: [],
168168
})
169169

170-
expect(eventBus.emit).toHaveBeenCalledTimes(1)
170+
expect(eventBus.emit).toHaveBeenCalledTimes(2)
171171
expect(eventBus.emit).toHaveBeenCalledWith('files:favorites:added', folder)
172+
expect(eventBus.emit).toHaveBeenCalledWith('files:node:updated', folder)
172173
})
173174

174175
test('Remove a favorite folder remove the entry from the navigation column', async () => {
@@ -213,8 +214,9 @@ describe('Dynamic update of favorite folders', () => {
213214
contents: [],
214215
})
215216

216-
expect(eventBus.emit).toHaveBeenCalledTimes(1)
217+
expect(eventBus.emit).toHaveBeenCalledTimes(2)
217218
expect(eventBus.emit).toHaveBeenCalledWith('files:favorites:removed', folder)
219+
expect(eventBus.emit).toHaveBeenCalledWith('files:node:updated', folder)
218220
expect(fo).toHaveBeenCalled()
219221

220222
favoritesView = Navigation.views.find((view) => view.id === 'favorites')
@@ -257,7 +259,8 @@ describe('Dynamic update of favorite folders', () => {
257259
folder: {} as NcFolder,
258260
contents: [],
259261
})
260-
expect(eventBus.emit).toHaveBeenNthCalledWith(1, 'files:favorites:added', folder)
262+
expect(eventBus.emit).toHaveBeenCalledWith('files:favorites:added', folder)
263+
expect(eventBus.emit).toHaveBeenCalledWith('files:node:updated', folder)
261264

262265
// Create a folder with the same id but renamed
263266
const renamedFolder = new Folder({
@@ -269,6 +272,6 @@ describe('Dynamic update of favorite folders', () => {
269272

270273
// Exec the rename action
271274
eventBus.emit('files:node:renamed', renamedFolder)
272-
expect(eventBus.emit).toHaveBeenNthCalledWith(2, 'files:node:renamed', renamedFolder)
275+
expect(eventBus.emit).toHaveBeenCalledWith('files:node:renamed', renamedFolder)
273276
})
274277
})

apps/files_sharing/src/views/FilesSidebarTab.vue

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
<!--
2+
- SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
3+
- SPDX-License-Identifier: AGPL-3.0-or-later
4+
-->
5+
16
<script setup lang="ts">
27
import type { IFolder, INode, IView } from '@nextcloud/files'
38

0 commit comments

Comments
 (0)