cozy-sharing 37.5.4 → 37.6.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.
@@ -1,24 +1,28 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
3
- var _excluded = ["document"];
3
+ var _excluded = ["document", "recipients"],
4
+ _excluded2 = ["document"];
4
5
  import PropTypes from 'prop-types';
5
- import React from 'react';
6
+ import React, { useEffect } from 'react';
6
7
  import { useClient } from 'cozy-client';
8
+ import flag from 'cozy-flags';
9
+ import minilog from 'cozy-minilog';
7
10
  import { useFetchDocumentPath } from '../../hooks/useFetchDocumentPath';
8
11
  import { useSharingContext } from '../../hooks/useSharingContext';
9
12
  import { Contact } from '../../models';
10
13
  import { ShareModal } from '../ShareModal';
11
14
  export var EditableSharingModal = function EditableSharingModal(_ref) {
12
15
  var document = _ref.document,
16
+ recipients = _ref.recipients,
13
17
  rest = _objectWithoutProperties(_ref, _excluded);
14
18
 
15
19
  var client = useClient();
20
+ var isFederatedMode = flag('drive.federated-shared-folder.enabled');
16
21
  var documentPath = useFetchDocumentPath(client, document);
17
22
 
18
23
  var _useSharingContext = useSharingContext(),
19
24
  documentType = _useSharingContext.documentType,
20
25
  getDocumentPermissions = _useSharingContext.getDocumentPermissions,
21
- getRecipients = _useSharingContext.getRecipients,
22
26
  getSharingForSelf = _useSharingContext.getSharingForSelf,
23
27
  getSharingLink = _useSharingContext.getSharingLink,
24
28
  hasSharedChild = _useSharingContext.hasSharedChild,
@@ -34,19 +38,51 @@ export var EditableSharingModal = function EditableSharingModal(_ref) {
34
38
  },
35
39
  document: document,
36
40
  documentType: documentType,
37
- hasSharedChild: documentPath && hasSharedChild(documentPath),
38
- hasSharedParent: documentPath && hasSharedParent(documentPath),
41
+ hasSharedChild: isFederatedMode ? undefined : documentPath && hasSharedChild(documentPath),
42
+ hasSharedParent: isFederatedMode ? undefined : documentPath && hasSharedParent(documentPath),
39
43
  isOwner: isOwner(document._id),
40
44
  link: getSharingLink(document._id),
41
45
  onRevoke: revoke,
42
46
  onRevokeSelf: revokeSelf,
43
47
  onShare: share,
44
48
  permissions: getDocumentPermissions(document._id),
45
- recipients: getRecipients(document._id),
49
+ recipients: recipients,
46
50
  sharing: getSharingForSelf(document._id)
47
51
  }, rest));
48
52
  };
49
53
  EditableSharingModal.propTypes = {
50
- document: PropTypes.object
54
+ document: PropTypes.object,
55
+ recipients: PropTypes.array
51
56
  };
52
- export default EditableSharingModal;
57
+ export var EditableSharingModalWrapper = function EditableSharingModalWrapper(_ref2) {
58
+ var document = _ref2.document,
59
+ rest = _objectWithoutProperties(_ref2, _excluded2);
60
+
61
+ var log = minilog('EditableSharingModal');
62
+ var isFederatedMode = flag('drive.federated-shared-folder.enabled');
63
+
64
+ var _useSharingContext2 = useSharingContext(),
65
+ getRecipients = _useSharingContext2.getRecipients,
66
+ getEffectiveRecipients = _useSharingContext2.getEffectiveRecipients,
67
+ fetchEffectiveRecipients = _useSharingContext2.fetchEffectiveRecipients,
68
+ invalidateEffectiveRecipients = _useSharingContext2.invalidateEffectiveRecipients;
69
+
70
+ var fileId = document._id || document.id;
71
+ useEffect(function () {
72
+ if (isFederatedMode && fileId) {
73
+ fetchEffectiveRecipients(fileId, document.driveId).catch(log.error);
74
+ }
75
+
76
+ return function () {
77
+ if (fileId) {
78
+ invalidateEffectiveRecipients(fileId);
79
+ }
80
+ };
81
+ }, [fileId, document.driveId, isFederatedMode, fetchEffectiveRecipients, invalidateEffectiveRecipients]);
82
+ var recipients = isFederatedMode ? getEffectiveRecipients(fileId) : getRecipients(fileId);
83
+ return /*#__PURE__*/React.createElement(EditableSharingModal, _extends({
84
+ document: document,
85
+ recipients: recipients
86
+ }, rest));
87
+ };
88
+ export default EditableSharingModalWrapper;
@@ -9,10 +9,10 @@ import React from 'react';
9
9
  import { useLocation } from 'react-router';
