cozy-sharing 30.3.0 → 31.0.0

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,24 @@
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
+ # [31.0.0](https://github.com/cozy/cozy-libs/compare/cozy-sharing@30.3.1...cozy-sharing@31.0.0) (2026-05-05)
7
+
8
+ ### Features
9
+
10
+ - **cozy-sharing:** Split SharedDriveModal ([82b9166](https://github.com/cozy/cozy-libs/commit/82b91662eadf1eb7380aa19484c6dac8c2757b2c))
11
+ - **cozy-sharing:** Update cozy-client ([bb5a3cf](https://github.com/cozy/cozy-libs/commit/bb5a3cf5c3ddb231f62d250508f744410dbfe477))
12
+ - **cozy-sharing:** Use new API to create shared drive ([4296b92](https://github.com/cozy/cozy-libs/commit/4296b92821643c3daa102192b550080b8d34b27f))
13
+
14
+ ### BREAKING CHANGES
15
+
16
+ - **cozy-sharing:** You need to update cozy-client to >=60.24.0
17
+
18
+ ## [30.3.1](https://github.com/cozy/cozy-libs/compare/cozy-sharing@30.3.0...cozy-sharing@30.3.1) (2026-04-24)
19
+
20
+ ### Bug Fixes
21
+
22
+ - **cozy-sharing:** Flatten contact name object in formatRecipients ([c804f59](https://github.com/cozy/cozy-libs/commit/c804f59d87d40cc8a6bfc5e96e88d88a13cbaadb))
23
+
6
24
  # [30.3.0](https://github.com/cozy/cozy-libs/compare/cozy-sharing@30.2.2...cozy-sharing@30.3.0) (2026-04-23)
7
25
 
8
26
  ### Features
@@ -24,7 +24,6 @@ export var EditableSharingModal = function EditableSharingModal(_ref) {
24
24
  hasSharedChild = _useSharingContext.hasSharedChild,
25
25
  hasSharedParent = _useSharingContext.hasSharedParent,
26
26
  isOwner = _useSharingContext.isOwner,
27
- isSharedDrive = _useSharingContext.isSharedDrive,
28
27
  revoke = _useSharingContext.revoke,
29
28
  revokeSelf = _useSharingContext.revokeSelf,
30
29
  share = _useSharingContext.share;
@@ -38,7 +37,6 @@ export var EditableSharingModal = function EditableSharingModal(_ref) {
38
37
  hasSharedChild: documentPath && hasSharedChild(documentPath),
39
38
  hasSharedParent: documentPath && hasSharedParent(documentPath),
40
39
  isOwner: isOwner(document._id),
41
- isSharedDrive: isSharedDrive(document._id),
42
40
  link: getSharingLink(document._id),
43
41
  onRevoke: revoke,
44
42
  onRevokeSelf: revokeSelf,
@@ -3,7 +3,6 @@ import React from 'react';
3
3
  import flag from 'cozy-flags';
4
4
  import ShareDialogCozyToCozy from './ShareDialogCozyToCozy';
5
5
  import ShareDialogOnlyByLink from './ShareDialogOnlyByLink';
6
- import { SharedDriveEditModal } from './SharedDrive/SharedDriveEditModal';
7
6
  export var ShareModal = function ShareModal(_ref) {
8
7
  var autoOpenShareRestriction = _ref.autoOpenShareRestriction,
9
8
  createContact = _ref.createContact,
@@ -13,7 +12,6 @@ export var ShareModal = function ShareModal(_ref) {
13
12
  hasSharedChild = _ref.hasSharedChild,
14
13
  hasSharedParent = _ref.hasSharedParent,
15
14
  isOwner = _ref.isOwner,
16
- isSharedDrive = _ref.isSharedDrive,
17
15
  link = _ref.link,
18
16
  onClose = _ref.onClose,
19
17
  onRevoke = _ref.onRevoke,
@@ -25,20 +23,6 @@ export var ShareModal = function ShareModal(_ref) {
25
23
  sharingDesc = _ref.sharingDesc,
26
24
  showGenerateLinkButton = _ref.showGenerateLinkButton,
27
25
  twoStepsConfirmationMethods = _ref.twoStepsConfirmationMethods;
28
-
29
- if (isSharedDrive && !flag('drive.federated-shared-folder.enabled')) {
30
- return /*#__PURE__*/React.createElement(SharedDriveEditModal, {
31
- document: document,
32
- sharing: sharing,
33
- recipients: recipients,
34
- onShare: onShare,
35
- onRevoke: onRevoke,
36
- onClose: onClose,
37
- autoOpenShareRestriction: autoOpenShareRestriction,
38
- showGenerateLinkButton: showGenerateLinkButton
39
- });
40
- }
41
-
42
26
  var shareDialogOnlyByLink = flag('cozy.hide-sharing-cozy-to-cozy') || documentType === 'Albums';
43
27
  var showShareByEmail = !hasSharedParent && !hasSharedChild;
44
28
  var showShareByLink = documentType !== 'Organizations';
@@ -0,0 +1,75 @@
1
+ import PropTypes from 'prop-types';
2
+ import React from 'react';
3
+ import Button from 'cozy-ui/transpiled/react/Buttons';
4
+ import TextField from 'cozy-ui/transpiled/react/TextField';
5
+ import Typography from 'cozy-ui/transpiled/react/Typography';
6
+ import { useI18n } from 'twake-i18n';
7
+ import withLocales from '../../hoc/withLocales';
8
+ import { default as DumbShareByEmail } from '../ShareByEmail';
9
+ import WhoHasAccess from '../WhoHasAccess';
10
+ import { useSharedDrive } from './useSharedDrive';
11
+ export var SharedDriveForm = withLocales(function (_ref) {
12
+ var onSuccess = _ref.onSuccess,
13
+ onCancel = _ref.onCancel;
14
+
15
+ var _useI18n = useI18n(),
16
+ t = _useI18n.t;
17
+
18
+ var _useSharedDrive = useSharedDrive({
19
+ onSuccess: onSuccess
20
+ }),
21
+ sharedDriveName = _useSharedDrive.sharedDriveName,
22
+ recipients = _useSharedDrive.recipients,
23
+ handleSharedDriveNameChange = _useSharedDrive.handleSharedDriveNameChange,
24
+ onShare = _useSharedDrive.onShare,
25
+ onCreate = _useSharedDrive.onCreate,
26
+ onSetType = _useSharedDrive.onSetType,
27
+ onRevoke = _useSharedDrive.onRevoke,
28
+ createContact = _useSharedDrive.createContact;
29
+
30
+ return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
31
+ className: "u-ph-2"
32
+ }, /*#__PURE__*/React.createElement(TextField, {
33
+ required: true,
34
+ label: t('SharedDrive.sharedDriveModal.nameLabel'),
35
+ variant: "outlined",
36
+ size: "small",
37
+ className: "u-w-100 u-mt-1-half",
38
+ value: sharedDriveName,
39
+ onChange: handleSharedDriveNameChange
40
+ }), /*#__PURE__*/React.createElement(Typography, {
41
+ variant: "h6",
42
+ className: "u-mt-1-half u-mb-half"
43
+ }, t('SharedDrive.sharedDriveModal.addPeople')), /*#__PURE__*/React.createElement(DumbShareByEmail, {
44
+ createContact: createContact,
45
+ currentRecipients: recipients,
46
+ documentType: "Files",
47
+ sharedDrive: true,
48
+ onShare: onShare,
49
+ submitLabel: t('SharedDrive.sharedDriveModal.add'),
50
+ showNotifications: false,
51
+ sharingDesc: ""
52
+ })), /*#__PURE__*/React.createElement(WhoHasAccess, {
53
+ isOwner: true,
54
+ isSharedDrive: true,
55
+ recipients: recipients,
56
+ documentType: "Files",
57
+ className: "u-w-100",
58
+ onRevoke: onRevoke,
59
+ onSetType: onSetType
60
+ }), /*#__PURE__*/React.createElement("div", {
61
+ className: "u-flex u-flex-justify-end u-ph-2 u-pv-1 u-column-gap-half"
62
+ }, /*#__PURE__*/React.createElement(Button, {
63
+ variant: "secondary",
64
+ label: t('SharedDrive.sharedDriveModal.cancel'),
65
+ onClick: onCancel
66
+ }), /*#__PURE__*/React.createElement(Button, {
67
+ variant: "primary",
68
+ label: t('SharedDrive.sharedDriveModal.create'),
69
+ onClick: onCreate
70
+ })));
71
+ });
72
+ SharedDriveForm.propTypes = {
73
+ onSuccess: PropTypes.func.isRequired,
74
+ onCancel: PropTypes.func.isRequired
75
+ };
@@ -1,182 +1,32 @@
1
- import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
- import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
3
- import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
4
- import _regeneratorRuntime from "@babel/runtime/regenerator";
5
1
  import PropTypes from 'prop-types';
6
- import React, { useState } from 'react';
7
- import { useClient } from 'cozy-client';
8
- import { useAlert } from 'cozy-ui/transpiled/react/providers/Alert';
2
+ import React from 'react';
3
+ import { FixedDialog } from 'cozy-ui/transpiled/react/CozyDialogs';
9
4
  import { useI18n } from 'twake-i18n';
10
- import { DumbSharedDriveModal } from './DumbSharedDriveModal';
11
- import { mergeAndDeduplicateRecipients, formatRecipients, RECIPIENT_INDEX_PREFIX } from './helpers';
12
5
  import withLocales from '../../hoc/withLocales';
13
- import { useSharingContext } from '../../hooks/useSharingContext';
14
- import { Contact } from '../../models';
6
+ import { SharedDriveForm } from './SharedDriveForm';
15
7
  export var SharedDriveModal = withLocales(function (_ref) {
16
8
  var onClose = _ref.onClose;
17
- var client = useClient();
18
9
 
19
10
  var _useI18n = useI18n(),
20
11
  t = _useI18n.t;
21
12
 
22
- var _useSharingContext = useSharingContext(),
23
- share = _useSharingContext.share;
24
-
25
- var _useAlert = useAlert(),
26
- showAlert = _useAlert.showAlert;
27
-
28
- var _useState = useState({
29
- recipients: [],
30
- readOnlyRecipients: []
31
- }),
32
- _useState2 = _slicedToArray(_useState, 2),
33
- sharedDriveRecipients = _useState2[0],
34
- setSharedDriveRecipients = _useState2[1];
35
-
36
- var _useState3 = useState(''),
37
- _useState4 = _slicedToArray(_useState3, 2),
38
- sharedDriveName = _useState4[0],
39
- setSharedDriveName = _useState4[1];
40
-
41
- var onShare = function onShare(params) {
42
- setSharedDriveRecipients({
43
- recipients: mergeAndDeduplicateRecipients([sharedDriveRecipients.recipients, params.recipients]),
44
- readOnlyRecipients: mergeAndDeduplicateRecipients([sharedDriveRecipients.readOnlyRecipients, params.readOnlyRecipients])
45
- });
46
- };
47
-
48
- var handleSharedDriveNameChange = function handleSharedDriveNameChange(event) {
49
- setSharedDriveName(event.target.value);
50
- };
51
-
52
- var onCreate = /*#__PURE__*/function () {
53
- var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
54
- var _yield$client$create2, sharedDriveFolder;
55
-
56
- return _regeneratorRuntime.wrap(function _callee$(_context) {
57
- while (1) switch (_context.prev = _context.next) {
58
- case 0:
59
- _context.prev = 0;
60
- _context.next = 3;
61
- return client.collection('io.cozy.files').getOrCreateSharedDrivesDirectory();
62
-
63
- case 3:
64
- _context.next = 5;
65
- return client.create('io.cozy.files', {
66
- name: sharedDriveName,
67
- dirId: 'io.cozy.files.shared-drives-dir',
68
- type: 'directory'
69
- });
70
-
71
- case 5:
72
- _yield$client$create2 = _context.sent;
73
- sharedDriveFolder = _yield$client$create2.data;
74
- _context.next = 9;
75
- return share({
76
- description: sharedDriveName,
77
- document: sharedDriveFolder,
78
- recipients: sharedDriveRecipients.recipients,
79
- readOnlyRecipients: sharedDriveRecipients.readOnlyRecipients,
80
- sharedDrive: true,
81
- openSharing: false
82
- });
83
-
84
- case 9:
85
- showAlert({
86
- message: t('SharedDrive.sharedDriveModal.successNotification'),
87
- severity: 'success',
88
- variant: 'filled'
89
- });
90
- onClose();
91
- _context.next = 16;
92
- break;
93
-
94
- case 13:
95
- _context.prev = 13;
96
- _context.t0 = _context["catch"](0);
97
- showAlert({
98
- message: t('SharedDrive.sharedDriveModal.errorNotification'),
99
- severity: 'error',
100
- variant: 'filled'
101
- });
102
-
103
- case 16:
104
- case "end":
105
- return _context.stop();
106
- }
107
- }, _callee, null, [[0, 13]]);
108
- }));
109
-
110
- return function onCreate() {
111
- return _ref2.apply(this, arguments);
112
- };
113
- }();
114
-
115
- var onSetType = function onSetType(index, newType) {
116
- var _id = index.split(RECIPIENT_INDEX_PREFIX)[1];
117
-
118
- if (newType === 'two-way') {
119
- setSharedDriveRecipients(function (prev) {
120
- var recipientToMove = prev.readOnlyRecipients.find(function (r) {
121
- return r._id === _id;
122
- });
123
- return {
124
- recipients: [].concat(_toConsumableArray(prev.recipients), [recipientToMove]),
125
- readOnlyRecipients: prev.readOnlyRecipients.filter(function (r) {
126
- return r._id !== _id;
127
- })
128
- };
129
- });
130
- } else {
131
- setSharedDriveRecipients(function (prev) {
132
- var recipientToMove = prev.recipients.find(function (r) {
133
- return r._id === _id;
134
- });
135
- return {
136
- recipients: prev.recipients.filter(function (r) {
137
- return r._id !== _id;
138
- }),
139
- readOnlyRecipients: [].concat(_toConsumableArray(prev.readOnlyRecipients), [recipientToMove])
140
- };
141
- });
142
- }
143
- };
144
-
145
- var onRevoke = function onRevoke(index) {
146
- var _id = index.split(RECIPIENT_INDEX_PREFIX)[1];
147
- setSharedDriveRecipients(function (prev) {
148
- return {
149
- recipients: prev.recipients.filter(function (r) {
150
- return r._id !== _id;
151
- }),
152
- readOnlyRecipients: prev.readOnlyRecipients.filter(function (r) {
153
- return r._id !== _id;
154
- })
155
- };
156
- });
157
- };
158
-
159
- var createContact = function createContact(contact) {
160
- return client.create(Contact.doctype, contact);
161
- };
162
-
163
- var recipients = formatRecipients(sharedDriveRecipients);
164
- return /*#__PURE__*/React.createElement(DumbSharedDriveModal, {
165
- title: t('SharedDrive.sharedDriveModal.title'),
166
- sharedDriveName: sharedDriveName,
167
- handleSharedDriveNameChange: handleSharedDriveNameChange,
168
- createContact: createContact,
169
- recipients: recipients,
170
- currentRecipients: [],
171
- onRevoke: onRevoke,
172
- onSetType: onSetType,
173
- onCreate: onCreate,
174
- onSend: undefined,
13
+ return /*#__PURE__*/React.createElement(FixedDialog, {
14
+ open: true,
15
+ disableGutters: true,
175
16
  onClose: onClose,
176
- onShare: onShare,
177
- showNameField: true,
178
- sharingLink: undefined,
179
- document: undefined
17
+ title: t('SharedDrive.sharedDriveModal.title'),
18
+ classes: {
19
+ paper: 'u-ov-visible'
20
+ },
21
+ componentsProps: {
22
+ dialogContent: {
23
+ className: 'u-ov-visible'
24
+ }
25
+ },
26
+ content: /*#__PURE__*/React.createElement(SharedDriveForm, {
27
+ onSuccess: onClose,
28
+ onCancel: onClose
29
+ })
180
30
  });
181
31
  });
182
32
  SharedDriveModal.propTypes = {
@@ -68,7 +68,7 @@ export var formatRecipients = function formatRecipients(sharedDriveRecipients) {
68
68
  recipients.push({
69
69
  index: "".concat(RECIPIENT_INDEX_PREFIX).concat(r._id),
70
70
  email: ContactModel.getPrimaryEmail(r),
71
- public_name: r.displayName || r.name,
71
+ public_name: ContactModel.getDisplayName(r),
72
72
  memberIndex: r._id,
73
73
  type: 'two-way',
74
74
  members: r.members
@@ -78,7 +78,7 @@ export var formatRecipients = function formatRecipients(sharedDriveRecipients) {
78
78
  recipients.push({
79
79
  index: "".concat(RECIPIENT_INDEX_PREFIX).concat(r._id),
80
80
  email: ContactModel.getPrimaryEmail(r),
81
- public_name: r.displayName || r.name,
81
+ public_name: ContactModel.getDisplayName(r),
82
82
  memberIndex: r._id,
83
83
  type: 'one-way',
84
84
  members: r.members
@@ -182,6 +182,25 @@ describe('formatRecipients', function () {
182
182
  public_name: 'Bob'
183
183
  });
184
184
  });
185
+ it('should flatten an object-shaped contact name into a string public_name', function () {
186
+ var input = {
187
+ recipients: [{
188
+ _id: '3',
189
+ name: {
190
+ givenName: 'Arya',
191
+ familyName: 'Stark'
192
+ },
193
+ email: [{
194
+ address: 'arya@example.com',
195
+ primary: true
196
+ }]
197
+ }],
198
+ readOnlyRecipients: []
199
+ };
200
+ var result = formatRecipients(input);
201
+ expect(typeof result[0].public_name).toBe('string');
202
+ expect(result[0].public_name).toBe('Arya Stark');
203
+ });
185
204
  it('should sort recipients by public_name', function () {
186
205
  var input = {
187
206
  recipients: [{
@@ -0,0 +1,126 @@
1
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
4
+ import { useState } from 'react';
5
+ import { useClient } from 'cozy-client';
6
+ import { useAlert } from 'cozy-ui/transpiled/react/providers/Alert';
7
+ import { useI18n } from 'twake-i18n';
8
+ import { RECIPIENT_INDEX_PREFIX, formatRecipients, mergeAndDeduplicateRecipients, moveRecipientToReadOnly, moveRecipientToReadWrite } from './helpers';
9
+ import { Contact } from '../../models';
10
+ export var useSharedDrive = function useSharedDrive(_ref) {
11
+ var onSuccess = _ref.onSuccess;
12
+ var client = useClient();
13
+
14
+ var _useI18n = useI18n(),
15
+ t = _useI18n.t;
16
+
17
+ var _useAlert = useAlert(),
18
+ showAlert = _useAlert.showAlert;
19
+
20
+ var _useState = useState({
21
+ recipients: [],
22
+ readOnlyRecipients: []
23
+ }),
24
+ _useState2 = _slicedToArray(_useState, 2),
25
+ sharedDriveRecipients = _useState2[0],
26
+ setSharedDriveRecipients = _useState2[1];
27
+
28
+ var _useState3 = useState(''),
29
+ _useState4 = _slicedToArray(_useState3, 2),
30
+ sharedDriveName = _useState4[0],
31
+ setSharedDriveName = _useState4[1];
32
+
33
+ var handleSharedDriveNameChange = function handleSharedDriveNameChange(event) {
34
+ setSharedDriveName(event.target.value);
35
+ };
36
+
37
+ var onShare = function onShare(params) {
38
+ setSharedDriveRecipients(function (prev) {
39
+ return {
40
+ recipients: mergeAndDeduplicateRecipients([prev.recipients, params.recipients]),
41
+ readOnlyRecipients: mergeAndDeduplicateRecipients([prev.readOnlyRecipients, params.readOnlyRecipients])
42
+ };
43
+ });
44
+ };
45
+
46
+ var onCreate = /*#__PURE__*/function () {
47
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
48
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
49
+ while (1) switch (_context.prev = _context.next) {
50
+ case 0:
51
+ _context.prev = 0;
52
+ _context.next = 3;
53
+ return client.collection('io.cozy.sharings').createSharedDrive({
54
+ name: sharedDriveName,
55
+ description: sharedDriveName,
56
+ recipients: sharedDriveRecipients.recipients,
57
+ readOnlyRecipients: sharedDriveRecipients.readOnlyRecipients
58
+ });
59
+
60
+ case 3:
61
+ showAlert({
62
+ message: t('SharedDrive.sharedDriveModal.successNotification'),
63
+ severity: 'success',
64
+ variant: 'filled'
65
+ });
66
+ onSuccess();
67
+ _context.next = 10;
68
+ break;
69
+
70
+ case 7:
71
+ _context.prev = 7;
72
+ _context.t0 = _context["catch"](0);
73
+ showAlert({
74
+ message: t('SharedDrive.sharedDriveModal.errorNotification'),
75
+ severity: 'error',
76
+ variant: 'filled'
77
+ });
78
+
79
+ case 10:
80
+ case "end":
81
+ return _context.stop();
82
+ }
83
+ }, _callee, null, [[0, 7]]);
84
+ }));
85
+
86
+ return function onCreate() {
87
+ return _ref2.apply(this, arguments);
88
+ };
89
+ }();
90
+
91
+ var onSetType = function onSetType(index, newType) {
92
+ var _id = index.split(RECIPIENT_INDEX_PREFIX)[1];
93
+ setSharedDriveRecipients(function (prev) {
94
+ return newType === 'two-way' ? moveRecipientToReadWrite(prev, _id) : moveRecipientToReadOnly(prev, _id);
95
+ });
96
+ };
97
+
98
+ var onRevoke = function onRevoke(index) {
99
+ var _id = index.split(RECIPIENT_INDEX_PREFIX)[1];
100
+ setSharedDriveRecipients(function (prev) {
101
+ return {
102
+ recipients: prev.recipients.filter(function (r) {
103
+ return r._id !== _id;
104
+ }),
105
+ readOnlyRecipients: prev.readOnlyRecipients.filter(function (r) {
106
+ return r._id !== _id;
107
+ })
108
+ };
109
+ });
110
+ };
111
+
112
+ var createContact = function createContact(contact) {
113
+ return client.create(Contact.doctype, contact);
114
+ };
115
+
116
+ return {
117
+ sharedDriveName: sharedDriveName,
118
+ recipients: formatRecipients(sharedDriveRecipients),
119
+ handleSharedDriveNameChange: handleSharedDriveNameChange,
120
+ onShare: onShare,
121
+ onCreate: onCreate,
122
+ onSetType: onSetType,
123
+ onRevoke: onRevoke,
124
+ createContact: createContact
125
+ };
126
+ };