Skip to content

Commit 994b63d

Browse files
susnuxAndyScherzinger
authored andcommitted
fix(files_sharing): ensure share status action works also in grid view
Remove some hacks from files app about the *files_sharing* status action, in general not sure why this hack was there instead of being in the correct app - but it broke the grid view. So now the sharing information is also available in grid view. Moreover the icon is fixed in size to not overflow the actions menu. Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
1 parent ec4187c commit 994b63d

File tree

4 files changed

+161
-36
lines changed

4 files changed

+161
-36
lines changed

apps/files/src/components/FileEntry/FileEntryActions.vue

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,14 @@
4242
:open.sync="openedMenu"
4343
@close="openedSubmenu = null">
4444
<!-- Default actions list-->
45-
<NcActionButton v-for="action in enabledMenuActions"
45+
<NcActionButton v-for="action, index in enabledMenuActions"
4646
:key="action.id"
4747
:ref="`action-${action.id}`"
48+
class="files-list__row-action"
4849
:class="{
4950
[`files-list__row-action-${action.id}`]: true,
50-
[`files-list__row-action--menu`]: isMenu(action.id)
51+
'files-list__row-action--inline': index < enabledInlineActions.length,
52+
'files-list__row-action--menu': isMenu(action.id)
5153
}"
5254
:close-after-click="!isMenu(action.id)"
5355
:data-cy-files-list-row-action="action.id"
@@ -58,7 +60,7 @@
5860
<NcLoadingIcon v-if="loading === action.id" :size="18" />
5961
<NcIconSvgWrapper v-else :svg="action.iconSvgInline([source], currentView)" />
6062
</template>
61-
{{ mountType === 'shared' && action.id === 'sharing-status' ? '' : actionDisplayName(action) }}
63+
{{ actionDisplayName(action) }}
6264
</NcActionButton>
6365

