mirror of
https://github.com/nextcloud/server.git
synced 2026-06-13 18:50:47 -04:00
fix(files): Ensure favorites set in sidebar work
When marking a file as favorite from within the sidebar make sure it really works, this fixes two issues: 1. The source needs to be the plain source not URL encoded, as otherwise the source of the node would be encoded twice (and show with encoding in the navigation) 2. The store should also listen for the update events as the sidebar has no access to the real node to update it, instead the store should - as long as we only have the legacy sidebar - update the node when added or removed as favorite. Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
This commit is contained in:
parent
290d630cb7
commit
8d6139f17c
4 changed files with 170 additions and 11 deletions
|
|
@ -162,6 +162,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)
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
|
|
@ -172,6 +187,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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ import { getCurrentUser } from '@nextcloud/auth'
|
|||
import { getCapabilities } from '@nextcloud/capabilities'
|
||||
import { showError } from '@nextcloud/dialogs'
|
||||
import { emit, subscribe, unsubscribe } from '@nextcloud/event-bus'
|
||||
import { File, Folder, formatFileSize } from '@nextcloud/files'
|
||||
import { davRemoteURL, davRootPath, File, Folder, formatFileSize } from '@nextcloud/files'
|
||||
import { encodePath } from '@nextcloud/paths'
|
||||
import { generateRemoteUrl, generateUrl } from '@nextcloud/router'
|
||||
import { ShareType } from '@nextcloud/sharing'
|
||||
|
|
@ -375,10 +375,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 {
|
||||
|
|
@ -401,17 +401,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 })
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
137
cypress/e2e/files/favorites.cy.ts
Normal file
137
cypress/e2e/files/favorites.cy.ts
Normal 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')
|
||||
})
|
||||
})
|
||||
Loading…
Reference in a new issue