10
10
  import flag from 'cozy-flags';
11
11
  import EditableSharingModal from './EditableSharingModal';
12
- import { SharingDetailsModal } from './SharingDetailsModal';
12
+ import SharingDetailsModal from './SharingDetailsModal';
13
13
  import withLocales from '../../hoc/withLocales';
14
14
  import { useSharingContext } from '../../hooks/useSharingContext';
15
- import { FederatedFolderModal } from '../FederatedFolder/FederatedFolderModal';
15
+ import FederatedFolderModal from '../FederatedFolder/FederatedFolderModal';
16
16
  export var ShareModal = withLocales(function (props) {
17
17
  var _location$state;
18
18
 
@@ -64,7 +64,6 @@ export var ShareModal = function ShareModal(_ref) {
64
64
  twoStepsConfirmationMethods: twoStepsConfirmationMethods
65
65
  });
66
66
  };
67
- export default ShareModal;
68
67
  ShareModal.propTypes = {
69
68
  autoOpenShareRestriction: PropTypes.bool,
70
69
  createContact: PropTypes.func.isRequired,
@@ -87,4 +86,5 @@ ShareModal.propTypes = {
87
86
  rejectRecipient: PropTypes.func,
88
87
  recipientConfirmationDialogContent: PropTypes.func
89
88
  })