6466
<!-- Submenu actions list-->
@@ -251,10 +253,6 @@ export default defineComponent({
251253
getBoundariesElement() {
252254
return document.querySelector('.app-content > .files-list')
253255
},
254-
255-
mountType() {
256-
return this.source.attributes['mount-type']
257-
},
258256
},
259257
260258
watch: {
@@ -374,13 +372,19 @@ main.app-content[style*="mouse-pos-x"] .v-popper__popper {
374372
}
375373
</style>
376374

377-
<style lang="scss" scoped>
378-
:deep(.button-vue--icon-and-text, .files-list__row-action-sharing-status) {
379-
.button-vue__text {
380-
color: var(--color-primary-element);
375+
<style scoped lang="scss">
376+
.files-list__row-action {
377+
--max-icon-size: calc(var(--default-clickable-area) - 2 * var(--default-grid-baseline));
378+
379+
// inline icons can have clickable area size so they still fit into the row
380+
&.files-list__row-action--inline {
381+
--max-icon-size: var(--default-clickable-area);
381382
}
382-
.button-vue__icon {
383-
color: var(--color-primary-element);
383+
384+
// Some icons exceed the default size so we need to enforce a max width and height
385+
.files-list__row-action-icon :deep(svg) {
386+
max-height: var(--max-icon-size) !important;
387+
max-width: var(--max-icon-size) !important;
384388
}
385389
}
386390
</style>
Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,14 @@
11
/**
2-
* @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com>
3-
*
4-
* @author John Molakvoæ <skjnldsv@protonmail.com>
5-
*
6-
* @license AGPL-3.0-or-later
7-
*
8-
* This program is free software: you can redistribute it and/or modify
9-
* it under the terms of the GNU Affero General Public License as
10-
* published by the Free Software Foundation, either version 3 of the
11-
* License, or (at your option) any later version.
12-
*
13-
* This program is distributed in the hope that it will be useful,
14-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16-
* GNU Affero General Public License for more details.
17-
*
18-
* You should have received a copy of the GNU Affero General Public License
19-
* along with this program. If not, see <http://www.gnu.org/licenses/>.
20-
*
2+
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
214
*/
5+
226
// Only when rendered inline, when not enough space, this is put in the menu
23-
.action-items > .files-list__row-action-sharing-status {
7+
.action-items > .files-list__row-action-sharing-status {
248
// put icon at the end of the button
259
direction: rtl;
26-
// align icons with textless inline actions
27-
padding-right: 0 !important;
10+
// align icons with text-less inline actions
11+
padding-inline-end: 0 !important;
2812
}
2913

3014
svg.sharing-status__avatar {
@@ -35,3 +19,12 @@ svg.sharing-status__avatar {
3519
border-radius: 32px;
3620
overflow: hidden;
3721
}
22+
23+
.files-list__row-action-sharing-status {
24+
.button-vue__text {
25+
color: var(--color-primary-element);
26+
}
27+
.button-vue__icon {
28+
color: var(--color-primary-element);
29+
}
30+
}

cypress/e2e/files/FilesUtils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export const getActionsForFile = (filename: string) => getRowForFile(filename).f
4242
export const getActionButtonForFileId = (fileid: number) => getActionsForFileId(fileid).findByRole('button', { name: 'Actions' })
4343
export const getActionButtonForFile = (filename: string) => getActionsForFile(filename).findByRole('button', { name: 'Actions' })
4444

45-
const searchForActionInRow = (row: JQuery<HTMLElement>, actionId: string): Cypress.Chainable<JQuery<HTMLElement>> => {
45+
const searchForActionInRow = (row: JQuery<HTMLElement>, actionId: string): Cypress.Chainable<JQuery<HTMLElement>> => {
4646
const action = row.find(`[data-cy-files-list-row-action="${CSS.escape(actionId)}"]`)
4747
if (action.length > 0) {
4848
cy.log('Found action in row')
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*!
2+
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
import type { User } from '@nextcloud/cypress'
6+
import { createShare } from './filesSharingUtils.ts'
7+
import { closeSidebar, enableGridMode, getActionButtonForFile, getRowForFile } from '../files/FilesUtils.ts'
8+
9+
describe('files_sharing: Sharing status action', { testIsolation: true }, () => {
10+
/**
11+
* Regression test of https://github.com/nextcloud/server/issues/45723
12+
*/
13+
it('No "shared" tag when user ID is purely numerical but there are no shares', () => {
14+
const user = {
15+
language: 'en',
16+
password: 'test1234',
17+
userId: String(Math.floor(Math.random() * 1000)),
18+
} as User
19+
cy.createUser(user)
20+
cy.mkdir(user, '/folder')
21+
cy.login(user)
22+
23+
cy.visit('/apps/files')
24+
25+
getRowForFile('folder')
26+
.should('be.visible')
27+
.find('[data-cy-files-list-row-actions]')
28+
.findByRole('button', { name: 'Shared' })
29+
.should('not.exist')
30+
})
31+
32+
it('Render quick option for sharing', () => {
33+
cy.createRandomUser().then((user) => {
34+
cy.mkdir(user, '/folder')
35+
cy.login(user)
36+
37+
cy.visit('/apps/files')
38+
})
39+
40+
getRowForFile('folder')
41+
.should('be.visible')
42+
.find('[data-cy-files-list-row-actions]')
43+
.findByRole('button', { name: /Show sharing options/ })
44+
.should('be.visible')
45+
.click()
46+
47+
// check the click opened the sidebar
48+
cy.get('[data-cy-sidebar]')
49+
.should('be.visible')
50+
// and ensure the sharing tab is selected
51+
.findByRole('tab', { name: 'Sharing', selected: true })
52+
.should('exist')
53+
})
54+
55+
describe('Sharing inline status action handling', () => {
56+
let user: User
57+
let sharee: User
58+
59+
before(() => {
60+
cy.createRandomUser().then(($user) => {
61+
sharee = $user
62+
})
63+
cy.createRandomUser().then(($user) => {
64+
user = $user
65+
cy.mkdir(user, '/folder')
66+
cy.login(user)
67+
68+
cy.visit('/apps/files')
69+
getRowForFile('folder').should('be.visible')
70+
71+
createShare('folder', sharee.userId)
72+
closeSidebar()
73+
})
74+
cy.logout()
75+
})
76+
77+
it('Render inline status action for sharer', () => {
78+
cy.login(user)
79+
cy.visit('/apps/files')
80+
81+
getRowForFile('folder')
82+
.should('be.visible')
83+
.find('[data-cy-files-list-row-actions]')
84+
.findByRole('button', { name: /^Shared with/i })
85+
.should('be.visible')
86+
})
87+
88+
it('Render status action in gridview for sharer', () => {
89+
cy.login(user)
90+
cy.visit('/apps/files')
91+
enableGridMode()
92+
93+
getRowForFile('folder')
94+
.should('be.visible')
95+
getActionButtonForFile('folder')
96+
.click()
97+
cy.findByRole('menu')
98+
.findByRole('menuitem', { name: /shared with/i })
99+
.should('be.visible')
100+
})
101+
102+
it('Render inline status action for sharee', () => {
103+
cy.login(sharee)
104+
cy.visit('/apps/files')
105+
106+
getRowForFile('folder')
107+
.should('be.visible')
108+
.find('[data-cy-files-list-row-actions]')
109+
.findByRole('button', { name: `Shared by ${user.userId}` })
110+
.should('be.visible')
111+
})
112+
113+
it('Render status action in grid view for sharee', () => {
114+
cy.login(sharee)
115+
cy.visit('/apps/files')
116+
117+
enableGridMode()
118+
119+
getRowForFile('folder')
120+
.should('be.visible')
121+
getActionButtonForFile('folder')
122+
.click()
123+
cy.findByRole('menu')
124+
.findByRole('menuitem', { name: `Shared by ${user.userId}` })
125+
.should('be.visible')
126+
})
127+
})
128+
})

0 commit comments

Comments
 (0)