Merge pull request #50220 from nextcloud/fix/sidebar-favorites

fix(files): Ensure favorites set in sidebar work
This commit is contained in:
Ferdinand Thiessen 2025-01-21 18:58:51 +01:00 committed by GitHub
commit 9b2856affc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 176 additions and 17 deletions

View file

@ -149,6 +149,21 @@ export const useFilesStore = function(...args) {
// Otherwise, it means we receive an event for a node that is not in the store
fetchNode(node).then(n => this.updateNodes([n]))
},
// Handlers for legacy sidebar (no real nodes support)
onAddFavorite(node: Node) {
const ourNode = this.getNode(node.source)
if (ourNode) {
Vue.set(ourNode.attributes, 'favorite', 1)
}
},
onRemoveFavorite(node: Node) {
const ourNode = this.getNode(node.source)
if (ourNode) {
Vue.set(ourNode.attributes, 'favorite', 0)
}
},
},
})
@ -159,6 +174,9 @@ export const useFilesStore = function(...args) {
subscribe('files:node:deleted', fileStore.onDeletedNode)
subscribe('files:node:updated', fileStore.onUpdatedNode)
subscribe('files:node:moved', fileStore.onMovedNode)
// legacy sidebar
subscribe('files:favorites:added', fileStore.onAddFavorite)
subscribe('files:favorites:removed', fileStore.onRemoveFavorite)
fileStore._initialized = true
}

View file

@ -404,10 +404,10 @@ export default {
},
/**
* Toggle favourite state
* Toggle favorite state
* TODO: better implementation
*
* @param {boolean} state favourited or not
* @param {boolean} state is favorite or not
*/
async toggleStarred(state) {
try {
@ -430,17 +430,21 @@ export default {
*/
const isDir = this.fileInfo.type === 'dir'
const Node = isDir ? Folder : File
emit(state ? 'files:favorites:added' : 'files:favorites:removed', new Node({
const node = new Node({
fileid: this.fileInfo.id,
source: this.davPath,
root: `/files/${getCurrentUser().uid}`,
source: `${davRemoteURL}${davRootPath}${this.file}`,
root: davRootPath,
mime: isDir ? undefined : this.fileInfo.mimetype,
}))
attributes: {
favorite: 1,
},
})
emit(state ? 'files:favorites:added' : 'files:favorites:removed', node)
this.fileInfo.isFavourited = state
} catch (error) {
showError(t('files', 'Unable to change the favourite state of the file'))
logger.error('Unable to change favourite state', { error })
showError(t('files', 'Unable to change the favorite state of the file'))
logger.error('Unable to change favorite state', { error })
}
},

View file

@ -65,7 +65,7 @@ export const registerFavoritesView = async () => {
favoriteFoldersViews.forEach(view => Navigation.register(view))
/**
* Update favourites navigation when a new folder is added
* Update favorites navigation when a new folder is added
*/
subscribe('files:favorites:added', (node: Node) => {
if (node.type !== FileType.Folder) {
@ -99,7 +99,7 @@ export const registerFavoritesView = async () => {
})
/**
* Update favourites navigation when a folder is renamed
* Update favorites navigation when a folder is renamed
*/
subscribe('files:node:renamed', (node: Node) => {
if (node.type !== FileType.Folder) {

View file

@ -0,0 +1,137 @@
/*!
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import type { User } from '@nextcloud/cypress'
import { getActionButtonForFile, getRowForFile, triggerActionForFile } from './FilesUtils'
describe('files: Favorites', { testIsolation: true }, () => {
let user: User
beforeEach(() => {
cy.createRandomUser().then(($user) => {
user = $user
cy.uploadContent(user, new Blob([]), 'text/plain', '/file.txt')
cy.mkdir(user, '/new folder')
cy.login(user)
cy.visit('/apps/files')
})
})
it('Mark file as favorite', () => {
// See file exists
getRowForFile('file.txt')
.should('exist')
cy.intercept('POST', '**/apps/files/api/v1/files/file.txt').as('addToFavorites')
// Click actions
getActionButtonForFile('file.txt').click({ force: true })
// See action is called 'Add to favorites'
cy.get('[data-cy-files-list-row-action="favorite"] > button').last()
.should('exist')
.and('have.text', 'Add to favorites')
.click({ force: true })
cy.wait('@addToFavorites')
// See favorites star
getRowForFile('file.txt')
.findByRole('img', { name: 'Favorite' })
.should('exist')
})
it('Un-mark file as favorite', () => {
// See file exists
getRowForFile('file.txt')
.should('exist')
cy.intercept('POST', '**/apps/files/api/v1/files/file.txt').as('addToFavorites')
// toggle favorite
triggerActionForFile('file.txt', 'favorite')
cy.wait('@addToFavorites')
// See favorites star
getRowForFile('file.txt')
.findByRole('img', { name: 'Favorite' })
.should('be.visible')
// Remove favorite
// click action button
getActionButtonForFile('file.txt').click({ force: true })
// See action is called 'Remove from favorites'
cy.get('[data-cy-files-list-row-action="favorite"] > button').last()
.should('exist')
.and('have.text', 'Remove from favorites')
.click({ force: true })
cy.wait('@addToFavorites')
// See no favorites star anymore
getRowForFile('file.txt')
.findByRole('img', { name: 'Favorite' })
.should('not.exist')
})
it('See favorite folders in navigation', () => {
cy.intercept('POST', '**/apps/files/api/v1/files/new%20folder').as('addToFavorites')
// see navigation has no entry
cy.get('[data-cy-files-navigation-item="favorites"]')
.should('be.visible')
.contains('new folder')
.should('not.exist')
// toggle favorite
triggerActionForFile('new folder', 'favorite')
cy.wait('@addToFavorites')
// See in navigation
cy.get('[data-cy-files-navigation-item="favorites"]')
.should('be.visible')
.contains('new folder')
.should('exist')
// toggle favorite
triggerActionForFile('new folder', 'favorite')
cy.wait('@addToFavorites')
// See no longer in navigation
cy.get('[data-cy-files-navigation-item="favorites"]')
.should('be.visible')
.contains('new folder')
.should('not.exist')
})
it('Mark file as favorite using the sidebar', () => {
// See file exists
getRowForFile('new folder')
.should('exist')
// see navigation has no entry
cy.get('[data-cy-files-navigation-item="favorites"]')
.should('be.visible')
.contains('new folder')
.should('not.exist')
cy.intercept('PROPPATCH', '**/remote.php/dav/files/*/new%20folder').as('addToFavorites')
// open sidebar
triggerActionForFile('new folder', 'details')
// open actions
cy.get('[data-cy-sidebar]')
.findByRole('button', { name: 'Actions' })
.click()
// trigger menu button
cy.findAllByRole('menu')
.findByRole('menuitem', { name: 'Add to favorites' })
.should('be.visible')
.click()
cy.wait('@addToFavorites')
// See favorites star
getRowForFile('new folder')
.findByRole('img', { name: 'Favorite' })
.should('be.visible')
// See folder in navigation
cy.get('[data-cy-files-navigation-item="favorites"]')
.should('be.visible')
.contains('new folder')
.should('exist')
})
})

File diff suppressed because one or more lines are too long

4
dist/files-main.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long