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 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
@@ -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 recipients = getRecipients(file._id);
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
- var _isOwner = isOwner(file._id);
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: _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.2",
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",
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.2.1",
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": "107c14be0fb0677515062187e3fdadeab4e00350"
74
+ "gitHead": "4fe0199d7042ff150315bd4a097256b2364f200c"
75
75
  }
@@ -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
- useSharingContext,
7
+ getRecipientsFromSharing,
8
+ LinkRecipientLite,
7
9
  MemberRecipientLite,
8
10
  OwnerRecipientDefaultLite,
9
- LinkRecipientLite
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 recipients = getRecipients(file._id)
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 _isOwner = isOwner(file._id)
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={_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
+ })