90
- };
89
+ };
90
+ export default ShareModal;
@@ -0,0 +1,92 @@
1
+ import cx from 'classnames';
2
+ import React from 'react';
3
+ import Typography from 'cozy-ui/transpiled/react/Typography';
4
+ import useBreakpoints from 'cozy-ui/transpiled/react/providers/Breakpoints';
5
+ import { useI18n } from 'twake-i18n';
6
+ import AntivirusAlert from './AntivirusAlert';
7
+ import { default as DumbShareByEmail } from './ShareByEmail';
8
+ import WhoHasAccess from './WhoHasAccess';
9
+ var styles = {
10
+ "share-modal-content": "share__share-modal-content___1iqEq",
11
+ "coz-form": "share__coz-form___1ICST",
12
+ "coz-form-group": "share__coz-form-group___VsQp7",
13
+ "coz-form-desc": "share__coz-form-desc___2mYN4",
14
+ "coz-form-label": "share__coz-form-label___bogBw",
15
+ "coz-form-label--error": "share__coz-form-label--error___3YPkf",
16
+ "coz-form-errors": "share__coz-form-errors___2xYRz",
17
+ "coz-form-controls": "share__coz-form-controls___H8kGc",
18
+ "coz-form-controls--full": "share__coz-form-controls--full___1oQXF",
19
+ "coz-form-controls--dispatch": "share__coz-form-controls--dispatch___1zIxt",
20
+ "error": "share__error___pwqPO",
21
+ "share-dialog-scrollable-content": "share__share-dialog-scrollable-content___2Xyoq",
22
+ "share-dialog-scrollable-body": "share__share-dialog-scrollable-body___2O5UT",
23
+ "share-dialog-members": "share__share-dialog-members___CNHKJ",
24
+ "share-byemail-onlybylink": "share__share-byemail-onlybylink___29W-t",
25
+ "aligned-dropdown-button": "share__aligned-dropdown-button___3crgG"
26
+ };
27
+
28
+ var SharingContent = function SharingContent(_ref) {
29
+ var document = _ref.document,
30
+ documentType = _ref.documentType,
31
+ hasSharedParent = _ref.hasSharedParent,
32
+ isOwner = _ref.isOwner,
33
+ onRevoke = _ref.onRevoke,
34
+ onRevokeSelf = _ref.onRevokeSelf,
35
+ recipients = _ref.recipients,
36
+ sharing = _ref.sharing,
37
+ showShareByEmail = _ref.showShareByEmail,
38
+ showShareOnlyByLink = _ref.showShareOnlyByLink,
39
+ showWhoHasAccess = _ref.showWhoHasAccess,
40
+ recipientsToBeConfirmed = _ref.recipientsToBeConfirmed,
41
+ verifyRecipient = _ref.verifyRecipient,
42
+ link = _ref.link,
43
+ permissions = _ref.permissions,
44
+ pendingRecipients = _ref.pendingRecipients,
45
+ onPendingRecipientsChange = _ref.onPendingRecipientsChange,
46
+ selectedOption = _ref.selectedOption,
47
+ onSelectedOptionChange = _ref.onSelectedOptionChange;
48
+
49
+ var _useI18n = useI18n(),
50
+ t = _useI18n.t;
51
+
52
+ var _useBreakpoints = useBreakpoints(),
53
+ isMobile = _useBreakpoints.isMobile;
54
+
55
+ return /*#__PURE__*/React.createElement("div", {
56
+ className: cx(styles['share-modal-content'])
57
+ }, /*#__PURE__*/React.createElement("div", {
58
+ className: cx('u-pt-1-half', isMobile ? 'u-ph-1' : 'u-ph-2')
59
+ }, /*#__PURE__*/React.createElement(AntivirusAlert, {
60
+ document: document
61
+ }), showShareOnlyByLink && /*#__PURE__*/React.createElement("div", {
62
+ className: styles['share-byemail-onlybylink']
63
+ }, t("".concat(documentType, ".share.shareByEmail.onlyByLink"), {
64
+ type: t("".concat(documentType, ".share.shareByEmail.type.").concat(document.type === 'directory' ? 'folder' : 'file'))
65
+ }), ' ', /*#__PURE__*/React.createElement("strong", null, t("".concat(documentType, ".share.shareByEmail.").concat(hasSharedParent ? 'hasSharedParent' : 'hasSharedChild')))), /*#__PURE__*/React.createElement(Typography, {
66
+ variant: "h6",
67
+ className: "u-mb-half"
68
+ }, t('Share.contacts.addUsers')), showShareByEmail && /*#__PURE__*/React.createElement(DumbShareByEmail, {
69
+ currentRecipients: recipients,
70
+ document: document,
71
+ documentType: documentType,
72
+ sharing: sharing,
73
+ pendingRecipients: pendingRecipients,
74
+ onPendingRecipientsChange: onPendingRecipientsChange,
75
+ selectedOption: selectedOption,
76
+ onSelectedOptionChange: onSelectedOptionChange,
77
+ enableCreateContact: true
78
+ })), showWhoHasAccess && /*#__PURE__*/React.createElement(WhoHasAccess, {
79
+ document: document,
80
+ documentType: documentType,
81
+ isOwner: isOwner,
82
+ onRevoke: onRevoke,
83
+ onRevokeSelf: onRevokeSelf,
84
+ recipients: recipients,
85
+ recipientsToBeConfirmed: recipientsToBeConfirmed,
86
+ verifyRecipient: verifyRecipient,
87
+ link: link,
88
+ permissions: permissions
89
+ }));
90
+ };
91
+
92
+ export default SharingContent;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Pick the most relevant source for a recipient: prefer the target's own
3
+ * share ("self"), fall back to the first ancestor source.
4
+ * Needed because revoke/RO-RW actions target a specific sharing+member index.
5
+ */
6
+ var getBestSource = function getBestSource(effectiveRecipient) {
7
+ var sources = effectiveRecipient.sources || [];
8
+ return sources.find(function (s) {
9
+ return s.kind === 'self';
10
+ }) || sources[0];
11
+ };
12
+ /**
13
+ * Build a view object for MemberRecipient/MemberRecipientPermissions.
14
+ * Extracts sharingId/memberIndex/avatarPath/type from the source so
15
+ * existing components work without reading sources[] directly.
16
+ * Does not spread the backend data — only the fields needed for rendering.
17
+ */
18
+
19
+
20
+ var mapToRecipient = function mapToRecipient(effectiveRecipient, source) {
21
+ return {
22
+ name: effectiveRecipient.name,
23
+ email: effectiveRecipient.email,
24
+ instance: effectiveRecipient.instance,
25
+ status: effectiveRecipient.status,
26
+ read_only: effectiveRecipient.read_only,
27
+ index: "effective-".concat(source.sharing_id, "-").concat(source.member_index),
28
+ sharingId: source.sharing_id,
29
+ memberIndex: source.member_index,
30
+ avatarPath: "/sharings/".concat(source.sharing_id, "/recipients/").concat(source.member_index, "/avatar"),
31
+ type: effectiveRecipient.read_only ? 'one-way' : 'two-way'
32
+ };
33
+ };
34
+
35
+ export var mapEffectiveRecipients = function mapEffectiveRecipients(effectiveRecipients) {
36
+ return (effectiveRecipients || []).map(function (recipient) {
37
+ var source = getBestSource(recipient);
38
+ return source ? mapToRecipient(recipient, source) : recipient;
39
+ });
40
+ };
@@ -0,0 +1,134 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+
3
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
4
+
5
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
6
+
7
+ import { mapEffectiveRecipients } from './effectiveRecipients';
8
+
9
+ var makeAncestorSource = function makeAncestorSource() {
10
+ var rootName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'Parent Folder';
11
+ return {
12
+ sharing_id: 'sharing-1',
13
+ root_id: 'root-1',
14
+ root_name: rootName,
15
+ kind: 'ancestor',
16
+ member_index: 1,
17
+ read_only: false,
18
+ manageable: false
19
+ };
20
+ };
21
+
22
+ var makeSelfSource = function makeSelfSource() {
23
+ var _opts$memberIndex, _opts$readOnly, _opts$manageable;
24
+
25
+ var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
26
+ return {
27
+ sharing_id: opts.sharing_id || 'sharing-2',
28
+ root_id: 'root-2',
29
+ root_name: 'Child Folder',
30
+ kind: 'self',
31
+ member_index: (_opts$memberIndex = opts.memberIndex) !== null && _opts$memberIndex !== void 0 ? _opts$memberIndex : 1,
32
+ read_only: (_opts$readOnly = opts.readOnly) !== null && _opts$readOnly !== void 0 ? _opts$readOnly : false,
33
+ manageable: (_opts$manageable = opts.manageable) !== null && _opts$manageable !== void 0 ? _opts$manageable : true
34
+ };
35
+ };
36
+
37
+ var makeRecipient = function makeRecipient() {
38
+ var overrides = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
39
+ return _objectSpread({
40
+ id: 'recip-1',
41
+ name: 'Alice',
42
+ email: 'alice@example.com',
43
+ instance: 'https://alice.mycozy.cloud',
44
+ status: 'ready',
45
+ read_only: false,
46
+ can_edit_here: false,
47
+ sources: overrides.sources || []
48
+ }, overrides);
49
+ };
50
+
51
+ describe('mapEffectiveRecipients', function () {
52
+ it('returns empty array for empty input', function () {
53
+ expect(mapEffectiveRecipients([])).toEqual([]);
54
+ });
55
+ it('returns empty array for null or undefined', function () {
56
+ expect(mapEffectiveRecipients(null)).toEqual([]);
57
+ expect(mapEffectiveRecipients(undefined)).toEqual([]);
58
+ });
59
+ it('maps a recipient with a self source using the self source', function () {
60
+ var recipient = makeRecipient({
61
+ sources: [makeSelfSource()]
62
+ });
63
+ var result = mapEffectiveRecipients([recipient]);
64
+ expect(result).toHaveLength(1);
65
+ expect(result[0].sharingId).toBe('sharing-2');
66
+ expect(result[0].memberIndex).toBe(1);
67
+ expect(result[0].avatarPath).toBe('/sharings/sharing-2/recipients/1/avatar');
68
+ expect(result[0].type).toBe('two-way');
69
+ });
70
+ it('maps a recipient with only ancestor sources using the ancestor source', function () {
71
+ var recipient = makeRecipient({
72
+ sources: [makeAncestorSource('Shared Parent')]
73
+ });
74
+ var result = mapEffectiveRecipients([recipient]);
75
+ expect(result).toHaveLength(1);
76
+ expect(result[0].sharingId).toBe('sharing-1');
77
+ expect(result[0].memberIndex).toBe(1);
78
+ expect(result[0].name).toBe('Alice');
79
+ expect(result[0].email).toBe('alice@example.com');
80
+ });
81
+ it('maps an owner (self source, index 0) correctly', function () {
82
+ var recipient = makeRecipient({
83
+ status: 'owner',
84
+ read_only: true,
85
+ sources: [makeSelfSource({
86
+ memberIndex: 0,
87
+ manageable: false
88
+ })]
89
+ });
90
+ var result = mapEffectiveRecipients([recipient]);
91
+ expect(result).toHaveLength(1);
92
+ expect(result[0].status).toBe('owner');
93
+ expect(result[0].type).toBe('one-way');
94
+ });
95
+ it('maps an owner with only ancestor sources correctly', function () {
96
+ var recipient = makeRecipient({
97
+ status: 'owner',
98
+ sources: [makeAncestorSource('Parent Folder')]
99
+ });
100
+ var result = mapEffectiveRecipients([recipient]);
101
+ expect(result).toHaveLength(1);
102
+ expect(result[0].status).toBe('owner');
103
+ expect(result[0].sharingId).toBe('sharing-1');
104
+ expect(result[0].memberIndex).toBe(1);
105
+ });
106
+ it('sets type to one-way for read_only recipients', function () {
107
+ var recipient = makeRecipient({
108
+ read_only: true,
109
+ sources: [makeSelfSource({
110
+ readOnly: true
111
+ })]
112
+ });
113
+ var result = mapEffectiveRecipients([recipient]);
114
+ expect(result[0].type).toBe('one-way');
115
+ });
116
+ it('handles all recipients in the same array regardless of source kind', function () {
117
+ var selfRecipient = makeRecipient({
118
+ id: 'self-1',
119
+ name: 'Bob',
120
+ email: 'bob@example.com',
121
+ sources: [makeSelfSource()]
122
+ });
123
+ var ancestorRecipient = makeRecipient({
124
+ id: 'ancestor-1',
125
+ name: 'Carol',
126
+ email: 'carol@example.com',
127
+ sources: [makeAncestorSource('Root Folder')]
128
+ });
129
+ var result = mapEffectiveRecipients([selfRecipient, ancestorRecipient]);
130
+ expect(result).toHaveLength(2);
131
+ expect(result[0].sharingId).toBe('sharing-2');
132
+ expect(result[1].sharingId).toBe('sharing-1');
133
+ });
134
+ });
package/dist/state.js CHANGED
@@ -1,3 +1,4 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
1
2
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
3
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
3
4
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
@@ -23,6 +24,9 @@ var ADD_SHARING_LINK = 'ADD_SHARING_LINK';
23
24
  var UPDATE_SHARING_LINK = 'UPDATE_SHARING_LINK';
