cozy-sharing 31.0.2 → 31.2.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 +30 -0
- package/dist/components/FederatedFolder/DumbFederatedFolderModal.js +15 -16
- package/dist/components/FederatedFolder/FederatedFolderModal.js +78 -103
- package/dist/components/FederatedFolder/FederatedFolderModal.spec.js +102 -292
- package/dist/components/Recipient/GroupRecipientPermissions.js +15 -11
- package/dist/components/Recipient/LinkRecipient.js +15 -11
- package/dist/components/Recipient/LinkRecipientLite.js +1 -1
- package/dist/components/Recipient/LinkRecipientPermissions.js +2 -1
- package/dist/components/Recipient/MemberRecipient.spec.js +8 -10
- package/dist/components/Recipient/MemberRecipientLite.js +1 -1
- package/dist/components/Recipient/MemberRecipientPermissions.js +16 -12
- package/dist/components/Recipient/MemberRecipientPermissions.spec.js +62 -50
- package/dist/components/Recipient/RecipientConfirm.js +0 -5
- package/dist/components/ShareAutosuggest.js +9 -4
- package/dist/components/ShareByEmail.js +29 -274
- package/dist/components/ShareByEmail.spec.js +52 -230
- package/dist/components/ShareByLink.js +1 -3
- package/dist/components/ShareDialogCozyToCozy.js +169 -35
- package/dist/components/ShareDialogCozyToCozy.spec.js +123 -36
- package/dist/components/ShareDialogTwoStepsConfirmationContainer.js +13 -3
- package/dist/components/ShareModal/SharingDetailsModal.js +0 -5
- package/dist/components/ShareRecipientsInput.js +6 -3
- package/dist/components/SharedDrive/SharedDriveForm.js +17 -25
- package/dist/components/SharedDrive/SharedDriveModal.js +1 -1
- package/dist/components/SharedDrive/SharedDriveRecipientPermissions.js +15 -10
- package/dist/components/SharedDrive/useSharedDrive.js +33 -57
- package/dist/components/SharedDrive/useSharedDrive.spec.js +29 -93
- package/dist/components/SharedFolder/DumbBatchSharedFolderModal.js +15 -26
- package/dist/components/Sharetypeselect.js +85 -90
- package/dist/hooks/usePendingRecipients.js +20 -0
- package/dist/hooks/usePendingRecipients.spec.js +30 -0
- package/dist/styles/autosuggest.styl +8 -2
- package/dist/styles/share.styl +0 -39
- package/dist/stylesheet.css +8 -36
- package/locales/en.json +14 -44
- package/locales/fr.json +14 -44
- package/locales/ru.json +14 -44
- package/locales/vi.json +14 -42
- package/package.json +2 -2
- package/src/components/FederatedFolder/DumbFederatedFolderModal.jsx +14 -15
- package/src/components/FederatedFolder/FederatedFolderModal.jsx +50 -67
- package/src/components/FederatedFolder/FederatedFolderModal.spec.jsx +63 -186
- package/src/components/Recipient/GroupRecipientPermissions.jsx +15 -13
- package/src/components/Recipient/LinkRecipient.jsx +9 -9
- package/src/components/Recipient/LinkRecipientLite.jsx +1 -3
- package/src/components/Recipient/LinkRecipientPermissions.jsx +2 -1
- package/src/components/Recipient/MemberRecipient.spec.jsx +4 -6
- package/src/components/Recipient/MemberRecipientLite.jsx +2 -2
- package/src/components/Recipient/MemberRecipientPermissions.jsx +16 -21
- package/src/components/Recipient/MemberRecipientPermissions.spec.jsx +21 -23
- package/src/components/ShareAutosuggest.jsx +7 -2
- package/src/components/ShareByEmail.jsx +35 -186
- package/src/components/ShareByEmail.spec.jsx +22 -173
- package/src/components/ShareByLink.jsx +1 -7
- package/src/components/ShareDialogCozyToCozy.jsx +171 -38
- package/src/components/ShareDialogCozyToCozy.spec.jsx +67 -1
- package/src/components/ShareDialogTwoStepsConfirmationContainer.jsx +11 -1
- package/src/components/ShareRecipientsInput.jsx +5 -2
- package/src/components/SharedDrive/SharedDriveForm.jsx +16 -25
- package/src/components/SharedDrive/SharedDriveModal.jsx +1 -1
- package/src/components/SharedDrive/SharedDriveRecipientPermissions.jsx +15 -17
- package/src/components/SharedDrive/useSharedDrive.js +24 -50
- package/src/components/SharedDrive/useSharedDrive.spec.js +19 -67
- package/src/components/SharedFolder/DumbBatchSharedFolderModal.jsx +15 -29
- package/src/components/Sharetypeselect.jsx +75 -58
- package/src/hooks/usePendingRecipients.js +13 -0
- package/src/hooks/usePendingRecipients.spec.js +21 -0
- package/src/styles/autosuggest.styl +8 -2
- package/src/styles/share.styl +0 -39
- package/dist/components/Recipient/actions/revokeGroup.js +0 -42
- package/dist/components/Recipient/actions/revokeMember.js +0 -42
- package/dist/components/Recipient/actions/revokeSharedDriveMember.js +0 -41
- package/dist/components/SharedDrive/helpers.js +0 -102
- package/dist/components/SharedDrive/helpers.spec.js +0 -227
- package/dist/components/Sharesubmit.js +0 -28
- package/src/components/Recipient/actions/revokeGroup.js +0 -42
- package/src/components/Recipient/actions/revokeMember.js +0 -42
- package/src/components/Recipient/actions/revokeSharedDriveMember.js +0 -41
- package/src/components/SharedDrive/helpers.js +0 -108
- package/src/components/SharedDrive/helpers.spec.js +0 -177
- package/src/components/Sharesubmit.jsx +0 -31
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
box-sizing border-box
|
|
6
6
|
position absolute
|
|
7
7
|
top 100%
|
|
8
|
-
margin-top .
|
|
8
|
+
margin-top .5rem
|
|
9
9
|
z-index var(--zIndex-alertMobile)
|
|
10
10
|
width 100%
|
|
11
11
|
overflow hidden
|
|
@@ -37,12 +37,13 @@
|
|
|
37
37
|
display flex
|
|
38
38
|
flex-wrap wrap
|
|
39
39
|
align-items center
|
|
40
|
-
padding .25rem .5rem
|
|
40
|
+
padding .25rem 3.5rem .25rem .5rem
|
|
41
41
|
border-radius .25rem
|
|
42
42
|
border 1px solid var(--borderMainColor)
|
|
43
43
|
min-height 2.5rem
|
|
44
44
|
max-height 6.75rem
|
|
45
45
|
overflow auto
|
|
46
|
+
position relative
|
|
46
47
|
|
|
47
48
|
&:hover
|
|
48
49
|
border 1px solid var(--borderMainColor)
|
|
@@ -69,3 +70,8 @@
|
|
|
69
70
|
font-size 1rem
|
|
70
71
|
.recipientChip
|
|
71
72
|
margin .25rem .5rem .25rem 0
|
|
73
|
+
|
|
74
|
+
.endAdornment
|
|
75
|
+
position absolute
|
|
76
|
+
top .75rem
|
|
77
|
+
right 1rem
|
package/src/styles/share.styl
CHANGED
|
@@ -38,45 +38,6 @@
|
|
|
38
38
|
.coz-form-desc
|
|
39
39
|
color var(--secondaryTextColor)
|
|
40
40
|
|
|
41
|
-
.share-type-control
|
|
42
|
-
display flex
|
|
43
|
-
flex-direction row
|
|
44
|
-
justify-content space-between
|
|
45
|
-
padding .5rem 0 0
|
|
46
|
-
|
|
47
|
-
.select-wrapper
|
|
48
|
-
flex 0 0 49%
|
|
49
|
-
position relative
|
|
50
|
-
|
|
51
|
-
.select-option
|
|
52
|
-
padding .5rem 1.5rem .5rem 3rem
|
|
53
|
-
position relative
|
|
54
|
-
|
|
55
|
-
svg
|
|
56
|
-
position absolute
|
|
57
|
-
left 1rem
|
|
58
|
-
top 1rem
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
.select-option-label
|
|
62
|
-
line-height 2
|
|
63
|
-
|
|
64
|
-
.select-option-desc
|
|
65
|
-
line-height 1.5
|
|
66
|
-
font-size .8125rem
|
|
67
|
-
color var(--secondaryTextColor)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
button
|
|
72
|
-
flex 0 0 49%
|
|
73
|
-
margin 0
|
|
74
|
-
|
|
75
|
-
:global
|
|
76
|
-
// dirty hack for react-select: its API doesn't allow to make change to active styles
|
|
77
|
-
.react-select__option:active
|
|
78
|
-
background-color var(--defaultBackgroundColor) !important
|
|
79
|
-
|
|
80
41
|
input[type=text]
|
|
81
42
|
width 100%
|
|
82
43
|
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
-
import React, { forwardRef } from 'react';
|
|
3
|
-
import ActionsMenuItem from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem';
|
|
4
|
-
import Icon from 'cozy-ui/transpiled/react/Icon';
|
|
5
|
-
import ForbiddenIcon from 'cozy-ui/transpiled/react/Icons/Forbidden';
|
|
6
|
-
import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon';
|
|
7
|
-
import ListItemText from 'cozy-ui/transpiled/react/ListItemText';
|
|
8
|
-
import Typography from 'cozy-ui/transpiled/react/Typography';
|
|
9
|
-
|
|
10
|
-
var revokeGroup = function revokeGroup(_ref) {
|
|
11
|
-
var t = _ref.t,
|
|
12
|
-
isOwner = _ref.isOwner,
|
|
13
|
-
isSharedDrive = _ref.isSharedDrive,
|
|
14
|
-
handleRevocation = _ref.handleRevocation;
|
|
15
|
-
var revokeType = isOwner ? 'revoke' : 'revokeSelf';
|
|
16
|
-
var title = t("RevokeGroupItem.".concat(revokeType, ".title"));
|
|
17
|
-
var desc = isOwner && isSharedDrive ? t("RevokeGroupItem.revoke.sharedDriveDesc") : t("RevokeGroupItem.".concat(revokeType, ".desc"));
|
|
18
|
-
var icon = ForbiddenIcon;
|
|
19
|
-
return {
|
|
20
|
-
name: 'revokeMember',
|
|
21
|
-
label: title,
|
|
22
|
-
icon: icon,
|
|
23
|
-
action: function action() {
|
|
24
|
-
handleRevocation();
|
|
25
|
-
},
|
|
26
|
-
Component: /*#__PURE__*/forwardRef(function RevokeMemberItem(props, ref) {
|
|
27
|
-
return /*#__PURE__*/React.createElement(ActionsMenuItem, _extends({}, props, {
|
|
28
|
-
ref: ref
|
|
29
|
-
}), /*#__PURE__*/React.createElement(ListItemIcon, null, /*#__PURE__*/React.createElement(Icon, {
|
|
30
|
-
icon: icon,
|
|
31
|
-
color: "var(--errorColor)"
|
|
32
|
-
})), /*#__PURE__*/React.createElement(ListItemText, {
|
|
33
|
-
primary: /*#__PURE__*/React.createElement(Typography, {
|
|
34
|
-
color: "error"
|
|
35
|
-
}, title),
|
|
36
|
-
secondary: desc
|
|
37
|
-
}));
|
|
38
|
-
})
|
|
39
|
-
};
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export { revokeGroup };
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
-
import React, { forwardRef } from 'react';
|
|
3
|
-
import ActionsMenuItem from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem';
|
|
4
|
-
import Icon from 'cozy-ui/transpiled/react/Icon';
|
|
5
|
-
import TrashIcon from 'cozy-ui/transpiled/react/Icons/Trash';
|
|
6
|
-
import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon';
|
|
7
|
-
import ListItemText from 'cozy-ui/transpiled/react/ListItemText';
|
|
8
|
-
import Typography from 'cozy-ui/transpiled/react/Typography';
|
|
9
|
-
|
|
10
|
-
var revokeMember = function revokeMember(_ref) {
|
|
11
|
-
var t = _ref.t,
|
|
12
|
-
isOwner = _ref.isOwner,
|
|
13
|
-
isSharedDrive = _ref.isSharedDrive,
|
|
14
|
-
handleRevocation = _ref.handleRevocation;
|
|
15
|
-
var revokeType = isOwner ? 'revoke' : 'revokeSelf';
|
|
16
|
-
var title = t("RevokeMemberItem.".concat(revokeType, ".title"));
|
|
17
|
-
var desc = isOwner && isSharedDrive ? t("RevokeMemberItem.revoke.sharedDriveDesc") : t("RevokeMemberItem.".concat(revokeType, ".desc"));
|
|
18
|
-
var icon = TrashIcon;
|
|
19
|
-
return {
|
|
20
|
-
name: 'revokeMember',
|
|
21
|
-
label: title,
|
|
22
|
-
icon: icon,
|
|
23
|
-
action: function action() {
|
|
24
|
-
handleRevocation();
|
|
25
|
-
},
|
|
26
|
-
Component: /*#__PURE__*/forwardRef(function RevokeMemberItem(props, ref) {
|
|
27
|
-
return /*#__PURE__*/React.createElement(ActionsMenuItem, _extends({}, props, {
|
|
28
|
-
ref: ref
|
|
29
|
-
}), /*#__PURE__*/React.createElement(ListItemIcon, null, /*#__PURE__*/React.createElement(Icon, {
|
|
30
|
-
icon: icon,
|
|
31
|
-
color: "var(--errorColor)"
|
|
32
|
-
})), /*#__PURE__*/React.createElement(ListItemText, {
|
|
33
|
-
primary: /*#__PURE__*/React.createElement(Typography, {
|
|
34
|
-
color: "error"
|
|
35
|
-
}, title),
|
|
36
|
-
secondary: desc
|
|
37
|
-
}));
|
|
38
|
-
})
|
|
39
|
-
};
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export { revokeMember };
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
-
import React, { forwardRef } from 'react';
|
|
3
|
-
import ActionsMenuItem from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem';
|
|
4
|
-
import Icon from 'cozy-ui/transpiled/react/Icon';
|
|
5
|
-
import TrashIcon from 'cozy-ui/transpiled/react/Icons/Trash';
|
|
6
|
-
import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon';
|
|
7
|
-
import ListItemText from 'cozy-ui/transpiled/react/ListItemText';
|
|
8
|
-
import Typography from 'cozy-ui/transpiled/react/Typography';
|
|
9
|
-
|
|
10
|
-
var makeComponent = function makeComponent(title) {
|
|
11
|
-
var Component = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
12
|
-
return /*#__PURE__*/React.createElement(ActionsMenuItem, _extends({}, props, {
|
|
13
|
-
ref: ref
|
|
14
|
-
}), /*#__PURE__*/React.createElement(ListItemIcon, null, /*#__PURE__*/React.createElement(Icon, {
|
|
15
|
-
icon: TrashIcon,
|
|
16
|
-
color: "var(--errorColor)"
|
|
17
|
-
})), /*#__PURE__*/React.createElement(ListItemText, {
|
|
18
|
-
primary: /*#__PURE__*/React.createElement(Typography, {
|
|
19
|
-
color: "error"
|
|
20
|
-
}, title)
|
|
21
|
-
}));
|
|
22
|
-
});
|
|
23
|
-
Component.displayName = 'RevokeSharedDriveMember';
|
|
24
|
-
return Component;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
var revokeSharedDriveMember = function revokeSharedDriveMember(_ref) {
|
|
28
|
-
var t = _ref.t,
|
|
29
|
-
handleRevocation = _ref.handleRevocation;
|
|
30
|
-
var title = t("RevokeSharedDriveMemberItem.revoke.title");
|
|
31
|
-
return {
|
|
32
|
-
name: 'revokeSharedDriveMember',
|
|
33
|
-
label: title,
|
|
34
|
-
action: function action() {
|
|
35
|
-
handleRevocation();
|
|
36
|
-
},
|
|
37
|
-
Component: makeComponent(title)
|
|
38
|
-
};
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
export { revokeSharedDriveMember };
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
|
-
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
3
|
-
|
|
4
|
-
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; }
|
|
5
|
-
|
|
6
|
-
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; }
|
|
7
|
-
|
|
8
|
-
import { models } from 'cozy-client';
|
|
9
|
-
var ContactModel = models.contact;
|
|
10
|
-
export var RECIPIENT_INDEX_PREFIX = 'virtual-shared-drive-sharing-';
|
|
11
|
-
export var mergeAndDeduplicateRecipients = function mergeAndDeduplicateRecipients(arrays) {
|
|
12
|
-
var combinedArray = arrays.flat().map(function (item) {
|
|
13
|
-
return _objectSpread(_objectSpread({}, item), {}, {
|
|
14
|
-
id: item.id || item._id
|
|
15
|
-
});
|
|
16
|
-
});
|
|
17
|
-
var seenIds = new Set();
|
|
18
|
-
var uniqueArray = combinedArray.reduce(function (acc, item) {
|
|
19
|
-
var id = item.id || item._id;
|
|
20
|
-
|
|
21
|
-
if (id == null) {
|
|
22
|
-
// Recipients without any identifier are kept as-is to avoid silent data loss
|
|
23
|
-
acc.push(item);
|
|
24
|
-
return acc;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (!seenIds.has(id)) {
|
|
28
|
-
seenIds.add(id); // Ensure both id and _id exist for downstream compatibility
|
|
29
|
-
|
|
30
|
-
var normalizedItem = !item.id || !item._id ? _objectSpread(_objectSpread({}, item), {}, {
|
|
31
|
-
id: item.id || item._id,
|
|
32
|
-
_id: item._id || item.id
|
|
33
|
-
}) : item;
|
|
34
|
-
acc.push(normalizedItem);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return acc;
|
|
38
|
-
}, []);
|
|
39
|
-
return uniqueArray;
|
|
40
|
-
};
|
|
41
|
-
export var moveRecipientToReadWrite = function moveRecipientToReadWrite(federatedRecipients, _id) {
|
|
42
|
-
var recipientToMove = federatedRecipients.readOnlyRecipients.find(function (r) {
|
|
43
|
-
return r._id === _id;
|
|
44
|
-
});
|
|
45
|
-
if (!recipientToMove) return federatedRecipients;
|
|
46
|
-
return {
|
|
47
|
-
recipients: [].concat(_toConsumableArray(federatedRecipients.recipients), [recipientToMove]),
|
|
48
|
-
readOnlyRecipients: federatedRecipients.readOnlyRecipients.filter(function (r) {
|
|
49
|
-
return r._id !== _id;
|
|
50
|
-
})
|
|
51
|
-
};
|
|
52
|
-
};
|
|
53
|
-
export var moveRecipientToReadOnly = function moveRecipientToReadOnly(federatedRecipients, _id) {
|
|
54
|
-
var recipientToMove = federatedRecipients.recipients.find(function (r) {
|
|
55
|
-
return r._id === _id;
|
|
56
|
-
});
|
|
57
|
-
if (!recipientToMove) return federatedRecipients;
|
|
58
|
-
return {
|
|
59
|
-
recipients: federatedRecipients.recipients.filter(function (r) {
|
|
60
|
-
return r._id !== _id;
|
|
61
|
-
}),
|
|
62
|
-
readOnlyRecipients: [].concat(_toConsumableArray(federatedRecipients.readOnlyRecipients), [recipientToMove])
|
|
63
|
-
};
|
|
64
|
-
};
|
|
65
|
-
export var formatRecipients = function formatRecipients(sharedDriveRecipients) {
|
|
66
|
-
var recipients = [];
|
|
67
|
-
sharedDriveRecipients.recipients.forEach(function (r) {
|
|
68
|
-
recipients.push({
|
|
69
|
-
index: "".concat(RECIPIENT_INDEX_PREFIX).concat(r._id),
|
|
70
|
-
email: ContactModel.getPrimaryEmail(r),
|
|
71
|
-
public_name: ContactModel.getDisplayName(r),
|
|
72
|
-
memberIndex: r._id,
|
|
73
|
-
type: 'two-way',
|
|
74
|
-
members: r.members
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
sharedDriveRecipients.readOnlyRecipients.forEach(function (r) {
|
|
78
|
-
recipients.push({
|
|
79
|
-
index: "".concat(RECIPIENT_INDEX_PREFIX).concat(r._id),
|
|
80
|
-
email: ContactModel.getPrimaryEmail(r),
|
|
81
|
-
public_name: ContactModel.getDisplayName(r),
|
|
82
|
-
memberIndex: r._id,
|
|
83
|
-
type: 'one-way',
|
|
84
|
-
members: r.members
|
|
85
|
-
});
|
|
86
|
-
}); // We need to sort recipients by public_name
|
|
87
|
-
// to avoid reording them every time we change
|
|
88
|
-
// them from read only to read write.
|
|
89
|
-
|
|
90
|
-
recipients.sort(function (a, b) {
|
|
91
|
-
if (a.public_name < b.public_name) {
|
|
92
|
-
return -1;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
if (a.public_name > b.public_name) {
|
|
96
|
-
return 1;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
return 0;
|
|
100
|
-
});
|
|
101
|
-
return recipients;
|
|
102
|
-
};
|
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
import { mergeAndDeduplicateRecipients, moveRecipientToReadWrite, moveRecipientToReadOnly, formatRecipients, RECIPIENT_INDEX_PREFIX } from './helpers';
|
|
2
|
-
describe('mergeAndDeduplicateRecipients', function () {
|
|
3
|
-
it('should merge multiple arrays into one', function () {
|
|
4
|
-
var result = mergeAndDeduplicateRecipients([[{
|
|
5
|
-
id: '1',
|
|
6
|
-
name: 'Alice'
|
|
7
|
-
}], [{
|
|
8
|
-
id: '2',
|
|
9
|
-
name: 'Bob'
|
|
10
|
-
}]]);
|
|
11
|
-
expect(result).toEqual([{
|
|
12
|
-
id: '1',
|
|
13
|
-
_id: '1',
|
|
14
|
-
name: 'Alice'
|
|
15
|
-
}, {
|
|
16
|
-
id: '2',
|
|
17
|
-
_id: '2',
|
|
18
|
-
name: 'Bob'
|
|
19
|
-
}]);
|
|
20
|
-
});
|
|
21
|
-
it('should deduplicate recipients with the same id', function () {
|
|
22
|
-
var result = mergeAndDeduplicateRecipients([[{
|
|
23
|
-
id: '1',
|
|
24
|
-
name: 'Alice'
|
|
25
|
-
}], [{
|
|
26
|
-
id: '1',
|
|
27
|
-
name: 'Alice'
|
|
28
|
-
}]]);
|
|
29
|
-
expect(result).toEqual([{
|
|
30
|
-
id: '1',
|
|
31
|
-
_id: '1',
|
|
32
|
-
name: 'Alice'
|
|
33
|
-
}]);
|
|
34
|
-
});
|
|
35
|
-
it('should normalize _id to id for deduplication', function () {
|
|
36
|
-
var result = mergeAndDeduplicateRecipients([[{
|
|
37
|
-
_id: '1',
|
|
38
|
-
name: 'Alice'
|
|
39
|
-
}], [{
|
|
40
|
-
_id: '2',
|
|
41
|
-
name: 'Bob'
|
|
42
|
-
}]]);
|
|
43
|
-
expect(result).toEqual([{
|
|
44
|
-
_id: '1',
|
|
45
|
-
id: '1',
|
|
46
|
-
name: 'Alice'
|
|
47
|
-
}, {
|
|
48
|
-
_id: '2',
|
|
49
|
-
id: '2',
|
|
50
|
-
name: 'Bob'
|
|
51
|
-
}]);
|
|
52
|
-
});
|
|
53
|
-
it('should deduplicate recipients when one has id and the other has _id', function () {
|
|
54
|
-
var result = mergeAndDeduplicateRecipients([[{
|
|
55
|
-
id: '1',
|
|
56
|
-
name: 'Alice'
|
|
57
|
-
}], [{
|
|
58
|
-
_id: '1',
|
|
59
|
-
name: 'Alice'
|
|
60
|
-
}]]);
|
|
61
|
-
expect(result).toEqual([{
|
|
62
|
-
id: '1',
|
|
63
|
-
_id: '1',
|
|
64
|
-
name: 'Alice'
|
|
65
|
-
}]);
|
|
66
|
-
});
|
|
67
|
-
it('should prefer existing id over _id when both are present', function () {
|
|
68
|
-
var result = mergeAndDeduplicateRecipients([[{
|
|
69
|
-
id: 'real-id',
|
|
70
|
-
_id: 'other-id',
|
|
71
|
-
name: 'Alice'
|
|
72
|
-
}]]);
|
|
73
|
-
expect(result).toEqual([{
|
|
74
|
-
id: 'real-id',
|
|
75
|
-
_id: 'other-id',
|
|
76
|
-
name: 'Alice'
|
|
77
|
-
}]);
|
|
78
|
-
});
|
|
79
|
-
it('should handle empty arrays', function () {
|
|
80
|
-
var result = mergeAndDeduplicateRecipients([[], []]);
|
|
81
|
-
expect(result).toEqual([]);
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
describe('moveRecipientToReadWrite', function () {
|
|
85
|
-
it('should move a recipient from readOnly to readWrite', function () {
|
|
86
|
-
var state = {
|
|
87
|
-
recipients: [{
|
|
88
|
-
_id: '1',
|
|
89
|
-
name: 'Alice'
|
|
90
|
-
}],
|
|
91
|
-
readOnlyRecipients: [{
|
|
92
|
-
_id: '2',
|
|
93
|
-
name: 'Bob'
|
|
94
|
-
}]
|
|
95
|
-
};
|
|
96
|
-
var result = moveRecipientToReadWrite(state, '2');
|
|
97
|
-
expect(result.recipients).toEqual([{
|
|
98
|
-
_id: '1',
|
|
99
|
-
name: 'Alice'
|
|
100
|
-
}, {
|
|
101
|
-
_id: '2',
|
|
102
|
-
name: 'Bob'
|
|
103
|
-
}]);
|
|
104
|
-
expect(result.readOnlyRecipients).toEqual([]);
|
|
105
|
-
});
|
|
106
|
-
it('should return unchanged state if recipient not found', function () {
|
|
107
|
-
var state = {
|
|
108
|
-
recipients: [{
|
|
109
|
-
_id: '1',
|
|
110
|
-
name: 'Alice'
|
|
111
|
-
}],
|
|
112
|
-
readOnlyRecipients: []
|
|
113
|
-
};
|
|
114
|
-
var result = moveRecipientToReadWrite(state, '999');
|
|
115
|
-
expect(result).toBe(state);
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
describe('moveRecipientToReadOnly', function () {
|
|
119
|
-
it('should move a recipient from readWrite to readOnly', function () {
|
|
120
|
-
var state = {
|
|
121
|
-
recipients: [{
|
|
122
|
-
_id: '1',
|
|
123
|
-
name: 'Alice'
|
|
124
|
-
}],
|
|
125
|
-
readOnlyRecipients: [{
|
|
126
|
-
_id: '2',
|
|
127
|
-
name: 'Bob'
|
|
128
|
-
}]
|
|
129
|
-
};
|
|
130
|
-
var result = moveRecipientToReadOnly(state, '1');
|
|
131
|
-
expect(result.recipients).toEqual([]);
|
|
132
|
-
expect(result.readOnlyRecipients).toEqual([{
|
|
133
|
-
_id: '2',
|
|
134
|
-
name: 'Bob'
|
|
135
|
-
}, {
|
|
136
|
-
_id: '1',
|
|
137
|
-
name: 'Alice'
|
|
138
|
-
}]);
|
|
139
|
-
});
|
|
140
|
-
it('should return unchanged state if recipient not found', function () {
|
|
141
|
-
var state = {
|
|
142
|
-
recipients: [],
|
|
143
|
-
readOnlyRecipients: [{
|
|
144
|
-
_id: '1',
|
|
145
|
-
name: 'Alice'
|
|
146
|
-
}]
|
|
147
|
-
};
|
|
148
|
-
var result = moveRecipientToReadOnly(state, '999');
|
|
149
|
-
expect(result).toBe(state);
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
describe('formatRecipients', function () {
|
|
153
|
-
it('should format readWrite and readOnly recipients with correct types', function () {
|
|
154
|
-
var input = {
|
|
155
|
-
recipients: [{
|
|
156
|
-
_id: '1',
|
|
157
|
-
displayName: 'Alice',
|
|
158
|
-
email: [{
|
|
159
|
-
address: 'alice@example.com',
|
|
160
|
-
primary: true
|
|
161
|
-
}]
|
|
162
|
-
}],
|
|
163
|
-
readOnlyRecipients: [{
|
|
164
|
-
_id: '2',
|
|
165
|
-
displayName: 'Bob',
|
|
166
|
-
email: [{
|
|
167
|
-
address: 'bob@example.com',
|
|
168
|
-
primary: true
|
|
169
|
-
}]
|
|
170
|
-
}]
|
|
171
|
-
};
|
|
172
|
-
var result = formatRecipients(input);
|
|
173
|
-
expect(result).toHaveLength(2);
|
|
174
|
-
expect(result[0]).toMatchObject({
|
|
175
|
-
index: "".concat(RECIPIENT_INDEX_PREFIX, "1"),
|
|
176
|
-
type: 'two-way',
|
|
177
|
-
public_name: 'Alice'
|
|
178
|
-
});
|
|
179
|
-
expect(result[1]).toMatchObject({
|
|
180
|
-
index: "".concat(RECIPIENT_INDEX_PREFIX, "2"),
|
|
181
|
-
type: 'one-way',
|
|
182
|
-
public_name: 'Bob'
|
|
183
|
-
});
|
|
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
|
-
});
|
|
204
|
-
it('should sort recipients by public_name', function () {
|
|
205
|
-
var input = {
|
|
206
|
-
recipients: [{
|
|
207
|
-
_id: '1',
|
|
208
|
-
displayName: 'Zara',
|
|
209
|
-
email: [{
|
|
210
|
-
address: 'zara@example.com',
|
|
211
|
-
primary: true
|
|
212
|
-
}]
|
|
213
|
-
}, {
|
|
214
|
-
_id: '2',
|
|
215
|
-
displayName: 'Alice',
|
|
216
|
-
email: [{
|
|
217
|
-
address: 'alice@example.com',
|
|
218
|
-
primary: true
|
|
219
|
-
}]
|
|
220
|
-
}],
|
|
221
|
-
readOnlyRecipients: []
|
|
222
|
-
};
|
|
223
|
-
var result = formatRecipients(input);
|
|
224
|
-
expect(result[0].public_name).toBe('Alice');
|
|
225
|
-
expect(result[1].public_name).toBe('Zara');
|
|
226
|
-
});
|
|
227
|
-
});
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import PropTypes from 'prop-types';
|
|
2
|
-
import React from 'react';
|
|
3
|
-
import Button from 'cozy-ui/transpiled/react/Buttons';
|
|
4
|
-
|
|
5
|
-
var ShareSubmit = function ShareSubmit(props) {
|
|
6
|
-
return /*#__PURE__*/React.createElement(Button, {
|
|
7
|
-
onClick: function onClick() {
|
|
8
|
-
props.onSubmit();
|
|
9
|
-
},
|
|
10
|
-
size: "large",
|
|
11
|
-
busy: props.loading,
|
|
12
|
-
label: props.label,
|
|
13
|
-
disabled: props.disabled,
|
|
14
|
-
variant: "ghost"
|
|
15
|
-
});
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
ShareSubmit.propTypes = {
|
|
19
|
-
onSubmit: PropTypes.func.isRequired,
|
|
20
|
-
label: PropTypes.string,
|
|
21
|
-
loading: PropTypes.bool,
|
|
22
|
-
disabled: PropTypes.bool
|
|
23
|
-
};
|
|
24
|
-
ShareSubmit.defaultProps = {
|
|
25
|
-
label: 'Submit',
|
|
26
|
-
loading: false
|
|
27
|
-
};
|
|
28
|
-
export default ShareSubmit;
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import React, { forwardRef } from 'react'
|
|
2
|
-
|
|
3
|
-
import ActionsMenuItem from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem'
|
|
4
|
-
import Icon from 'cozy-ui/transpiled/react/Icon'
|
|
5
|
-
import ForbiddenIcon from 'cozy-ui/transpiled/react/Icons/Forbidden'
|
|
6
|
-
import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon'
|
|
7
|
-
import ListItemText from 'cozy-ui/transpiled/react/ListItemText'
|
|
8
|
-
import Typography from 'cozy-ui/transpiled/react/Typography'
|
|
9
|
-
|
|
10
|
-
const revokeGroup = ({ t, isOwner, isSharedDrive, handleRevocation }) => {
|
|
11
|
-
const revokeType = isOwner ? 'revoke' : 'revokeSelf'
|
|
12
|
-
const title = t(`RevokeGroupItem.${revokeType}.title`)
|
|
13
|
-
const desc =
|
|
14
|
-
isOwner && isSharedDrive
|
|
15
|
-
? t(`RevokeGroupItem.revoke.sharedDriveDesc`)
|
|
16
|
-
: t(`RevokeGroupItem.${revokeType}.desc`)
|
|
17
|
-
|
|
18
|
-
const icon = ForbiddenIcon
|
|
19
|
-
|
|
20
|
-
return {
|
|
21
|
-
name: 'revokeMember',
|
|
22
|
-
label: title,
|
|
23
|
-
icon,
|
|
24
|
-
action: () => {
|
|
25
|
-
handleRevocation()
|
|
26
|
-
},
|
|
27
|
-
Component: forwardRef(function RevokeMemberItem(props, ref) {
|
|
28
|
-
return (
|
|
29
|
-
<ActionsMenuItem {...props} ref={ref}>
|
|
30
|
-
<ListItemIcon>
|
|
31
|
-
<Icon icon={icon} color="var(--errorColor)" />
|
|
32
|
-
</ListItemIcon>
|
|
33
|
-
<ListItemText
|
|
34
|
-
primary={<Typography color="error">{title}</Typography>}
|
|
35
|
-
secondary={desc}
|
|
36
|
-
/>
|
|
37
|
-
</ActionsMenuItem>
|
|
38
|
-
)
|
|
39
|
-
})
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
export { revokeGroup }
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import React, { forwardRef } from 'react'
|
|
2
|
-
|
|
3
|
-
import ActionsMenuItem from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem'
|
|
4
|
-
import Icon from 'cozy-ui/transpiled/react/Icon'
|
|
5
|
-
import TrashIcon from 'cozy-ui/transpiled/react/Icons/Trash'
|
|
6
|
-
import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon'
|
|
7
|
-
import ListItemText from 'cozy-ui/transpiled/react/ListItemText'
|
|
8
|
-
import Typography from 'cozy-ui/transpiled/react/Typography'
|
|
9
|
-
|
|
10
|
-
const revokeMember = ({ t, isOwner, isSharedDrive, handleRevocation }) => {
|
|
11
|
-
const revokeType = isOwner ? 'revoke' : 'revokeSelf'
|
|
12
|
-
const title = t(`RevokeMemberItem.${revokeType}.title`)
|
|
13
|
-
const desc =
|
|
14
|
-
isOwner && isSharedDrive
|
|
15
|
-
? t(`RevokeMemberItem.revoke.sharedDriveDesc`)
|
|
16
|
-
: t(`RevokeMemberItem.${revokeType}.desc`)
|
|
17
|
-
|
|
18
|
-
const icon = TrashIcon
|
|
19
|
-
|
|
20
|
-
return {
|
|
21
|
-
name: 'revokeMember',
|
|
22
|
-
label: title,
|
|
23
|
-
icon,
|
|
24
|
-
action: () => {
|
|
25
|
-
handleRevocation()
|
|
26
|
-
},
|
|
27
|
-
Component: forwardRef(function RevokeMemberItem(props, ref) {
|
|
28
|
-
return (
|
|
29
|
-
<ActionsMenuItem {...props} ref={ref}>
|
|
30
|
-
<ListItemIcon>
|
|
31
|
-
<Icon icon={icon} color="var(--errorColor)" />
|
|
32
|
-
</ListItemIcon>
|
|
33
|
-
<ListItemText
|
|
34
|
-
primary={<Typography color="error">{title}</Typography>}
|
|
35
|
-
secondary={desc}
|
|
36
|
-
/>
|
|
37
|
-
</ActionsMenuItem>
|
|
38
|
-
)
|
|
39
|
-
})
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
export { revokeMember }
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import React, { forwardRef } from 'react'
|
|
2
|
-
|
|
3
|
-
import ActionsMenuItem from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem'
|
|
4
|
-
import Icon from 'cozy-ui/transpiled/react/Icon'
|
|
5
|
-
import TrashIcon from 'cozy-ui/transpiled/react/Icons/Trash'
|
|
6
|
-
import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon'
|
|
7
|
-
import ListItemText from 'cozy-ui/transpiled/react/ListItemText'
|
|
8
|
-
import Typography from 'cozy-ui/transpiled/react/Typography'
|
|
9
|
-
|
|
10
|
-
const makeComponent = title => {
|
|
11
|
-
const Component = forwardRef((props, ref) => {
|
|
12
|
-
return (
|
|
13
|
-
<ActionsMenuItem {...props} ref={ref}>
|
|
14
|
-
<ListItemIcon>
|
|
15
|
-
<Icon icon={TrashIcon} color="var(--errorColor)" />
|
|
16
|
-
</ListItemIcon>
|
|
17
|
-
<ListItemText
|
|
18
|
-
primary={<Typography color="error">{title}</Typography>}
|
|
19
|
-
/>
|
|
20
|
-
</ActionsMenuItem>
|
|
21
|
-
)
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
Component.displayName = 'RevokeSharedDriveMember'
|
|
25
|
-
|
|
26
|
-
return Component
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const revokeSharedDriveMember = ({ t, handleRevocation }) => {
|
|
30
|
-
const title = t(`RevokeSharedDriveMemberItem.revoke.title`)
|
|
31
|
-
|
|
32
|
-
return {
|
|
33
|
-
name: 'revokeSharedDriveMember',
|
|
34
|
-
label: title,
|
|
35
|
-
action: () => {
|
|
36
|
-
handleRevocation()
|
|
37
|
-
},
|
|
38
|
-
Component: makeComponent(title)
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
export { revokeSharedDriveMember }
|