Skip to content

Commit f6826f7

Browse files
authored
Merge pull request #4350 from nextcloud/bugfix/noid/close-sidebar
fix(Sidebar): Only close sidebar on v-click-outside for specific targets
2 parents 0f71a52 + 8b94750 commit f6826f7

14 files changed

Lines changed: 202 additions & 53 deletions

cypress/e2e/boardFeatures.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { randUser } from '../utils/index.js'
22
const user = randUser()
3+
const recipient = randUser()
34

45
describe('Board', function() {
56

67
before(function() {
78
cy.createUser(user)
9+
cy.createUser(recipient)
810
})
911

1012
beforeEach(function() {
@@ -21,7 +23,6 @@ describe('Board', function() {
2123
}).as('createBoardRequest')
2224

2325
// Click "Add board"
24-
cy.openLeftSidebar()
2526
cy.get('#app-navigation-vue .app-navigation__list .app-navigation-entry')
2627
.eq(3).find('a').first().click({ force: true })
2728

@@ -38,4 +39,18 @@ describe('Board', function() {
3839
cy.get('.app-navigation__list .app-navigation-entry__children .app-navigation-entry')
3940
.contains(board).should('be.visible')
4041
})
42+
43+
it('Shows and hides the navigation', () => {
44+
cy.get('#app-navigation-vue .app-navigation__list .app-navigation-entry')
45+
.contains('Upcoming cards')
46+
.should('be.visible')
47+
cy.openLeftSidebar()
48+
cy.get('#app-navigation-vue .app-navigation__list .app-navigation-entry')
49+
.contains('Upcoming cards')
50+
.should('not.be.visible')
51+
cy.openLeftSidebar()
52+
cy.get('#app-navigation-vue .app-navigation__list .app-navigation-entry')
53+
.contains('Upcoming cards')
54+
.should('be.visible')
55+
})
4156
})

cypress/e2e/cardFeatures.js

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,29 @@
11
import { randUser } from '../utils/index.js'
2-
const user = randUser()
2+
import { sampleBoard } from '../utils/sampleBoard'
33

4-
const testBoardData = {
5-
title: 'MyBoardTest',
6-
color: '00ff00',
7-
stacks: [
8-
{
9-
title: 'TestList',
10-
cards: [
11-
{
12-
title: 'Hello world',
13-
},
14-
],
15-
},
16-
],
17-
}
4+
const user = randUser()
5+
const boardData = sampleBoard()
186

197
describe('Card', function() {
8+
let boardId
209
before(function() {
2110
cy.createUser(user)
2211
cy.login(user)
2312
cy.createExampleBoard({
24-
user: user.userId,
25-
password: user.password,
26-
board: testBoardData,
13+
user,
14+
board: boardData,
15+
}).then((board) => {
16+
boardId = board.id
2717
})
2818
})
2919

3020
beforeEach(function() {
3121
cy.login(user)
32-
cy.visit('/apps/deck')
22+
cy.visit(`/apps/deck/#/board/${boardId}`)
3323
})
3424

3525
it('Can show card details modal', function() {
36-
cy.openLeftSidebar()
37-
cy.getNavigationEntry(testBoardData.title)
26+
cy.getNavigationEntry(boardData.title)
3827
.first().click({ force: true })
3928

4029
cy.get('.board .stack').eq(0).within(() => {
@@ -48,8 +37,7 @@ describe('Card', function() {
4837
it('Can add a card', function() {
4938
const newCardTitle = 'Write some cypress tests'
5039

51-
cy.openLeftSidebar()
52-
cy.getNavigationEntry(testBoardData.title)
40+
cy.getNavigationEntry(boardData.title)
5341
.first().click({ force: true })
5442

5543
cy.get('.board .stack').eq(0).within(() => {

cypress/e2e/deckDashboard.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ describe('Deck dashboard', function() {
2020
it('Can see the default "Personal Board" created for user by default', function() {
2121
const defaultBoard = 'Personal'
2222

23-
cy.openLeftSidebar()
2423
cy.get('.app-navigation-entry-wrapper[icon=icon-deck]')
2524
.find('ul.app-navigation-entry__children .app-navigation-entry:contains(' + defaultBoard + ')')
2625
.first()

cypress/e2e/sharingFeatures.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { randUser } from '../utils/index.js'
2+
import { sampleBoard } from '../utils/sampleBoard'
3+
const user = randUser()
4+
const recipient = randUser()
5+
6+
describe('Board', function() {
7+
before(function() {
8+
cy.createUser(user)
9+
cy.createUser(recipient)
10+
})
11+
12+
beforeEach(function() {
13+
cy.login(user)
14+
})
15+
16+
it('Share a board to a user', function() {
17+
const board = sampleBoard('Read only board')
18+
cy.createExampleBoard({ user, board }).then((board) => {
19+
const boardId = board.id
20+
cy.visit(`/apps/deck/#/board/${boardId}`)
21+
cy.get('.board-title').contains(board.title)
22+
23+
cy.shareBoardWithUi(recipient.userId)
24+
25+
cy.login(recipient)
26+
cy.visit(`/apps/deck/#/board/${boardId}`)
27+
cy.get('.board-title').contains(board.title)
28+
cy.get('.button-vue[aria-label*="Add card"]')
29+
.should('not.exist')
30+
})
31+
})
32+
33+
it('Share a board to a user as writable', function() {
34+
const board = sampleBoard('Editable board')
35+
cy.createExampleBoard({ user, board }).then((board) => {
36+
const boardId = board.id
37+
cy.visit(`/apps/deck/#/board/${boardId}`)
38+
cy.get('.board-title').contains(board.title)
39+
40+
cy.shareBoardWithUi(recipient.userId)
41+
cy.get(`[data-cy="acl-participant:${recipient.userId}"]`).find('[data-cy="action:permission-edit"]').click()
42+
43+
cy.login(recipient)
44+
cy.visit(`/apps/deck/#/board/${boardId}`)
45+
cy.get('.board-title').contains(board.title)
46+
cy.get('.button-vue[aria-label*="Add card"]')
47+
.first().click()
48+
})
49+
})
50+
})

cypress/e2e/stackFeatures.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ describe('Stack', function() {
1616
cy.createUser(user)
1717
cy.login(user)
1818
cy.createExampleBoard({
19-
user: user.userId,
20-
password: user.password,
19+
user,
2120
board: testBoardData,
2221
})
2322
})

cypress/support/commands.js

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,15 @@ Cypress.Commands.add('deckCreateList', ({ user, password }, title) => {
6363
cy.get('#stack-add form input[type=submit]').first().click()
6464
})
6565

66-
Cypress.Commands.add('createExampleBoard', ({ user, password, board }) => {
66+
Cypress.Commands.add('createExampleBoard', ({ user, board }) => {
67+
const auth = {
68+
user: user.userId,
69+
password: user.password,
70+
}
6771
cy.request({
6872
method: 'POST',
6973
url: `${Cypress.env('baseUrl')}/index.php/apps/deck/api/v1.0/boards`,
70-
auth: {
71-
user,
72-
password,
73-
},
74+
auth,
7475
body: { title: board.title, color: board.color ?? 'ff0000' },
7576
}).then((boardResponse) => {
7677
expect(boardResponse.status).to.eq(200)
@@ -80,10 +81,7 @@ Cypress.Commands.add('createExampleBoard', ({ user, password, board }) => {
8081
cy.request({
8182
method: 'POST',
8283
url: `${Cypress.env('baseUrl')}/index.php/apps/deck/api/v1.0/boards/${boardData.id}/stacks`,
83-
auth: {
84-
user,
85-
password,
86-
},
84+
auth,
8785
body: { title: stack.title, order: 0 },
8886
}).then((stackResponse) => {
8987
const stackData = stackResponse.body
@@ -92,15 +90,13 @@ Cypress.Commands.add('createExampleBoard', ({ user, password, board }) => {
9290
cy.request({
9391
method: 'POST',
9492
url: `${Cypress.env('baseUrl')}/index.php/apps/deck/api/v1.0/boards/${boardData.id}/stacks/${stackData.id}/cards`,
95-
auth: {
96-
user,
97-
password,
98-
},
93+
auth,
9994
body: { title: card.title },
10095
})
10196
}
10297
})
10398
}
99+
cy.wrap(boardData)
104100
})
105101
})
106102

@@ -109,3 +105,13 @@ Cypress.Commands.add('getNavigationEntry', (boardTitle) => {
109105
.find('ul.app-navigation-entry__children .app-navigation-entry:contains(' + boardTitle + ')')
110106
.find('a.app-navigation-entry-link')
111107
})
108+
109+
Cypress.Commands.add('shareBoardWithUi', (userId) => {
110+
cy.get('[aria-label="Open details"]').click()
111+
cy.get('.app-sidebar').should('be.visible')
112+
cy.get('.multiselect__input').type(`${userId}`)
113+
cy.get('.multiselect__content .multiselect__element').first().contains(userId)
114+
cy.get('.multiselect__input').type('{enter}')
115+
116+
cy.get('.shareWithList').contains(userId)
117+
})
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
6+
<meta name="viewport" content="width=device-width,initial-scale=1.0">
7+
<title>Components App</title>
8+
</head>
9+
<body>
10+
<div data-cy-root></div>
11+
</body>
12+
</html>

cypress/support/component.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// ***********************************************************
2+
// This example support/component.js is processed and
3+
// loaded automatically before your test files.
4+
//
5+
// This is a great place to put global configuration and
6+
// behavior that modifies Cypress.
7+
//
8+
// You can change the location of this file or turn off
9+
// automatically serving support files with the
10+
// 'supportFile' configuration option.
11+
//
12+
// You can read more here:
13+
// https://on.cypress.io/configuration
14+
// ***********************************************************
15+
16+
// Import commands.js using ES2015 syntax:
17+
import './commands'
18+
19+
// Alternatively you can use CommonJS syntax:
20+
// require('./commands')
21+
22+
import { mount } from 'cypress/vue2'
23+
24+
Cypress.Commands.add('mount', mount)
25+
26+
// Example use:
27+
// cy.mount(MyComponent)

cypress/utils/sampleBoard.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* @copyright Copyright (c) 2022 Julius Härtl <jus@bitgrid.net>
3+
*
4+
* @author Julius Härtl <jus@bitgrid.net>
5+
*
6+
* @license GNU AGPL version 3 or any later version
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+
*/
21+
22+
export const sampleBoard = (title = 'MyTestBoard') => {
23+
return {
24+
title: title,
25+
color: '00ff00',
26+
stacks: [
27+
{
28+
title: 'TestList',
29+
cards: [
30+
{
31+
title: 'Hello world',
32+
},
33+
],
34+
},
35+
],
36+
}
37+
}

src/components/Sidebar.vue

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,9 @@ export default {
3838
this.$router.push({ name: 'board' })
3939
},
4040
onClickOutside(e) {
41-
if (Array.from(document.querySelectorAll('.card')).some(node => node.contains(e.target))) {
42-
return
41+
if (e.target?.dataset?.clickClosesSidebar) {
42+
this.closeSidebar()
4343
}
44-
this.closeSidebar()
4544
},
4645
},
4746
}

0 commit comments

Comments
 (0)