24
25
  var REVOKE_SHARING_LINK = 'REVOKE_SHARING_LINK';
25
26
  var RECEIVE_PATHS = 'RECEIVE_PATHS';
27
+ var RECEIVE_EFFECTIVE_RECIPIENTS = 'RECEIVE_EFFECTIVE_RECIPIENTS';
28
+ var UPDATE_EFFECTIVE_RECIPIENT = 'UPDATE_EFFECTIVE_RECIPIENT';
29
+ var INVALIDATE_EFFECTIVE_RECIPIENTS = 'INVALIDATE_EFFECTIVE_RECIPIENTS';
26
30
  export var SHARING_TYPE = {
27
31
  TWO_WAY: 'two-way',
28
32
  ONE_WAY: 'one-way'
@@ -136,6 +140,27 @@ export var receivePaths = function receivePaths(paths) {
136
140
  paths: paths
137
141
  };
138
142
  };
143
+ export var receiveEffectiveRecipients = function receiveEffectiveRecipients(docId, recipients) {
144
+ return {
145
+ type: RECEIVE_EFFECTIVE_RECIPIENTS,
146
+ docId: docId,
147
+ recipients: recipients
148
+ };
149
+ };
150
+ export var updateEffectiveRecipient = function updateEffectiveRecipient(sharingId, memberIndex, readOnly) {
151
+ return {
152
+ type: UPDATE_EFFECTIVE_RECIPIENT,
153
+ sharingId: sharingId,
154
+ memberIndex: memberIndex,
155
+ readOnly: readOnly
156
+ };
157
+ };
158
+ export var invalidateEffectiveRecipients = function invalidateEffectiveRecipients(docId) {
159
+ return {
160
+ type: INVALIDATE_EFFECTIVE_RECIPIENTS,
161
+ docId: docId
162
+ };
163
+ };
139
164
  export var matchingInstanceName = function matchingInstanceName() {
140
165
  var instanceUri = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
141
166
  return function (shareMember) {
@@ -373,6 +398,42 @@ var sharedPaths = function sharedPaths() {
373
398
  }
374
399
  };
375
400
 
401
+ var effectiveRecipients = function effectiveRecipients() {
402
+ var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
403
+ var action = arguments.length > 1 ? arguments[1] : undefined;
404
+
405
+ switch (action.type) {
406
+ case RECEIVE_EFFECTIVE_RECIPIENTS:
407
+ return _objectSpread(_objectSpread({}, state), {}, _defineProperty({}, action.docId, action.recipients));
408
+
409
+ case UPDATE_EFFECTIVE_RECIPIENT:
410
+ return Object.fromEntries(Object.entries(state).map(function (_ref2) {
411
+ var _ref3 = _slicedToArray(_ref2, 2),
412
+ docId = _ref3[0],
413
+ recipients = _ref3[1];
414
+
415
+ return [docId, recipients.map(function (r) {
416
+ return r.sharingId === action.sharingId && r.memberIndex === action.memberIndex ? _objectSpread(_objectSpread({}, r), {}, {
417
+ read_only: action.readOnly,
418
+ type: action.readOnly ? 'one-way' : 'two-way'
419
+ }) : r;
420
+ })];
421
+ }));
422
+
423
+ case INVALIDATE_EFFECTIVE_RECIPIENTS:
424
+ {
425
+ var _action$docId2 = action.docId,
426
+ _ = state[_action$docId2],
427
+ rest = _objectWithoutProperties(state, [_action$docId2].map(_toPropertyKey));
428
+
429
+ return rest;
430
+ }
431
+
432
+ default:
433
+ return state;
434
+ }
435
+ };
436
+
376
437
  var reducer = function reducer() {
377
438
  var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
378
439
  var action = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
@@ -380,7 +441,8 @@ var reducer = function reducer() {
380
441
  byDocId: byDocId(state.byDocId, action),
381
442
  sharings: sharings(state.sharings, action),
382
443
  permissions: permissions(state.permissions, action),
383
- sharedPaths: sharedPaths(state.sharedPaths, action)
444
+ sharedPaths: sharedPaths(state.sharedPaths, action),
445
+ effectiveRecipients: effectiveRecipients(state.effectiveRecipients, action)
384
446
  };
385
447
  };
386
448
 
@@ -643,6 +705,11 @@ export var getSharedParentPath = function getSharedParentPath(state, documentPat
643
705
  }
644
706
 
645
707
  return null;
708
+ };
709
+ export var getEffectiveRecipients = function getEffectiveRecipients(state, docId) {
710
+ var _state$effectiveRecip;
711
+
712
+ return ((_state$effectiveRecip = state.effectiveRecipients) === null || _state$effectiveRecip === void 0 ? void 0 : _state$effectiveRecip[docId]) || [];
646
713
  }; // helpers
