cozy-sharing 12.3.0 → 13.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.
Files changed (65) hide show
  1. package/.storybook/preview.jsx +1 -0
  2. package/CHANGELOG.md +29 -0
  3. package/dist/components/ContactSuggestion.js +7 -3
  4. package/dist/components/ContactSuggestion.spec.js +7 -1
  5. package/dist/components/Recipient/GroupRecipient.js +14 -7
  6. package/dist/components/Recipient/GroupRecipientDetail.js +4 -2
  7. package/dist/components/Recipient/GroupRecipientDetailWithAccess.js +9 -11
  8. package/dist/components/Recipient/GroupRecipientDetailWithoutAccess.js +8 -4
  9. package/dist/components/Recipient/GroupRecipientPermissions.js +3 -6
  10. package/dist/components/Recipient/MemberRecipient.js +1 -2
  11. package/dist/components/Recipient/MemberRecipientPermissions.js +1 -1
  12. package/dist/components/ShareAutosuggest.js +16 -9
  13. package/dist/components/ShareAutosuggest.spec.js +38 -13
  14. package/dist/components/ShareAutosuggest.stories.js +61 -0
  15. package/dist/components/ShareByEmail.js +15 -15
  16. package/dist/components/ShareByEmail.spec.js +0 -6
  17. package/dist/components/ShareDialogCozyToCozy.js +1 -5
  18. package/dist/components/ShareDialogCozyToCozy.spec.js +0 -61
  19. package/dist/components/ShareDialogTwoStepsConfirmationContainer.js +1 -5
  20. package/dist/components/ShareDialogTwoStepsConfirmationContainer.spec.js +0 -61
  21. package/dist/components/ShareModal/EditableSharingModal.js +3 -10
  22. package/dist/components/ShareModal/EditableSharingModal.spec.js +0 -6
  23. package/dist/components/ShareModal.js +1 -8
  24. package/dist/components/ShareRecipientsInput.js +46 -49
  25. package/dist/components/ShareRecipientsInput.spec.js +120 -144
  26. package/dist/helpers/contacts.js +12 -1
  27. package/dist/helpers/recipients.js +16 -9
  28. package/dist/helpers/successMessage.js +58 -16
  29. package/dist/helpers/successMessage.spec.js +122 -57
  30. package/dist/queries/queries.js +37 -5
  31. package/dist/styles/autosuggest.styl +2 -1
  32. package/dist/stylesheet.css +2 -1
  33. package/locales/en.json +23 -10
  34. package/locales/fr.json +23 -8
  35. package/package.json +4 -4
  36. package/src/components/ContactSuggestion.jsx +9 -3
  37. package/src/components/ContactSuggestion.spec.jsx +10 -1
  38. package/src/components/Recipient/GroupRecipient.jsx +17 -10
  39. package/src/components/Recipient/GroupRecipientDetail.jsx +5 -2
  40. package/src/components/Recipient/GroupRecipientDetailWithAccess.jsx +9 -14
  41. package/src/components/Recipient/GroupRecipientDetailWithoutAccess.jsx +8 -3
  42. package/src/components/Recipient/GroupRecipientPermissions.jsx +3 -8
  43. package/src/components/Recipient/MemberRecipient.jsx +4 -3
  44. package/src/components/Recipient/MemberRecipientPermissions.jsx +1 -1
  45. package/src/components/ShareAutosuggest.jsx +16 -11
  46. package/src/components/ShareAutosuggest.spec.jsx +31 -10
  47. package/src/components/ShareAutosuggest.stories.jsx +63 -0
  48. package/src/components/ShareByEmail.jsx +11 -11
  49. package/src/components/ShareByEmail.spec.jsx +0 -4
  50. package/src/components/ShareDialogCozyToCozy.jsx +0 -4
  51. package/src/components/ShareDialogCozyToCozy.spec.jsx +0 -67
  52. package/src/components/ShareDialogTwoStepsConfirmationContainer.jsx +0 -4
  53. package/src/components/ShareDialogTwoStepsConfirmationContainer.spec.jsx +0 -67
  54. package/src/components/ShareModal/EditableSharingModal.jsx +3 -21
  55. package/src/components/ShareModal/EditableSharingModal.spec.jsx +0 -2
  56. package/src/components/ShareModal.jsx +1 -7
  57. package/src/components/ShareRecipientsInput.jsx +84 -52
  58. package/src/components/ShareRecipientsInput.spec.jsx +140 -145
  59. package/src/helpers/contacts.js +8 -0
  60. package/src/helpers/recipients.js +24 -15
  61. package/src/helpers/successMessage.js +71 -21
  62. package/src/helpers/successMessage.spec.js +129 -69
  63. package/src/queries/queries.js +36 -5
  64. package/src/styles/autosuggest.styl +2 -1
  65. package/test/AppLike.jsx +6 -3
@@ -3,6 +3,7 @@ import React from "react";
3
3
  import 'cozy-ui/dist/cozy-ui.min.css'
