diff --git a/apps/files/src/components/FileEntry/FileEntryActions.vue b/apps/files/src/components/FileEntry/FileEntryActions.vue index b562b445f7f..83cd475fcc3 100644 --- a/apps/files/src/components/FileEntry/FileEntryActions.vue +++ b/apps/files/src/components/FileEntry/FileEntryActions.vue @@ -42,12 +42,14 @@ :open.sync="openedMenu" @close="openedSubmenu = null"> - - {{ mountType === 'shared' && action.id === 'sharing-status' ? '' : actionDisplayName(action) }} + {{ actionDisplayName(action) }} @@ -251,10 +253,6 @@ export default defineComponent({ getBoundariesElement() { return document.querySelector('.app-content > .files-list') }, - - mountType() { - return this.source.attributes['mount-type'] - }, }, watch: { @@ -374,13 +372,19 @@ main.app-content[style*="mouse-pos-x"] .v-popper__popper { } - diff --git a/apps/files_sharing/src/actions/sharingStatusAction.scss b/apps/files_sharing/src/actions/sharingStatusAction.scss index 99fc8c88ad2..014ef450d6b 100644 --- a/apps/files_sharing/src/actions/sharingStatusAction.scss +++ b/apps/files_sharing/src/actions/sharingStatusAction.scss @@ -1,30 +1,14 @@ /** - * @copyright Copyright (c) 2023 John Molakvoæ - * - * @author John Molakvoæ - * - * @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 . - * + * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ + // Only when rendered inline, when not enough space, this is put in the menu -.action-items > .files-list__row-action-sharing-status { + .action-items > .files-list__row-action-sharing-status { // put icon at the end of the button direction: rtl; - // align icons with textless inline actions - padding-right: 0 !important; + // align icons with text-less inline actions + padding-inline-end: 0 !important; } svg.sharing-status__avatar { @@ -35,3 +19,12 @@ svg.sharing-status__avatar { border-radius: 32px; overflow: hidden; } + +.files-list__row-action-sharing-status { + .button-vue__text { + color: var(--color-primary-element); + } + .button-vue__icon { + color: var(--color-primary-element); + } +} diff --git a/cypress/e2e/files/FilesUtils.ts b/cypress/e2e/files/FilesUtils.ts index cb1982b36da..ade1bd88e94 100644 --- a/cypress/e2e/files/FilesUtils.ts +++ b/cypress/e2e/files/FilesUtils.ts @@ -42,7 +42,7 @@ export const getActionsForFile = (filename: string) => getRowForFile(filename).f export const getActionButtonForFileId = (fileid: number) => getActionsForFileId(fileid).findByRole('button', { name: 'Actions' }) export const getActionButtonForFile = (filename: string) => getActionsForFile(filename).findByRole('button', { name: 'Actions' }) -const searchForActionInRow = (row: JQuery, actionId: string): Cypress.Chainable> => { +const searchForActionInRow = (row: JQuery, actionId: string): Cypress.Chainable> => { const action = row.find(`[data-cy-files-list-row-action="${CSS.escape(actionId)}"]`) if (action.length > 0) { cy.log('Found action in row') diff --git a/cypress/e2e/files_sharing/share-status-action.cy.ts b/cypress/e2e/files_sharing/share-status-action.cy.ts new file mode 100644 index 00000000000..ca9724be15e --- /dev/null +++ b/cypress/e2e/files_sharing/share-status-action.cy.ts @@ -0,0 +1,128 @@ +/*! + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +import type { User } from '@nextcloud/cypress' +import { createShare } from './filesSharingUtils.ts' +import { closeSidebar, enableGridMode, getActionButtonForFile, getRowForFile } from '../files/FilesUtils.ts' + +describe('files_sharing: Sharing status action', { testIsolation: true }, () => { + /** + * Regression test of https://github.com/nextcloud/server/issues/45723 + */ + it('No "shared" tag when user ID is purely numerical but there are no shares', () => { + const user = { + language: 'en', + password: 'test1234', + userId: String(Math.floor(Math.random() * 1000)), + } as User + cy.createUser(user) + cy.mkdir(user, '/folder') + cy.login(user) + + cy.visit('/apps/files') + + getRowForFile('folder') + .should('be.visible') + .find('[data-cy-files-list-row-actions]') + .findByRole('button', { name: 'Shared' }) + .should('not.exist') + }) + + it('Render quick option for sharing', () => { + cy.createRandomUser().then((user) => { + cy.mkdir(user, '/folder') + cy.login(user) + + cy.visit('/apps/files') + }) + + getRowForFile('folder') + .should('be.visible') + .find('[data-cy-files-list-row-actions]') + .findByRole('button', { name: /Show sharing options/ }) + .should('be.visible') + .click() + + // check the click opened the sidebar + cy.get('[data-cy-sidebar]') + .should('be.visible') + // and ensure the sharing tab is selected + .findByRole('tab', { name: 'Sharing', selected: true }) + .should('exist') + }) + + describe('Sharing inline status action handling', () => { + let user: User + let sharee: User + + before(() => { + cy.createRandomUser().then(($user) => { + sharee = $user + }) + cy.createRandomUser().then(($user) => { + user = $user + cy.mkdir(user, '/folder') + cy.login(user) + + cy.visit('/apps/files') + getRowForFile('folder').should('be.visible') + + createShare('folder', sharee.userId) + closeSidebar() + }) + cy.logout() + }) + + it('Render inline status action for sharer', () => { + cy.login(user) + cy.visit('/apps/files') + + getRowForFile('folder') + .should('be.visible') + .find('[data-cy-files-list-row-actions]') + .findByRole('button', { name: /^Shared with/i }) + .should('be.visible') + }) + + it('Render status action in gridview for sharer', () => { + cy.login(user) + cy.visit('/apps/files') + enableGridMode() + + getRowForFile('folder') + .should('be.visible') + getActionButtonForFile('folder') + .click() + cy.findByRole('menu') + .findByRole('menuitem', { name: /shared with/i }) + .should('be.visible') + }) + + it('Render inline status action for sharee', () => { + cy.login(sharee) + cy.visit('/apps/files') + + getRowForFile('folder') + .should('be.visible') + .find('[data-cy-files-list-row-actions]') + .findByRole('button', { name: `Shared by ${user.userId}` }) + .should('be.visible') + }) + + it('Render status action in grid view for sharee', () => { + cy.login(sharee) + cy.visit('/apps/files') + + enableGridMode() + + getRowForFile('folder') + .should('be.visible') + getActionButtonForFile('folder') + .click() + cy.findByRole('menu') + .findByRole('menuitem', { name: `Shared by ${user.userId}` }) + .should('be.visible') + }) + }) +})