647
714
 
648
715
  export var getSharedDocIds = function getSharedDocIds(doc) {
@@ -13,7 +13,8 @@ describe('Sharing state', function () {
13
13
  byDocId: {},
14
14
  sharings: [],
15
15
  permissions: [],
16
- sharedPaths: []
16
+ sharedPaths: [],
17
+ effectiveRecipients: {}
17
18
  });
18
19
  });
19
20
  it('should index received sharings', function () {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-sharing",
3
- "version": "37.5.4",
3
+ "version": "37.6.0",
4
4
  "description": "Provides sharing login for React applications.",
5
5
  "main": "dist/index.js",
6
6
  "author": "Cozy",
@@ -59,7 +59,7 @@
59
59
  "cozy-intent": "^2.31.1",
60
60
  "cozy-minilog": "^3.10.1",
61
61
  "cozy-ui": "^140.5.0",
62
- "cozy-ui-plus": "^12.3.13",
62
+ "cozy-ui-plus": "^12.3.15",
63
63
  "jest": "30.3.0",
64
64
  "jest-environment-jsdom": "30.3.0",
65
65
  "react": "16.12.0",
@@ -85,5 +85,5 @@
85
85
  "sideEffects": [
86
86
  "*.css"
87
87
  ],
88
- "gitHead": "0257cf0ecb129fec4b9d3f99e3a3fbb318429112"
88
+ "gitHead": "aa6c91c03a8b734177fddb3075aa26110516c218"
89
89
  }
@@ -9,6 +9,7 @@ import {
9
9
  } from './components/ShareRestrictionModal/helpers'
10
10
  import SharingContext from './context'
11
11
  import { fetchNextPermissions } from './fetchNextPermissions'
12
+ import { mapEffectiveRecipients } from './helpers/effectiveRecipients'
12
13
  import { fetchFilesPaths } from './helpers/files'
13
14
  import {
14
15
  getSharingObject,
@@ -28,6 +29,10 @@ import reducer, {
28
29
  revokeGroup as revokeGroupFromState,
29
30
  revokeSelf,
30
31
  receivePaths,
32
+ receiveEffectiveRecipients,
33
+ updateEffectiveRecipient,
34
+ invalidateEffectiveRecipients,
35
+ getEffectiveRecipients,
31
36
  isOwner,
32
37
  isSharedDrive,
33
38
  isOrgSharedDrive,
@@ -109,7 +114,11 @@ export class SharingProvider extends Component {
109
114
  refresh: this.fetchAllSharings,
110
115
  hasWriteAccess: this.hasWriteAccess,
111
116
  renameSharedDrive: this.renameSharedDrive,
112
- updateSharingMemberType: this.updateSharingMemberType
117
+ updateSharingMemberType: this.updateSharingMemberType,
118
+ getEffectiveRecipients: docId =>
119
+ getEffectiveRecipients(this.state, docId),
120
+ fetchEffectiveRecipients: this.fetchEffectiveRecipients,
121
+ invalidateEffectiveRecipients: this.invalidateEffectiveRecipients
113
122
  }
114
123
  this.isPublic = props.isPublic ?? false
115
124
  this.realtime = null
@@ -261,6 +270,11 @@ export class SharingProvider extends Component {
261
270
 
262
271
  await this.state.onShared({ document, recipients, readOnlyRecipients })
263
272
 
273
+ await this.fetchEffectiveRecipients(
274
+ getDocumentId(document),
275
+ document.driveId
276
+ )
277
+
264
278
  return sharingResult
265
279
  }
266
280
 
@@ -284,6 +298,10 @@ export class SharingProvider extends Component {
284
298
  )
285
299
 
286
300
  await this.state.onShared({ document, recipients, readOnlyRecipients })
301
+ await this.fetchEffectiveRecipients(
302
+ getDocumentId(document),
303
+ document.driveId
304
+ )
287
305
  return data
288
306
  }
289
307
 
@@ -318,6 +336,10 @@ export class SharingProvider extends Component {
318
336
  )
319
337
  )
320
338
  })