4
4
  import 'cozy-ui/dist/cozy-ui.utils.min.css'
5
5
  import 'cozy-ui/transpiled/react/stylesheet.css'
6
+ import '../dist/stylesheet.css'
6
7
 
7
8
  import I18n from 'cozy-ui/transpiled/react/providers/I18n'
8
9
  import { BreakpointsProvider } from 'cozy-ui/transpiled/react/providers/Breakpoints'
package/CHANGELOG.md CHANGED
@@ -3,6 +3,35 @@
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
+ # [13.0.0](https://github.com/cozy/cozy-libs/compare/cozy-sharing@12.3.0...cozy-sharing@13.0.0) (2024-04-08)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **GroupRecipientDetail:** Improve member display ([2bb65cf](https://github.com/cozy/cozy-libs/commit/2bb65cf5218781845a5587433952437b3c764b97))
12
+ * Improve secondary text of GroupRecipient ([d747f9c](https://github.com/cozy/cozy-libs/commit/d747f9c6ad30701c16b9f888d4aee7729a5fc28b))
13
+ * Remove translation error when there is no type like for owner ([830d5fa](https://github.com/cozy/cozy-libs/commit/830d5faaaea118189f574d6cec859ba361ee4cd5))
14
+ * **ShareAutosuggest:** Align correctly loading state ([9d93952](https://github.com/cozy/cozy-libs/commit/9d93952b1740c6974da0ced62bd81d1990311b40))
15
+ * Show all the members from a group even unreachable ones ([e62ec59](https://github.com/cozy/cozy-libs/commit/e62ec5980bcb037a2af28cb64d522abdc9fa0408))
16
+ * Show group avatar into share input ([632658a](https://github.com/cozy/cozy-libs/commit/632658af64a8b8f1bcd4ba72d9b0e563d9a8dfdd))
17
+ * Show permissions when the current user is inside members ([d28d4b4](https://github.com/cozy/cozy-libs/commit/d28d4b46938aafddb39884511e7859d800e953b8))
18
+
19
+
20
+ ### Features
21
+
22
+ * Improve the message of success to integrate the notion of groups ([f0945b7](https://github.com/cozy/cozy-libs/commit/f0945b7e054a14d35e5d689f9db65c53df0286c6))
23
+ * **ShareRecipientsInput:** Simplify loading state ([e2ec136](https://github.com/cozy/cozy-libs/commit/e2ec136363df578bec338fde9336ac09ed573bb1))
24
+ * Update cozy-ui from 103.8.2 to 105.3.1 ([e1b21f8](https://github.com/cozy/cozy-libs/commit/e1b21f887fb55e5ddab7348f3f5fd41631318cdf))
25
+
26
+
27
+ ### BREAKING CHANGES
28
+
29
+ * you must have `cozy-ui >= 105.3.1`
30
+
31
+
32
+
33
+
34
+
6
35
  # [12.3.0](https://github.com/cozy/cozy-libs/compare/cozy-sharing@12.2.0...cozy-sharing@12.3.0) (2024-03-25)
7
36
 
8
37
 
@@ -6,6 +6,7 @@ import ListItem from 'cozy-ui/transpiled/react/ListItem';
6
6
  import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon';
7
7
  import ListItemText from 'cozy-ui/transpiled/react/ListItemText';
8
8
  import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n';
9
+ import { GroupAvatar } from './Avatar/GroupAvatar';
9
10
  import { Contact, Group, getDisplayName, getInitials } from '../models';
10
11
  var ContactModel = models.contact;
11
12
  export var ContactSuggestion = function ContactSuggestion(_ref) {
@@ -15,12 +16,13 @@ export var ContactSuggestion = function ContactSuggestion(_ref) {
15
16
  t = _useI18n.t;
16
17
 
17
18
  var avatarText, name, details;
19
+ var isContactGroup = contactOrGroup._type === Group.doctype;
18
20
 
19
- if (contactOrGroup._type === Group.doctype) {
21
+ if (isContactGroup) {
20
22
  name = contactOrGroup.name;
21
23
  avatarText = 'G';
22
24
  details = t('Share.members.count', {
23
- smart_count: contactOrGroup.membersCount.toString()
25
+ smart_count: contactOrGroup.members.length.toString()
24
26
  });
25
27
  } else {
26
28
  name = getDisplayName(contactOrGroup);
@@ -30,7 +32,9 @@ export var ContactSuggestion = function ContactSuggestion(_ref) {
30
32
 
31
33
  return /*#__PURE__*/React.createElement(ListItem, {
32
34
  button: true
33
- }, /*#__PURE__*/React.createElement(ListItemIcon, null, /*#__PURE__*/React.createElement(Avatar, {
35
+ }, /*#__PURE__*/React.createElement(ListItemIcon, null, isContactGroup ? /*#__PURE__*/React.createElement(GroupAvatar, {
36
+ size: "small"
37
+ }) : /*#__PURE__*/React.createElement(Avatar, {
34
38
  text: avatarText,
35
39
  size: "small"
36
40
  })), /*#__PURE__*/React.createElement(ListItemText, {
@@ -57,7 +57,13 @@ describe('ContactSuggestion component', function () {
57
57
  _id: '610718e6-2d7a',
58
58
  name: "The Night's Watch",
59
59
  _type: 'io.cozy.contacts.groups',
60
- membersCount: 2
60
+ members: [{
61
+ _id: 'f3a4e501-abbd',
62
+ fullname: 'Jon Snow'
63
+ }, {
64
+ _id: 'ab23a451-tzas',
65
+ fullname: 'Samwell Tarly'
66
+ }]
61
67
  };
62
68
  setup({
63
69
  contactOrGroup: theNightsWatch
@@ -1,3 +1,4 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
1
2
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
3
  import React, { useState } from 'react';
3
4
  import { useClient } from 'cozy-client';
@@ -11,14 +12,15 @@ import useBreakpoints from 'cozy-ui/transpiled/react/providers/Breakpoints';
11
12
  import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n';
12
13
  import { GroupRecipientDetail } from './GroupRecipientDetail';
13
14
  import { GroupRecipientPermissions } from './GroupRecipientPermissions';
14
- import { FADE_IN_DURATION } from '../../helpers/recipients';
15
+ import { FADE_IN_DURATION, getGroupRecipientSecondaryText } from '../../helpers/recipients';
15
16
  import { GroupAvatar } from '../Avatar/GroupAvatar';
16
17
 
17
18
  var GroupRecipient = function GroupRecipient(props) {
18
19
  var name = props.name,
19
20
  members = props.members,
20
21
  fadeIn = props.fadeIn,
21
- owner = props.owner;
22
+ owner = props.owner,
23
+ isOwner = props.isOwner;
22
24
 
23
25
  var _useI18n = useI18n(),
24
26
  t = _useI18n.t;
@@ -37,7 +39,7 @@ var GroupRecipient = function GroupRecipient(props) {
37
39
  var nbMemberReady = members.filter(function (member) {
38
40
  return !['revoked', 'mail-not-sent'].includes(member.status);
39
41
  }).length;
40
- var isCurrentInstanceInsideMembers = members.some(function (member) {
42
+ var isUserInsideMembers = members.some(function (member) {
41
43
  return member.instance === client.options.uri;
42
44
  });
43
45
 
@@ -63,13 +65,18 @@ var GroupRecipient = function GroupRecipient(props) {
63
65
  className: "u-ellipsis",
64
66
  variant: "body1"
65
67
  }, name),
66
- secondary: t('GroupRecipient.secondary', {
68
+ secondary: getGroupRecipientSecondaryText({
69
+ t: t,
67
70
  nbMember: nbMember,
68
- nbMemberReady: nbMemberReady
69
- }) + (isCurrentInstanceInsideMembers ? " (".concat(t('GroupRecipient.secondary_you'), ")") : '')
71
+ nbMemberReady: nbMemberReady,
72
+ isUserInsideMembers: isUserInsideMembers
73
+ })
70
74
  }), /*#__PURE__*/React.createElement(ListItemSecondaryAction, {
71
75
  className: isMobile ? 'u-mr-1' : 'u-mr-2'
72
- }, /*#__PURE__*/React.createElement(GroupRecipientPermissions, props)))), isDetailOpened ? /*#__PURE__*/React.createElement(GroupRecipientDetail, {
76
+ }, /*#__PURE__*/React.createElement(GroupRecipientPermissions, _extends({
77
+ isUserInsideMembers: isUserInsideMembers
78
+ }, props))))), isDetailOpened ? /*#__PURE__*/React.createElement(GroupRecipientDetail, {
79
+ isOwner: isOwner,
73
80
  owner: owner,
74
81
  name: name,
75
82
  members: members,
@@ -9,7 +9,8 @@ var GroupRecipientDetail = function GroupRecipientDetail(_ref) {
9
9
  var name = _ref.name,
10
10
  owner = _ref.owner,
11
11
  members = _ref.members,
12
- onClose = _ref.onClose;
12
+ onClose = _ref.onClose,
13
+ isOwner = _ref.isOwner;
13
14
 
14
15
  var _useI18n = useI18n(),
15
16
  t = _useI18n.t;
@@ -35,7 +36,8 @@ var GroupRecipientDetail = function GroupRecipientDetail(_ref) {
35
36
  }, withAccess.length > 0 ? /*#__PURE__*/React.createElement(GroupRecipientDetailWithAccess, {
36
37
  withAccess: withAccess
37
38
  }) : null, withoutAccess.length > 0 ? /*#__PURE__*/React.createElement(GroupRecipientDetailWithoutAccess, {
38
- withoutAccess: withoutAccess
39
+ withoutAccess: withoutAccess,
40
+ isOwner: isOwner
39
41
  }) : null)
40
42
  });
41
43
  };
@@ -1,13 +1,13 @@
1
1
  import React from 'react';
2
+ import { useClient } from 'cozy-client';
2
3
  import Avatar from 'cozy-ui/transpiled/react/Avatar';
3
- import Icon from 'cozy-ui/transpiled/react/Icon';
4
- import ToTheCloudIcon from 'cozy-ui/transpiled/react/Icons/ToTheCloud';
5
4
  import List from 'cozy-ui/transpiled/react/List';
6
5
  import ListItem from 'cozy-ui/transpiled/react/ListItem';
7
6
  import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon';
8
7
  import ListItemText from 'cozy-ui/transpiled/react/ListItemText';
9
8
  import Typography from 'cozy-ui/transpiled/react/Typography';
10
9
  import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n';
10
+ import MemberRecipientStatus from './MemberRecipientStatus';
11
11
  import { getInitials, getDisplayName } from '../../models';
12
12
 
13
13
  var GroupRecipientDetailWithAccess = function GroupRecipientDetailWithAccess(_ref) {
@@ -16,10 +16,12 @@ var GroupRecipientDetailWithAccess = function GroupRecipientDetailWithAccess(_re
16
16
  var _useI18n = useI18n(),
17
17
  t = _useI18n.t;
18
18
 
19
+ var client = useClient();
19
20
  return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Typography, {
20
21
  variant: "subtitle2"
21
22
  }, t('GroupRecipientDetail.withAccess.title')), /*#__PURE__*/React.createElement(List, null, withAccess.map(function (recipient) {
22
23
  var name = getDisplayName(recipient);
24
+ var isMe = recipient.instance === client.options.uri;
23
25
  return /*#__PURE__*/React.createElement(ListItem, {
24
26
  disableGutters: true,
25
27
  key: recipient.index
@@ -28,15 +30,11 @@ var GroupRecipientDetailWithAccess = function GroupRecipientDetailWithAccess(_re
28
30
  textId: name
29
31
  })), /*#__PURE__*/React.createElement(ListItemText, {
30
32
  primary: name,
31
- secondary: recipient.instance ? /*#__PURE__*/React.createElement("div", {
32
- className: "u-flex u-flex-items-center"
33
- }, /*#__PURE__*/React.createElement(Icon, {
34
- icon: ToTheCloudIcon,
35
- size: 10,
36
- style: {
37
- marginRight: '0.25rem'
38
- }
39
- }), recipient.instance) : null
33
+ secondary: /*#__PURE__*/React.createElement(MemberRecipientStatus, {
34
+ status: recipient.status,
35
+ isMe: isMe,
36
+ instance: recipient.instance
37
+ })
40
38
  }));
41
39
  })));
42
40
  };
@@ -8,10 +8,12 @@ import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon';
8
8
  import ListItemText from 'cozy-ui/transpiled/react/ListItemText';
9
9
  import Typography from 'cozy-ui/transpiled/react/Typography';
10
10
  import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n';
11
+ import { DEFAULT_DISPLAY_NAME } from '../../helpers/recipients';
11
12
  import { getInitials, getDisplayName } from '../../models';
12
13
 
13
14
  var GroupRecipientDetailWithoutAccess = function GroupRecipientDetailWithoutAccess(_ref) {
14
- var withoutAccess = _ref.withoutAccess;
15
+ var withoutAccess = _ref.withoutAccess,
16
+ isOwner = _ref.isOwner;
15
17
 
16
18
  var _useI18n = useI18n(),
17
19
  t = _useI18n.t;
@@ -20,10 +22,12 @@ var GroupRecipientDetailWithoutAccess = function GroupRecipientDetailWithoutAcce
20
22
  variant: "subtitle2"
21
23
  }, t('GroupRecipientDetail.withoutAccess.title')), /*#__PURE__*/React.createElement(List, null, withoutAccess.map(function (recipient) {
22
24
  var icon = recipient.status === 'revoked' ? ForbiddenIcon : null;
23
- var name = getDisplayName(recipient);
25
+ var defaultDisplayName = t(DEFAULT_DISPLAY_NAME);
26
+ var name = getDisplayName(recipient, defaultDisplayName);
24
27
  return /*#__PURE__*/React.createElement(ListItem, {
25
28
  disableGutters: true,
26
- key: recipient.index
29
+ key: recipient.index,
30
+ ellipsis: false
27
31
  }, /*#__PURE__*/React.createElement(ListItemIcon, null, /*#__PURE__*/React.createElement(Avatar, {
28
32
  text: getInitials(recipient),
29
33
  textId: name
@@ -37,7 +41,7 @@ var GroupRecipientDetailWithoutAccess = function GroupRecipientDetailWithoutAcce
37
41
  style: {
38
42
  marginRight: '0.25rem'
39
43
  }
40
- }) : null, t("GroupRecipientDetail.withoutAccess.status.".concat(recipient.status)))
44
+ }) : null, t("GroupRecipientDetail.withoutAccess.status.".concat(recipient.status)), isOwner ? " - ".concat(t('GroupRecipientDetail.withoutAccess.addEmail')) : null)
41
45
  }));
42
46
  })));
43
47
  };
@@ -2,7 +2,6 @@ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
2
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
3
  import _regeneratorRuntime from "@babel/runtime/regenerator";
4
4
  import React, { useState, useRef } from 'react';
5
- import { useClient } from 'cozy-client';
6
5
  import ActionsMenu from 'cozy-ui/transpiled/react/ActionsMenu';
7
6
  import { makeActions, divider } from 'cozy-ui/transpiled/react/ActionsMenu/Actions';
8
7
  import ActionsMenuMobileHeader from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuMobileHeader';
@@ -19,18 +18,17 @@ import { GroupAvatar } from '../Avatar/GroupAvatar';
19
18
  var GroupRecipientPermissions = function GroupRecipientPermissions(_ref) {
20
19
  var name = _ref.name,
21
20
  isOwner = _ref.isOwner,
22
- instance = _ref.instance,
23
21
  sharingId = _ref.sharingId,
24
22
  groupIndex = _ref.groupIndex,
25
23
  _ref$read_only = _ref.read_only,
26
24
  isReadOnly = _ref$read_only === void 0 ? false : _ref$read_only,
27
- className = _ref.className;
25
+ className = _ref.className,
26
+ isUserInsideMembers = _ref.isUserInsideMembers;
28
27
 
29
28
  var _useI18n = useI18n(),
30
29
  t = _useI18n.t;
31
30
 
32
31
  var buttonRef = useRef();
33
- var client = useClient();
34
32
 
35
33
  var _useSharingContext = useSharingContext(),
36
34
  revokeGroup = _useSharingContext.revokeGroup,
@@ -46,8 +44,7 @@ var GroupRecipientPermissions = function GroupRecipientPermissions(_ref) {
46
44
  revoking = _useState4[0],
47
45
  setRevoking = _useState4[1];
48
46
 
49
- var instanceMatchesClient = instance !== undefined && instance === client.options.uri;
50
- var shouldShowMenu = !revoking && (instanceMatchesClient && !isOwner || isOwner);
47
+ var shouldShowMenu = !revoking && (isOwner || isUserInsideMembers);
51
48
 
52
49
  var toggleMenu = function toggleMenu() {
53
50
  return setMenuDisplayed(!isMenuDisplayed);
@@ -14,10 +14,9 @@ import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n';
14
14
  import MemberRecipientPermissions from './MemberRecipientPermissions';
15
15
  import MemberRecipientStatus from './MemberRecipientStatus';
16
16
  import RecipientConfirm from './RecipientConfirm';
17
- import { FADE_IN_DURATION } from '../../helpers/recipients';
17
+ import { FADE_IN_DURATION, DEFAULT_DISPLAY_NAME } from '../../helpers/recipients';
18
18
  import { getDisplayName } from '../../models';
19
19
  import { MemberAvatar } from '../Avatar/MemberAvatar';
20
- var DEFAULT_DISPLAY_NAME = 'Share.contacts.defaultDisplayName';
21
20
 
22
21
  var MemberRecipient = function MemberRecipient(props) {
23
22
  var _useI18n = useI18n(),
@@ -85,7 +85,7 @@ var MemberRecipientPermissions = function MemberRecipientPermissions(_ref) {
85
85
  })), [isOwner, onRevoke, onRevokeSelf, document, sharingId, memberIndex]);
86
86
  var actions = makeActions([permission, divider, revokeMember], {
87
87
  t: t,
88
- type: type,
88
+ type: type !== null && type !== void 0 ? type : 'one-way',
89
89
  isOwner: isOwner,
90
90
  handleRevocation: handleRevocation
91
91
  });
@@ -7,9 +7,10 @@ import Avatar from 'cozy-ui/transpiled/react/Avatar';
7
7
  import Chip from 'cozy-ui/transpiled/react/Chips';
8
8
  import { Spinner } from 'cozy-ui/transpiled/react/Spinner';
9
9
  import palette from 'cozy-ui/transpiled/react/palette';
10
+ import { GroupAvatar } from './Avatar/GroupAvatar';
10
11
  import ContactSuggestion from './ContactSuggestion';
11
12
  import { extractEmails, validateEmail } from '../helpers/email';
12
- import { getDisplayName, getInitials, Contact } from '../models';
13
+ import { getDisplayName, getInitials, Contact, Group } from '../models';
13
14
  var styles = {
14
15
  "container": "autosuggest__container___1Yro7",
15
16
  "suggestionsContainer": "autosuggest__suggestionsContainer___3EDuG",
@@ -26,7 +27,6 @@ var ShareAutocomplete = function ShareAutocomplete(_ref) {
26
27
  var loading = _ref.loading,
27
28
  contactsAndGroups = _ref.contactsAndGroups,
28
29
  recipients = _ref.recipients,
29
- onFocus = _ref.onFocus,
30
30
  onPick = _ref.onPick,
31
31
  onRemove = _ref.onRemove,
32
32
  placeholder = _ref.placeholder;
@@ -46,6 +46,11 @@ var ShareAutocomplete = function ShareAutocomplete(_ref) {
46
46
  isPasted = _useState6[0],
47
47
  setIsPasted = _useState6[1];
48
48
 
49
+ var _useState7 = useState(false),
50
+ _useState8 = _slicedToArray(_useState7, 2),
51
+ isLoadingDisplayed = _useState8[0],
52
+ setLoadingDisplayed = _useState8[1];
53
+
49
54
  var autosuggestRef = useRef(null);
50
55
 
51
56
  var computeSuggestions = function computeSuggestions(value) {
@@ -118,7 +123,8 @@ var ShareAutocomplete = function ShareAutocomplete(_ref) {
118
123
  };
119
124
 
120
125
  var onAutosuggestFocus = function onAutosuggestFocus() {
121
- onFocus();
126
+ // We only show the loading state when the user has focus on the input
127
+ setLoadingDisplayed(true);
122
128
  };
123
129
 
124
130
  var onAutosuggestBlur = function onAutosuggestBlur() {
@@ -148,12 +154,15 @@ var ShareAutocomplete = function ShareAutocomplete(_ref) {
148
154
  return /*#__PURE__*/React.createElement("div", {
149
155
  className: styles['recipientsContainer']
150
156
  }, recipients.map(function (recipient, idx) {
157
+ var isContactGroup = recipient._type === Group.doctype;
151
158
  var avatarText = getInitials(recipient);
152
159
  var name = getDisplayName(recipient);
153
160
  return /*#__PURE__*/React.createElement(Chip, {
154
161
  id: "recipient_".concat(idx),
155
162
  key: "key_recipient_".concat(idx),
156
- avatar: /*#__PURE__*/React.createElement(Avatar, {
163
+ avatar: isContactGroup ? /*#__PURE__*/React.createElement(GroupAvatar, {
164
+ size: "xsmall"
165
+ }) : /*#__PURE__*/React.createElement(Avatar, {
157
166
  text: avatarText,
158
167
  size: "xsmall"
159
168
  }),
@@ -166,10 +175,9 @@ var ShareAutocomplete = function ShareAutocomplete(_ref) {
166
175
  }), /*#__PURE__*/React.createElement("input", _extends({}, inputProps, {
167
176
  onKeyPress: onKeyPress,
168
177
  onKeyUp: onKeyUp
169
- })), loading && /*#__PURE__*/React.createElement(Spinner, {
170
- color: palette.dodgerBlue,
171
- className: "u-flex u-flex-items-center"
172
- }));
178
+ })), loading && isLoadingDisplayed ? /*#__PURE__*/React.createElement(Spinner, {
179
+ color: palette.dodgerBlue
180
+ }) : null);
173
181
  };
174
182
 
175
183
  var renderSuggestion = function renderSuggestion(contactOrGroup) {
@@ -206,7 +214,6 @@ ShareAutocomplete.propTypes = {
206
214
  loading: PropTypes.bool,
207
215
  contactsAndGroups: PropTypes.array,
208
216
  recipients: PropTypes.array.isRequired,
209
- onFocus: PropTypes.func.isRequired,
210
217
  onPick: PropTypes.func.isRequired,
211
218
  onRemove: PropTypes.func.isRequired,
212
219
  placeholder: PropTypes.string
@@ -1,26 +1,38 @@
1
- import { render, fireEvent } from '@testing-library/react';
1
+ import { render, fireEvent, screen } from '@testing-library/react';
2
2
  import React from 'react';
3
3
  import ShareAutosuggest from './ShareAutosuggest';
4
4
  import AppLike from '../../test/AppLike';
5
+ jest.mock('cozy-ui/transpiled/react/Spinner', function () {
6
+ return {
7
+ Spinner: function Spinner() {
8
+ return /*#__PURE__*/React.createElement("div", null, "loading");
9
+ }
10
+ };
11
+ });
5
12
  describe('ShareAutosuggest', function () {
6
- it('tests if ShareAutosuggest calls onFocus and onPick', function () {
7
- var onPick = jest.fn();
8
- var onFocus = jest.fn();
9
- var onRemove = jest.fn();
10
-
11
- var _render = render( /*#__PURE__*/React.createElement(AppLike, null, /*#__PURE__*/React.createElement(ShareAutosuggest, {
13
+ var setup = function setup(_ref) {
14
+ var onPick = _ref.onPick,
15
+ onRemove = _ref.onRemove,
16
+ _ref$loading = _ref.loading,
17
+ loading = _ref$loading === void 0 ? false : _ref$loading;
18
+ render( /*#__PURE__*/React.createElement(AppLike, null, /*#__PURE__*/React.createElement(ShareAutosuggest, {
19
+ loading: loading,
12
20
  contactsAndGroups: [],
13
21
  placeholder: "myPlaceHolder",
14
22
  onPick: onPick,
15
- onFocus: onFocus,
16
23
  recipients: [],
17
24
  onRemove: onRemove
18
- }))),
19
- getByPlaceholderText = _render.getByPlaceholderText;
25
+ })));
26
+ };
20
27
 
21
- var inputNode = getByPlaceholderText('myPlaceHolder');
22
- inputNode.focus();
23
- expect(onFocus).toHaveBeenCalled(); // It should not call onPick if the value is not an email
28
+ it('tests if ShareAutosuggest calls onPick', function () {
29
+ var onPick = jest.fn();
30
+ var onRemove = jest.fn();
31
+ setup({
32
+ onPick: onPick,
33
+ onRemove: onRemove
34
+ });
35
+ var inputNode = screen.getByPlaceholderText('myPlaceHolder'); // It should not call onPick if the value is not an email
24
36
 
25
37
  fireEvent.change(inputNode, {
26
38
  target: {
@@ -66,4 +78,17 @@ describe('ShareAutosuggest', function () {
66
78
  email: 'quentin.valmori@cozycloud.cc'
67
79
  });
68
80
  });
81
+ it('should show loading only after user focus input', function () {
82
+ var onPick = jest.fn();
83
+ var onRemove = jest.fn();
84
+ setup({
85
+ onPick: onPick,
86
+ onRemove: onRemove,
87
+ loading: true
88
+ });
89
+ var inputNode = screen.getByPlaceholderText('myPlaceHolder');
90
+ expect(screen.queryByText('loading')).toBeNull();
91
+ fireEvent.focus(inputNode);
92
+ expect(screen.getByText('loading')).toBeInTheDocument();
93
+ });
69
94
  });
@@ -0,0 +1,61 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
3
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
4
+ import React, { useState } from 'react';
5
+ import ShareAutosuggest from './ShareAutosuggest';
6
+ var meta = {
7
+ component: ShareAutosuggest,
8
+ args: {}
9
+ };
10
+ export default meta;
11
+
12
+ var ShareAutosuggestRender = function ShareAutosuggestRender(props) {
13
+ var _useState = useState([]),
14
+ _useState2 = _slicedToArray(_useState, 2),
15
+ recipients = _useState2[0],
16
+ setRecipients = _useState2[1];
17
+
18
+ var onPick = function onPick(contactOrGroup) {
19
+ setRecipients([].concat(_toConsumableArray(recipients), [contactOrGroup]));
20
+ };
21
+
22
+ var onRemove = function onRemove(contactOrGroup) {
23
+ setRecipients(recipients.filter(function (r) {
24
+ return r.id !== contactOrGroup.id;
25
+ }));
26
+ };
27
+
28
+ return /*#__PURE__*/React.createElement(ShareAutosuggest, _extends({}, props, {
29
+ recipients: recipients,
30
+ onPick: onPick,
31
+ onRemove: onRemove
32
+ }));
33
+ };
34
+
35
+ export var Default = {
36
+ name: 'Default',
37
+ render: ShareAutosuggestRender,
38
+ args: {
39
+ loading: false,
40
+ contactsAndGroups: [{
41
+ id: 'group1',
42
+ name: 'Family',
43
+ _type: 'io.cozy.contacts.groups',
44
+ members: [{
45
+ id: 'contact1',
46
+ name: 'John Doe',
47
+ _type: 'io.cozy.contacts'
48
+ }, {
49
+ id: 'contact2',
50
+ name: 'Jane Doe',
51
+ _type: 'io.cozy.contacts'
52
+ }]
53
+ }, {
54
+ id: 'contact3',
55
+ name: 'Alice Wonderland',
56
+ _type: 'io.cozy.contacts',
57
+ email: 'alice@wonder.land'
58
+ }],
59
+ placeholder: 'Type a name or email address'
60
+ }
61
+ };
@@ -7,6 +7,7 @@ import React, { useState } from 'react';
7
7
  import { useClient } from 'cozy-client';
8
8
  import flag from 'cozy-flags';
9
9
  import Alerter from 'cozy-ui/transpiled/react/deprecated/Alerter';
10
+ import { useAlert } from 'cozy-ui/transpiled/react/providers/Alert';
10
11
  import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n';
11
12
  import ShareRecipientsInput from './ShareRecipientsInput';
12
13
  import { ShareRecipientsLimitModal } from './ShareRecipientsLimitModal';
@@ -15,7 +16,6 @@ import ShareTypeSelect from './Sharetypeselect';
15
16
  import { getOrCreateFromArray } from '../helpers/contacts';
16
17
  import { mergeRecipients, spreadGroupAndMergeRecipients, hasReachRecipientsLimit } from '../helpers/recipients';
17
18
  import { getSuccessMessage } from '../helpers/successMessage';
18
- import { contactsResponseType, contactGroupsResponseType } from '../propTypes';
19
19
  import { isReadOnlySharing } from '../state';
20
20
  var styles = {
21
21
  "share-modal-content": "share__share-modal-content___1iqEq",
@@ -41,9 +41,7 @@ var styles = {
41
41
  "share-details-perm-desc": "share__share-details-perm-desc___3HyHu"
42
42
  };
43
43
  export var ShareByEmail = function ShareByEmail(_ref) {
44
- var contacts = _ref.contacts,
45
- contactGroups = _ref.contactGroups,
46
- document = _ref.document,
44
+ var document = _ref.document,
47
45
  sharingDesc = _ref.sharingDesc,
48
46
  onShare = _ref.onShare,
49
47
  createContact = _ref.createContact,
@@ -55,6 +53,9 @@ export var ShareByEmail = function ShareByEmail(_ref) {
55
53
  var _useI18n = useI18n(),
56
54
  t = _useI18n.t;
57
55
 
56
+ var _useAlert = useAlert(),
57
+ showAlert = _useAlert.showAlert;
58
+
58
59
  var _useState = useState([]),
59
60
  _useState2 = _slicedToArray(_useState, 2),
60
61
  recipients = _useState2[0],
@@ -85,7 +86,7 @@ export var ShareByEmail = function ShareByEmail(_ref) {
85
86
  };
86
87
 
87
88
  var onRecipientPick = function onRecipientPick(recipient) {
88
- var mergedRecipients = flag('sharing.show-recipient-groups') ? mergeRecipients(recipients, recipient) : spreadGroupAndMergeRecipients(recipients, recipient, contacts);
89
+ var mergedRecipients = flag('sharing.show-recipient-groups') ? mergeRecipients(recipients, recipient) : spreadGroupAndMergeRecipients(recipients, recipient);
89
90
  setRecipients(mergedRecipients);
90
91
  };
91
92
 
@@ -98,8 +99,7 @@ export var ShareByEmail = function ShareByEmail(_ref) {
98
99
 
99
100
  var share = /*#__PURE__*/function () {
100
101
  var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
101
- var recipientsBefore, _contacts, readWriteRecipients, readOnlyRecipients;
102
-
102
+ var recipientsBefore, contacts, readWriteRecipients, readOnlyRecipients;
103
103
  return _regeneratorRuntime.wrap(function _callee$(_context) {
104
104
  while (1) switch (_context.prev = _context.next) {
105
105
  case 0:
@@ -130,14 +130,14 @@ export var ShareByEmail = function ShareByEmail(_ref) {
130
130
  return getOrCreateFromArray(client, recipients, createContact);
131
131
 
132
132
  case 10:
133
- _contacts = _context.sent;
133
+ contacts = _context.sent;
134
134
  readWriteRecipients = [];
135
135
  readOnlyRecipients = [];
136
136
 
137
137
  if (selectedOption === 'readOnly') {
138
- readOnlyRecipients = _contacts;
138
+ readOnlyRecipients = contacts;
139
139
  } else {
140
- readWriteRecipients = _contacts;
140
+ readWriteRecipients = contacts;
141
141
  }
142
142
 
143
143
  _context.next = 16;
@@ -150,7 +150,11 @@ export var ShareByEmail = function ShareByEmail(_ref) {
150
150
  });
151
151
 
152
152
  case 16:
153
- Alerter.success(t.apply(void 0, _toConsumableArray(getSuccessMessage(recipientsBefore, _contacts, documentType))));
153
+ showAlert({
154
+ message: t.apply(void 0, _toConsumableArray(getSuccessMessage(recipientsBefore, contacts, documentType))),
155
+ severity: 'success',
156
+ variant: 'filled'
157
+ });
154
158
  reset();
155
159
  _context.next = 25;
156
160
  break;
@@ -204,8 +208,6 @@ export var ShareByEmail = function ShareByEmail(_ref) {
204
208
  onRemove: function onRemove(recipient) {
205
209
  return onRecipientRemove(recipient);
206
210
  },
207
- contacts: contacts,
208
- contactGroups: contactGroups,
209
211
  recipients: recipients
210
212
  })), showShareControl && /*#__PURE__*/React.createElement("div", {
211
213
  className: styles['share-type-control']
@@ -226,8 +228,6 @@ export var ShareByEmail = function ShareByEmail(_ref) {
226
228
  };
227
229
  ShareByEmail.propTypes = {
228
230
  currentRecipients: PropTypes.arrayOf(PropTypes.object),
229
- contacts: contactsResponseType.isRequired,
230
- contactGroups: contactGroupsResponseType.isRequired,
231
231
  document: PropTypes.object.isRequired,
232
232
  documentType: PropTypes.string.isRequired,
233
233
  sharingDesc: PropTypes.string.isRequired,
@@ -31,12 +31,6 @@ describe('ShareByEmailComponent', function () {
31
31
  currentRecipients = _ref$currentRecipient === void 0 ? [] : _ref$currentRecipient;
32
32
 
33
33
  var props = {
34
- contacts: {
35
- data: []
36
- },
37
- contactGroups: {
38
- data: []
39
- },
40
34
  documentType: 'Files',
41
35
  onShare: onShare,
42
36
  document: document,