cozy-viewer 28.1.2 → 28.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/dist/Panel/Sharing.js +13 -6
- package/dist/Panel/Sharing.spec.d.ts +1 -0
- package/package.json +4 -4
- package/src/Panel/Sharing.jsx +17 -7
- package/src/Panel/Sharing.spec.jsx +170 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,16 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [28.1.4](https://github.com/cozy/cozy-libs/compare/cozy-viewer@28.1.3...cozy-viewer@28.1.4) (2026-06-10)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- **cozy-viewer:** Show shared drive recipients in panel ([f58d29a](https://github.com/cozy/cozy-libs/commit/f58d29ad4a5ed3c7ef98b5cc95a6694f631d86d9))
|
|
11
|
+
|
|
12
|
+
## [28.1.3](https://github.com/cozy/cozy-libs/compare/cozy-viewer@28.1.2...cozy-viewer@28.1.3) (2026-06-10)
|
|
13
|
+
|
|
14
|
+
**Note:** Version bump only for package cozy-viewer
|
|
15
|
+
|
|
6
16
|
## [28.1.2](https://github.com/cozy/cozy-libs/compare/cozy-viewer@28.1.1...cozy-viewer@28.1.2) (2026-06-09)
|
|
7
17
|
|
|
8
18
|
**Note:** Version bump only for package cozy-viewer
|
package/dist/Panel/Sharing.js
CHANGED
|
@@ -11,6 +11,8 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
|
11
11
|
|
|
12
12
|
var _react = _interopRequireDefault(require("react"));
|
|
13
13
|
|
|
14
|
+
var _cozyClient = require("cozy-client");
|
|
15
|
+
|
|
14
16
|
var _cozyFlags = _interopRequireDefault(require("cozy-flags"));
|
|
15
17
|
|
|
16
18
|
var _cozySharing = require("cozy-sharing");
|
|
@@ -38,22 +40,27 @@ var _ShareModalProvider = require("../providers/ShareModalProvider");
|
|
|
38
40
|
var Sharing = function Sharing(_ref) {
|
|
39
41
|
var file = _ref.file,
|
|
40
42
|
t = _ref.t;
|
|
43
|
+
var client = (0, _cozyClient.useClient)();
|
|
41
44
|
|
|
42
45
|
var _useShareModal = (0, _ShareModalProvider.useShareModal)(),
|
|
43
46
|
setShowShareModal = _useShareModal.setShowShareModal;
|
|
44
47
|
|
|
45
48
|
var _useSharingContext = (0, _cozySharing.useSharingContext)(),
|
|
46
|
-
isOwner = _useSharingContext.isOwner,
|
|
47
49
|
getDocumentPermissions = _useSharingContext.getDocumentPermissions,
|
|
50
|
+
getSharingById = _useSharingContext.getSharingById,
|
|
48
51
|
getSharingLink = _useSharingContext.getSharingLink,
|
|
49
52
|
allLoaded = _useSharingContext.allLoaded,
|
|
50
|
-
getRecipients = _useSharingContext.getRecipients
|
|
53
|
+
getRecipients = _useSharingContext.getRecipients,
|
|
54
|
+
isOwner = _useSharingContext.isOwner;
|
|
51
55
|
|
|
52
|
-
var
|
|
56
|
+
var sharedDriveSharing = file.driveId ? getSharingById(file.driveId) : null;
|
|
57
|
+
var recipients = sharedDriveSharing ? (0, _cozySharing.getRecipientsFromSharing)(sharedDriveSharing, file._id) : getRecipients(file._id);
|
|
53
58
|
var permissions = getDocumentPermissions(file._id);
|
|
54
59
|
var link = getSharingLink(file._id);
|
|
55
|
-
|
|
56
|
-
|
|
60
|
+
var owner = recipients.find(function (recipient) {
|
|
61
|
+
return recipient.status === 'owner';
|
|
62
|
+
});
|
|
63
|
+
var isCurrentUserOwner = file.driveId ? (owner === null || owner === void 0 ? void 0 : owner.instance) === client.options.uri : isOwner(file._id);
|
|
57
64
|
|
|
58
65
|
var showModal = function showModal() {
|
|
59
66
|
if (!(0, _cozyFlags.default)('drive.new-file-viewer-ui.enabled')) {
|
|
@@ -84,7 +91,7 @@ var Sharing = function Sharing(_ref) {
|
|
|
84
91
|
return /*#__PURE__*/_react.default.createElement(_cozySharing.MemberRecipientLite, {
|
|
85
92
|
key: recipient.index,
|
|
86
93
|
recipient: recipient,
|
|
87
|
-
isOwner:
|
|
94
|
+
isOwner: isCurrentUserOwner
|
|
88
95
|
});
|
|
89
96
|
}) : /*#__PURE__*/_react.default.createElement(_cozySharing.OwnerRecipientDefaultLite, null), (0, _cozyFlags.default)('drive.new-file-viewer-ui.enabled') && /*#__PURE__*/_react.default.createElement(_ListItem.default, null, /*#__PURE__*/_react.default.createElement(_Buttons.default, {
|
|
90
97
|
variant: "secondary",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cozy-viewer",
|
|
3
|
-
"version": "28.1.
|
|
3
|
+
"version": "28.1.4",
|
|
4
4
|
"description": "Cozy-Viewer provides a component to show files in a viewer.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,10 +31,10 @@
|
|
|
31
31
|
"babel-preset-cozy-app": "^2.8.4",
|
|
32
32
|
"cozy-client": "^60.20.0",
|
|
33
33
|
"cozy-device-helper": "2.0.0",
|
|
34
|
-
"cozy-harvest-lib": "^37.0.
|
|
34
|
+
"cozy-harvest-lib": "^37.0.36",
|
|
35
35
|
"cozy-intent": "^2.31.1",
|
|
36
36
|
"cozy-logger": "^1.18.1",
|
|
37
|
-
"cozy-sharing": "^33.
|
|
37
|
+
"cozy-sharing": "^33.3.0",
|
|
38
38
|
"cozy-ui": "^138.1.0",
|
|
39
39
|
"cozy-ui-plus": "^8.0.1",
|
|
40
40
|
"identity-obj-proxy": "3.0.0",
|
|
@@ -71,5 +71,5 @@
|
|
|
71
71
|
"react-router-dom": ">=6.14.2",
|
|
72
72
|
"twake-i18n": ">=0.3.0"
|
|
73
73
|
},
|
|
74
|
-
"gitHead": "
|
|
74
|
+
"gitHead": "4fe0199d7042ff150315bd4a097256b2364f200c"
|
|
75
75
|
}
|
package/src/Panel/Sharing.jsx
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import PropTypes from 'prop-types'
|
|
2
2
|
import React from 'react'
|
|
3
3
|
|
|
4
|
+
import { useClient } from 'cozy-client'
|
|
4
5
|
import flag from 'cozy-flags'
|
|
5
6
|
import {
|
|
6
|
-
|
|
7
|
+
getRecipientsFromSharing,
|
|
8
|
+
LinkRecipientLite,
|
|
7
9
|
MemberRecipientLite,
|
|
8
10
|
OwnerRecipientDefaultLite,
|
|
9
|
-
|
|
11
|
+
useSharingContext
|
|
10
12
|
} from 'cozy-sharing'
|
|
11
13
|
import Button from 'cozy-ui/transpiled/react/Buttons'
|
|
12
14
|
import Icon from 'cozy-ui/transpiled/react/Icon'
|
|
@@ -21,19 +23,27 @@ import { withViewerLocales } from '../hoc/withViewerLocales'
|
|
|
21
23
|
import { useShareModal } from '../providers/ShareModalProvider'
|
|
22
24
|
|
|
23
25
|
const Sharing = ({ file, t }) => {
|
|
26
|
+
const client = useClient()
|
|
24
27
|
const { setShowShareModal } = useShareModal()
|
|
25
28
|
const {
|
|
26
|
-
isOwner,
|
|
27
29
|
getDocumentPermissions,
|
|
30
|
+
getSharingById,
|
|
28
31
|
getSharingLink,
|
|
29
32
|
allLoaded,
|
|
30
|
-
getRecipients
|
|
33
|
+
getRecipients,
|
|
34
|
+
isOwner
|
|
31
35
|
} = useSharingContext()
|
|
32
36
|
|
|
33
|
-
const
|
|
37
|
+
const sharedDriveSharing = file.driveId ? getSharingById(file.driveId) : null
|
|
38
|
+
const recipients = sharedDriveSharing
|
|
39
|
+
? getRecipientsFromSharing(sharedDriveSharing, file._id)
|
|
40
|
+
: getRecipients(file._id)
|
|
34
41
|
const permissions = getDocumentPermissions(file._id)
|
|
35
42
|
const link = getSharingLink(file._id)
|
|
36
|
-
const
|
|
43
|
+
const owner = recipients.find(recipient => recipient.status === 'owner')
|
|
44
|
+
const isCurrentUserOwner = file.driveId
|
|
45
|
+
? owner?.instance === client.options.uri
|
|
46
|
+
: isOwner(file._id)
|
|
37
47
|
|
|
38
48
|
const showModal = () => {
|
|
39
49
|
if (!flag('drive.new-file-viewer-ui.enabled')) {
|
|
@@ -71,7 +81,7 @@ const Sharing = ({ file, t }) => {
|
|
|
71
81
|
<MemberRecipientLite
|
|
72
82
|
key={recipient.index}
|
|
73
83
|
recipient={recipient}
|
|
74
|
-
isOwner={
|
|
84
|
+
isOwner={isCurrentUserOwner}
|
|
75
85
|
/>
|
|
76
86
|
))
|
|
77
87
|
) : (
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { render } from '@testing-library/react'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
|
|
4
|
+
import Sharing from './Sharing'
|
|
5
|
+
|
|
6
|
+
const mockGetRecipientsFromSharing = jest.fn()
|
|
7
|
+
const mockUseClient = jest.fn()
|
|
8
|
+
const mockUseShareModal = jest.fn()
|
|
9
|
+
const mockUseSharingContext = jest.fn()
|
|
10
|
+
const mockMemberRecipientLite = jest.fn(({ recipient, isOwner }) => (
|
|
11
|
+
<div data-testid="member-recipient" data-is-owner={String(isOwner)}>
|
|
12
|
+
{recipient.name}
|
|
13
|
+
</div>
|
|
14
|
+
))
|
|
15
|
+
|
|
16
|
+
jest.mock('cozy-client', () => ({
|
|
17
|
+
useClient: () => mockUseClient()
|
|
18
|
+
}))
|
|
19
|
+
|
|
20
|
+
jest.mock('cozy-flags', () => jest.fn(() => false))
|
|
21
|
+
jest.mock('cozy-sharing', () => ({
|
|
22
|
+
getRecipientsFromSharing: (...args) => mockGetRecipientsFromSharing(...args),
|
|
23
|
+
LinkRecipientLite: () => <div data-testid="link-recipient" />,
|
|
24
|
+
MemberRecipientLite: props => mockMemberRecipientLite(props),
|
|
25
|
+
OwnerRecipientDefaultLite: () => (
|
|
26
|
+
<div data-testid="owner-recipient-default" />
|
|
27
|
+
),
|
|
28
|
+
useSharingContext: () => mockUseSharingContext()
|
|
29
|
+
}))
|
|
30
|
+
|
|
31
|
+
jest.mock('../hoc/withViewerLocales', () => ({
|
|
32
|
+
withViewerLocales: Component => props => (
|
|
33
|
+
<Component {...props} t={key => key} />
|
|
34
|
+
)
|
|
35
|
+
}))
|
|
36
|
+
|
|
37
|
+
jest.mock('../providers/ShareModalProvider', () => ({
|
|
38
|
+
useShareModal: () => mockUseShareModal()
|
|
39
|
+
}))
|
|
40
|
+
|
|
41
|
+
const file = { _id: 'file-id' }
|
|
42
|
+
const sharedFile = { _id: 'shared-file-id' }
|
|
43
|
+
const sharedDriveFile = { _id: 'file-id', driveId: 'drive-id' }
|
|
44
|
+
const ownerRecipient = {
|
|
45
|
+
index: 'recipient-0',
|
|
46
|
+
name: 'Alice',
|
|
47
|
+
status: 'owner',
|
|
48
|
+
instance: 'http://alice.localhost:8080/'
|
|
49
|
+
}
|
|
50
|
+
const expectedOwnerRecipient = {
|
|
51
|
+
name: ownerRecipient.name,
|
|
52
|
+
status: ownerRecipient.status,
|
|
53
|
+
instance: ownerRecipient.instance
|
|
54
|
+
}
|
|
55
|
+
const sharedDriveSharing = {
|
|
56
|
+
id: 'drive-id',
|
|
57
|
+
attributes: {
|
|
58
|
+
drive: true,
|
|
59
|
+
members: [ownerRecipient]
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const setup = ({
|
|
64
|
+
clientUri = 'http://bob.localhost:8080/',
|
|
65
|
+
targetFile = file,
|
|
66
|
+
userIsOwner = true
|
|
67
|
+
} = {}) => {
|
|
68
|
+
const getDocumentPermissions = jest
|
|
69
|
+
.fn()
|
|
70
|
+
.mockImplementation(docId => (docId === 'file-id' ? ['perm'] : []))
|
|
71
|
+
const getSharingById = jest
|
|
72
|
+
.fn()
|
|
73
|
+
.mockImplementation(id => (id === 'drive-id' ? sharedDriveSharing : null))
|
|
74
|
+
const getRecipients = jest.fn().mockImplementation(docId => {
|
|
75
|
+
if (docId === 'file-id' || docId === 'shared-file-id') {
|
|
76
|
+
return [ownerRecipient]
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return []
|
|
80
|
+
})
|
|
81
|
+
const getSharingLink = jest
|
|
82
|
+
.fn()
|
|
83
|
+
.mockImplementation(docId =>
|
|
84
|
+
docId === 'file-id' ? 'http://share-link' : null
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
mockGetRecipientsFromSharing.mockReturnValue([ownerRecipient])
|
|
88
|
+
mockUseClient.mockReturnValue({ options: { uri: clientUri } })
|
|
89
|
+
const isOwner = jest.fn().mockReturnValue(userIsOwner)
|
|
90
|
+
|
|
91
|
+
mockUseShareModal.mockReturnValue({ setShowShareModal: jest.fn() })
|
|
92
|
+
mockUseSharingContext.mockReturnValue({
|
|
93
|
+
allLoaded: true,
|
|
94
|
+
getDocumentPermissions,
|
|
95
|
+
getSharingById,
|
|
96
|
+
getRecipients,
|
|
97
|
+
getSharingLink,
|
|
98
|
+
isOwner
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
return render(<Sharing file={targetFile} />)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
describe('Sharing', () => {
|
|
105
|
+
beforeEach(() => {
|
|
106
|
+
jest.clearAllMocks()
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
it('should use shared drive recipients when the file belongs to a shared drive', () => {
|
|
110
|
+
setup({ targetFile: sharedDriveFile })
|
|
111
|
+
|
|
112
|
+
expect(mockUseSharingContext().getSharingById).toHaveBeenCalledWith(
|
|
113
|
+
'drive-id'
|
|
114
|
+
)
|
|
115
|
+
expect(mockGetRecipientsFromSharing).toHaveBeenCalledWith(
|
|
116
|
+
sharedDriveSharing,
|
|
117
|
+
'file-id'
|
|
118
|
+
)
|
|
119
|
+
expect(mockUseSharingContext().getRecipients).not.toHaveBeenCalled()
|
|
120
|
+
expect(mockUseSharingContext().getDocumentPermissions).toHaveBeenCalledWith(
|
|
121
|
+
'file-id'
|
|
122
|
+
)
|
|
123
|
+
expect(mockUseSharingContext().getSharingLink).toHaveBeenCalledWith(
|
|
124
|
+
'file-id'
|
|
125
|
+
)
|
|
126
|
+
expect(mockUseSharingContext().isOwner).not.toHaveBeenCalled()
|
|
127
|
+
expect(mockMemberRecipientLite).toHaveBeenCalledWith(
|
|
128
|
+
expect.objectContaining({
|
|
129
|
+
recipient: expect.objectContaining(expectedOwnerRecipient),
|
|
130
|
+
isOwner: false
|
|
131
|
+
})
|
|
132
|
+
)
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
it('should use isOwner for a regular sharing', () => {
|
|
136
|
+
setup({ targetFile: sharedFile, userIsOwner: true })
|
|
137
|
+
|
|
138
|
+
expect(mockUseSharingContext().isOwner).toHaveBeenCalledWith(
|
|
139
|
+
'shared-file-id'
|
|
140
|
+
)
|
|
141
|
+
expect(mockMemberRecipientLite).toHaveBeenCalledWith(
|
|
142
|
+
expect.objectContaining({
|
|
143
|
+
recipient: expect.objectContaining(expectedOwnerRecipient),
|
|
144
|
+
isOwner: true
|
|
145
|
+
})
|
|
146
|
+
)
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
it('should not mark the owner as current user when the owner is remote', () => {
|
|
150
|
+
setup({ targetFile: sharedDriveFile })
|
|
151
|
+
|
|
152
|
+
expect(mockMemberRecipientLite).toHaveBeenCalledWith(
|
|
153
|
+
expect.objectContaining({
|
|
154
|
+
recipient: expect.objectContaining(expectedOwnerRecipient),
|
|
155
|
+
isOwner: false
|
|
156
|
+
})
|
|
157
|
+
)
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
it('should mark the owner as current user when the owner matches the current instance', () => {
|
|
161
|
+
setup({ clientUri: ownerRecipient.instance, targetFile: sharedDriveFile })
|
|
162
|
+
|
|
163
|
+
expect(mockMemberRecipientLite).toHaveBeenCalledWith(
|
|
164
|
+
expect.objectContaining({
|
|
165
|
+
recipient: expect.objectContaining(expectedOwnerRecipient),
|
|
166
|
+
isOwner: true
|
|
167
|
+
})
|
|
168
|
+
)
|
|
169
|
+
})
|
|
170
|
+
})
|