339
+ await this.fetchEffectiveRecipients(
340
+ getDocumentId(document),
341
+ document.driveId
342
+ )
321
343
  }
322
344
 
323
345
  revoke = async (document, sharingId, recipientIndex) => {
@@ -331,6 +353,10 @@ export class SharingProvider extends Component {
331
353
  document.path || (await fetchFilesPaths(client, doctype, [document]))
332
354
  )
333
355
  )
356
+ await this.fetchEffectiveRecipients(
357
+ getDocumentId(document),
358
+ document.driveId
359
+ )
334
360
  }
335
361
 
336
362
  revokeGroup = async (document, sharingId, recipientIndex) => {
@@ -350,6 +376,10 @@ export class SharingProvider extends Component {
350
376
  const sharing = getSharingForSelf(this.state, document.id)
351
377
  await this.sharingCol.revokeSelf(sharing)
352
378
  this.dispatch(revokeSelf(sharing))
379
+ await this.fetchEffectiveRecipients(
380
+ getDocumentId(document),
381
+ document.driveId
382
+ )
353
383
  }
354
384
 
355
385
  /**
@@ -386,6 +416,9 @@ export class SharingProvider extends Component {
386
416
  }
387
417
 
388
418
  this.dispatch(updateSharing(optimisticSharing))
419
+ this.dispatch(
420
+ updateEffectiveRecipient(sharingId, memberIndex, makeReadOnly)
421
+ )
389
422
 
390
423
  try {
391
424
  if (makeReadOnly) {
@@ -411,12 +444,39 @@ export class SharingProvider extends Component {
411
444
  }
412
445
 
413
446
  this.dispatch(updateSharing(rollbackSharing))
447
+ this.dispatch(
448
+ updateEffectiveRecipient(sharingId, memberIndex, !makeReadOnly)
449
+ )
414
450
  log.error(
415
451
  `Failed to change member ${member.email} permission type to ${newType}`,
416
452
  error
417
453
  )
418
454
  throw error
419
455
  }
456
+
457
+ const docId = Object.keys(this.state.byDocId).find(id =>
458
+ this.state.byDocId[id].sharings?.includes(sharingId)
459
+ )
460
+ if (docId) {
461
+ const driveId = this.state.byDocId[docId].driveId
462
+ await this.fetchEffectiveRecipients(docId, driveId)
463
+ }
464
+ }
465
+
466
+ fetchEffectiveRecipients = async (fileId, driveId) => {
467
+ const resp = await this.sharingCol.fetchEffectiveRecipients(fileId, {
468
+ driveId
469
+ })
470
+ this.dispatch(
471
+ receiveEffectiveRecipients(
472
+ fileId,
473
+ mapEffectiveRecipients(resp?.data || [])
474
+ )
475
+ )
476
+ }
477
+
478
+ invalidateEffectiveRecipients = docId => {
479
+ this.dispatch(invalidateEffectiveRecipients(docId))
420
480
  }
421
481
 
422
482
  shareByLink = async (document, options) => {