box-ui-elements 23.1.0 → 23.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.
Files changed (117) hide show
  1. package/dist/explorer.css +1 -1
  2. package/dist/explorer.js +1 -1
  3. package/dist/openwith.js +1 -1
  4. package/dist/picker.js +1 -1
  5. package/dist/preview.css +1 -1
  6. package/dist/preview.js +1 -1
  7. package/dist/sharing.css +1 -1
  8. package/dist/sharing.js +1 -1
  9. package/dist/sidebar.js +1 -1
  10. package/dist/uploader.js +1 -1
  11. package/es/elements/common/content-answers/ContentAnswersOpenButton.scss +1 -1
  12. package/es/features/collaborator-avatars/CollaboratorList.js +5 -1
  13. package/es/features/collaborator-avatars/CollaboratorList.js.flow +12 -1
  14. package/es/features/collaborator-avatars/CollaboratorList.js.map +1 -1
  15. package/es/features/collaborator-avatars/CollaboratorList.scss +3 -0
  16. package/es/features/collaborator-avatars/CollaboratorListItem.js +26 -5
  17. package/es/features/collaborator-avatars/CollaboratorListItem.js.flow +33 -9
  18. package/es/features/collaborator-avatars/CollaboratorListItem.js.map +1 -1
  19. package/es/features/collaborator-avatars/CollaboratorListItem.scss +23 -0
  20. package/es/features/message-center/components/MessageCenter.js +1 -0
  21. package/es/features/message-center/components/MessageCenter.js.flow +2 -1
  22. package/es/features/message-center/components/MessageCenter.js.map +1 -1
  23. package/es/features/unified-share-modal/RemoveCollaboratorConfirmModal.js +44 -0
  24. package/es/features/unified-share-modal/RemoveCollaboratorConfirmModal.js.flow +67 -0
  25. package/es/features/unified-share-modal/RemoveCollaboratorConfirmModal.js.map +1 -0
  26. package/es/features/unified-share-modal/UnifiedShareForm.js +8 -3
  27. package/es/features/unified-share-modal/UnifiedShareForm.js.flow +5 -1
  28. package/es/features/unified-share-modal/UnifiedShareForm.js.map +1 -1
  29. package/es/features/unified-share-modal/UnifiedShareModal.js +54 -10
  30. package/es/features/unified-share-modal/UnifiedShareModal.js.flow +59 -11
  31. package/es/features/unified-share-modal/UnifiedShareModal.js.map +1 -1
  32. package/es/features/unified-share-modal/UnifiedShareModal.scss +9 -2
  33. package/es/features/unified-share-modal/flowTypes.js.flow +13 -0
  34. package/es/features/unified-share-modal/flowTypes.js.map +1 -1
  35. package/es/features/unified-share-modal/messages.js +8 -0
  36. package/es/features/unified-share-modal/messages.js.flow +10 -0
  37. package/es/features/unified-share-modal/messages.js.map +1 -1
  38. package/es/features/unified-share-modal/stories/UnifiedShareModal.stories.js +221 -4
  39. package/es/features/unified-share-modal/stories/UnifiedShareModal.stories.js.flow +208 -3
  40. package/es/features/unified-share-modal/stories/UnifiedShareModal.stories.js.map +1 -1
  41. package/es/src/elements/content-sidebar/stories/tests/MetadataSidebarRedesign-visual.stories.d.ts +4 -4
  42. package/i18n/bn-IN.js +2 -0
  43. package/i18n/bn-IN.properties +4 -0
  44. package/i18n/da-DK.js +2 -0
  45. package/i18n/da-DK.properties +4 -0
  46. package/i18n/de-DE.js +2 -0
  47. package/i18n/de-DE.properties +4 -0
  48. package/i18n/en-AU.js +2 -0
  49. package/i18n/en-AU.properties +4 -0
  50. package/i18n/en-CA.js +2 -0
  51. package/i18n/en-CA.properties +4 -0
  52. package/i18n/en-GB.js +2 -0
  53. package/i18n/en-GB.properties +4 -0
  54. package/i18n/en-US.js +2 -0
  55. package/i18n/en-US.properties +4 -0
  56. package/i18n/en-x-pseudo.js +1010 -1008
  57. package/i18n/en-x-pseudo.properties +1012 -1008
  58. package/i18n/es-419.js +2 -0
  59. package/i18n/es-419.properties +4 -0
  60. package/i18n/es-ES.js +2 -0
  61. package/i18n/es-ES.properties +4 -0
  62. package/i18n/fi-FI.js +2 -0
  63. package/i18n/fi-FI.properties +4 -0
  64. package/i18n/fr-CA.js +2 -0
  65. package/i18n/fr-CA.properties +4 -0
  66. package/i18n/fr-FR.js +2 -0
  67. package/i18n/fr-FR.properties +4 -0
  68. package/i18n/hi-IN.js +2 -0
  69. package/i18n/hi-IN.properties +4 -0
  70. package/i18n/it-IT.js +2 -0
  71. package/i18n/it-IT.properties +4 -0
  72. package/i18n/ja-JP.js +2 -0
  73. package/i18n/ja-JP.properties +4 -0
  74. package/i18n/ko-KR.js +2 -0
  75. package/i18n/ko-KR.properties +4 -0
  76. package/i18n/nb-NO.js +2 -0
  77. package/i18n/nb-NO.properties +4 -0
  78. package/i18n/nl-NL.js +2 -0
  79. package/i18n/nl-NL.properties +4 -0
  80. package/i18n/pl-PL.js +2 -0
  81. package/i18n/pl-PL.properties +4 -0
  82. package/i18n/pt-BR.js +2 -0
  83. package/i18n/pt-BR.properties +4 -0
  84. package/i18n/ru-RU.js +2 -0
  85. package/i18n/ru-RU.properties +4 -0
  86. package/i18n/sv-SE.js +2 -0
  87. package/i18n/sv-SE.properties +4 -0
  88. package/i18n/tr-TR.js +2 -0
  89. package/i18n/tr-TR.properties +4 -0
  90. package/i18n/zh-CN.js +2 -0
  91. package/i18n/zh-CN.properties +4 -0
  92. package/i18n/zh-TW.js +2 -0
  93. package/i18n/zh-TW.properties +4 -0
  94. package/package.json +18 -18
  95. package/src/elements/common/content-answers/ContentAnswersOpenButton.scss +1 -1
  96. package/src/features/collaborator-avatars/CollaboratorList.js +12 -1
  97. package/src/features/collaborator-avatars/CollaboratorList.scss +3 -0
  98. package/src/features/collaborator-avatars/CollaboratorListItem.js +33 -9
  99. package/src/features/collaborator-avatars/CollaboratorListItem.scss +23 -0
  100. package/src/features/collaborator-avatars/__tests__/CollaboratorList.test.js +11 -0
  101. package/src/features/collaborator-avatars/__tests__/CollaboratorListItem.test.js +51 -0
  102. package/src/features/collaborator-avatars/__tests__/__snapshots__/CollaboratorList.test.js.snap +110 -0
  103. package/src/features/collaborator-avatars/__tests__/__snapshots__/CollaboratorListItem.test.js.snap +310 -0
  104. package/src/features/message-center/__tests__/MessageCenter.integration.test.js +10 -0
  105. package/src/features/message-center/components/MessageCenter.js +2 -1
  106. package/src/features/unified-share-modal/README.md +12 -1
  107. package/src/features/unified-share-modal/RemoveCollaboratorConfirmModal.js +67 -0
  108. package/src/features/unified-share-modal/UnifiedShareForm.js +5 -1
  109. package/src/features/unified-share-modal/UnifiedShareModal.js +59 -11
  110. package/src/features/unified-share-modal/UnifiedShareModal.scss +9 -2
  111. package/src/features/unified-share-modal/__tests__/RemoveCollaboratorConfirmModal.test.js +64 -0
  112. package/src/features/unified-share-modal/__tests__/UnifiedShareForm.test.js +34 -1
  113. package/src/features/unified-share-modal/__tests__/UnifiedShareModal.test.js +74 -4
  114. package/src/features/unified-share-modal/__tests__/__snapshots__/UnifiedShareModal.test.js.snap +258 -0
  115. package/src/features/unified-share-modal/flowTypes.js +13 -0
  116. package/src/features/unified-share-modal/messages.js +10 -0
  117. package/src/features/unified-share-modal/stories/UnifiedShareModal.stories.js +208 -3
@@ -4,20 +4,26 @@ import classnames from 'classnames';
4
4
  import { FormattedMessage } from 'react-intl';
5
5
 
6
6
  import { Link } from '../../components/link';
7
-
7
+ import PlainButton from '../../components/plain-button';
8
+ import Tooltip from '../../components/tooltip';
9
+ import IconClose from '../../icon/fill/X16';
8
10
  import { COLLAB_GROUP_TYPE, COLLAB_PENDING_TYPE } from './constants';
9
11
  import messages from './messages';
12
+ import commonMessages from '../../elements/common/messages';
10
13
  import CollaboratorAvatarItem from './CollaboratorAvatarItem';
14
+ import type { collaboratorType } from '../unified-share-modal/flowTypes';
11
15
  import './CollaboratorListItem.scss';
12
16
 
13
17
  type Props = {
18
+ canRemoveCollaborators?: boolean,
14
19
  collaborator: Object,
15
20
  index: number,
21
+ onRemoveCollaborator?: (collaborator: collaboratorType) => void,
16
22
  trackingProps: { emailProps: ?Object, usernameProps: ?Object },
17
23
  };
18
24
 
19
25
  const CollaboratorListItem = (props: Props) => {
20
- const { index, trackingProps } = props;
26
+ const { index, trackingProps, canRemoveCollaborators = false, onRemoveCollaborator } = props;
21
27
  const { usernameProps, emailProps } = trackingProps;
22
28
  const {
23
29
  email,
@@ -30,6 +36,7 @@ const CollaboratorListItem = (props: Props) => {
30
36
  profileURL,
31
37
  translatedRole,
32
38
  userID,
39
+ isRemovable = false,
33
40
  } = props.collaborator;
34
41
 
35
42
  const userOrGroupNameContent =
@@ -52,6 +59,12 @@ const CollaboratorListItem = (props: Props) => {
52
59
  </div>
53
60
  ) : null;
54
61
 
62
+ const roleNodeContent = (
63
+ <div className="role">
64
+ {type === COLLAB_PENDING_TYPE ? <FormattedMessage {...messages.pendingCollabText} /> : translatedRole}
65
+ </div>
66
+ );
67
+
55
68
  return (
56
69
  <li>
57
70
  <div className="collaborator-list-item">
@@ -71,13 +84,24 @@ const CollaboratorListItem = (props: Props) => {
71
84
  name={name}
72
85
  />
73
86
  </div>
74
- <div className="role">
75
- {type === COLLAB_PENDING_TYPE ? (
76
- <FormattedMessage {...messages.pendingCollabText} />
77
- ) : (
78
- translatedRole
79
- )}
80
- </div>
87
+ {canRemoveCollaborators ? (
88
+ <div className="user-actions">
89
+ {roleNodeContent}
90
+ {isRemovable && (
91
+ <Tooltip isTabbable={false} text={<FormattedMessage {...commonMessages.remove} />}>
92
+ <PlainButton
93
+ className="remove-button"
94
+ onClick={() => onRemoveCollaborator?.(props.collaborator)}
95
+ type="button"
96
+ >
97
+ <IconClose color="##6f6f6f" height={16} width={16} />
98
+ </PlainButton>
99
+ </Tooltip>
100
+ )}
101
+ </div>
102
+ ) : (
103
+ roleNodeContent
104
+ )}
81
105
  </div>
82
106
  </li>
83
107
  );
@@ -54,10 +54,33 @@
54
54
  text-overflow: ellipsis;
55
55
  }
56
56
 
57
+ .user-actions {
58
+ display: flex;
59
+ gap: 8px;
60
+ align-items: center;
61
+ margin-left: auto;
62
+ }
63
+
57
64
  .role {
58
65
  color: $bdl-gray-65;
59
66
  line-height: 32px;
60
67
  }
68
+
69
+ .remove-button {
70
+ display: flex;
71
+ align-items: center;
72
+ justify-content: center;
73
+ width: $bdl-btn-height;
74
+ height: $bdl-btn-height;
75
+ background: none;
76
+ border: 0;
77
+ cursor: pointer;
78
+
79
+ &:hover {
80
+ background: $bdl-gray-05;
81
+ border-radius: $bdl-border-radius-size;
82
+ }
83
+ }
61
84
  }
62
85
 
63
86
  .collaborator-list-item.more {
@@ -67,5 +67,16 @@ describe('features/collaborator-avatars/CollaboratorList', () => {
67
67
  });
68
68
  expect(wrapper).toMatchSnapshot();
69
69
  });
70
+
71
+ test('should render component when canRemoveCollaborators prop is true', () => {
72
+ const onRemoveCollaboratorClickMock = jest.fn();
73
+ const wrapper = getWrapper({
74
+ canRemoveCollaborators: true,
75
+ onRemoveCollaboratorClick: onRemoveCollaboratorClickMock,
76
+ });
77
+
78
+ expect(wrapper.find('CollaboratorListItem')).toHaveLength(collaborators.length);
79
+ expect(wrapper).toMatchSnapshot();
80
+ });
70
81
  });
71
82
  });
@@ -69,5 +69,56 @@ describe('features/collaborator-avatars/CollaboratorListItem', () => {
69
69
 
70
70
  expect(wrapper).toMatchSnapshot();
71
71
  });
72
+
73
+ test('should render component when canRemoveCollaborators prop is true and collaborator is not removable', () => {
74
+ const wrapper = getWrapper({ canRemoveCollaborators: true, collaborator });
75
+
76
+ expect(wrapper.find('.role').exists()).toBe(true);
77
+ expect(wrapper.find('PlainButton')).toHaveLength(0);
78
+ expect(wrapper).toMatchSnapshot();
79
+ });
80
+
81
+ test('should render component when canRemoveCollaborators prop is true and collaborator is removable', () => {
82
+ const wrapper = getWrapper({
83
+ canRemoveCollaborators: true,
84
+ collaborator: { ...collaborator, isRemovable: true },
85
+ });
86
+
87
+ expect(wrapper.find('.role').exists()).toBe(true);
88
+ expect(wrapper.find('PlainButton').exists()).toBe(true);
89
+ expect(wrapper.find('Tooltip').exists()).toBe(true);
90
+ expect(wrapper).toMatchSnapshot();
91
+ });
92
+
93
+ test('should call onRemoveCollaborator when onRemoveCollaborator prop is passed', () => {
94
+ const onRemoveCollaboratorMock = jest.fn();
95
+ const wrapper = getWrapper({
96
+ canRemoveCollaborators: true,
97
+ onRemoveCollaborator: onRemoveCollaboratorMock,
98
+ collaborator: { ...collaborator, isRemovable: true },
99
+ });
100
+
101
+ const removeButton = wrapper.find('PlainButton');
102
+ removeButton.simulate('click');
103
+
104
+ expect(onRemoveCollaboratorMock).toHaveBeenCalledWith({ ...collaborator, isRemovable: true });
105
+ expect(wrapper).toMatchSnapshot();
106
+ });
107
+
108
+ test('should not call onRemoveCollaborator when onRemoveCollaborator prop is undefined', () => {
109
+ const onRemoveCollaboratorMock = jest.fn();
110
+
111
+ const wrapper = getWrapper({
112
+ canRemoveCollaborators: true,
113
+ onRemoveCollaborator: undefined,
114
+ collaborator: { ...collaborator, isRemovable: true },
115
+ });
116
+
117
+ const removeButton = wrapper.find('PlainButton');
118
+ removeButton.simulate('click');
119
+
120
+ expect(onRemoveCollaboratorMock).not.toHaveBeenCalled();
121
+ expect(wrapper).toMatchSnapshot();
122
+ });
72
123
  });
73
124
  });
@@ -1,5 +1,115 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
+ exports[`features/collaborator-avatars/CollaboratorList render() should render component when canRemoveCollaborators prop is true 1`] = `
4
+ <div
5
+ className="usm-collaborator-list"
6
+ >
7
+ <div
8
+ className="manage-all-btn-container"
9
+ >
10
+ <Link
11
+ className=""
12
+ href="/file/111/collaborators/"
13
+ rel="noopener"
14
+ target="_blank"
15
+ >
16
+ <span
17
+ className="manage-all-btn"
18
+ >
19
+ <FormattedMessage
20
+ defaultMessage="Manage All"
21
+ id="boxui.collaboratorAvatars.manageAllLinkText"
22
+ />
23
+ </span>
24
+ </Link>
25
+ </div>
26
+ <ul
27
+ className="be collaborator-list"
28
+ >
29
+ <CollaboratorListItem
30
+ canRemoveCollaborators={true}
31
+ collaborator={
32
+ {
33
+ "collabID": 1,
34
+ "email": "testa@example.com",
35
+ "hasCustomAvatar": false,
36
+ "name": "test a",
37
+ "type": "user",
38
+ "userID": 1,
39
+ }
40
+ }
41
+ index={0}
42
+ key="1-user"
43
+ onRemoveCollaborator={[MockFunction]}
44
+ trackingProps={
45
+ {
46
+ "emailProps": undefined,
47
+ "usernameProps": undefined,
48
+ }
49
+ }
50
+ />
51
+ <CollaboratorListItem
52
+ canRemoveCollaborators={true}
53
+ collaborator={
54
+ {
55
+ "collabID": 2,
56
+ "email": "testb@example.com",
57
+ "name": "test b",
58
+ "type": "user",
59
+ "userID": 2,
60
+ }
61
+ }
62
+ index={1}
63
+ key="2-user"
64
+ onRemoveCollaborator={[MockFunction]}
65
+ trackingProps={
66
+ {
67
+ "emailProps": undefined,
68
+ "usernameProps": undefined,
69
+ }
70
+ }
71
+ />
72
+ <CollaboratorListItem
73
+ canRemoveCollaborators={true}
74
+ collaborator={
75
+ {
76
+ "collabID": 3,
77
+ "email": "testc@example.com",
78
+ "hasCustomAvatar": true,
79
+ "imageUrl": "https://foo.bar",
80
+ "name": "test c",
81
+ "profileUrl": "http://foo.bar.profile",
82
+ "type": "user",
83
+ "userID": 3,
84
+ }
85
+ }
86
+ index={2}
87
+ key="3-user"
88
+ onRemoveCollaborator={[MockFunction]}
89
+ trackingProps={
90
+ {
91
+ "emailProps": undefined,
92
+ "usernameProps": undefined,
93
+ }
94
+ }
95
+ />
96
+ </ul>
97
+ <ModalActions>
98
+ <Button
99
+ className="btn-done"
100
+ isLoading={false}
101
+ showRadar={false}
102
+ type="button"
103
+ >
104
+ <FormattedMessage
105
+ defaultMessage="Done"
106
+ id="boxui.core.done"
107
+ />
108
+ </Button>
109
+ </ModalActions>
110
+ </div>
111
+ `;
112
+
3
113
  exports[`features/collaborator-avatars/CollaboratorList render() should render default component 1`] = `
4
114
  <div
5
115
  className="usm-collaborator-list"
@@ -1,5 +1,315 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
+ exports[`features/collaborator-avatars/CollaboratorListItem render() should call onRemoveCollaborator when onRemoveCollaborator prop is passed 1`] = `
4
+ <li>
5
+ <div
6
+ className="collaborator-list-item"
7
+ >
8
+ <div
9
+ className="bdl-CollaboratorListItem-user user"
10
+ >
11
+ <div
12
+ className="info"
13
+ >
14
+ <div
15
+ className="name"
16
+ >
17
+ <Link
18
+ className=""
19
+ href="/profile/undefined"
20
+ rel="noopener"
21
+ target="_blank"
22
+ >
23
+ test c
24
+ </Link>
25
+ </div>
26
+ <div
27
+ className="email"
28
+ >
29
+ <Link
30
+ className=""
31
+ href="mailto:testc@example.com"
32
+ >
33
+ testc@example.com
34
+ </Link>
35
+ </div>
36
+ </div>
37
+ <CollaboratorAvatarItem
38
+ allowBadging={true}
39
+ email="testc@example.com"
40
+ expiration={
41
+ {
42
+ "expiresAt": "Jan 1, 1966",
43
+ }
44
+ }
45
+ hasCustomAvatar={true}
46
+ id={1}
47
+ name="test c"
48
+ />
49
+ </div>
50
+ <div
51
+ className="user-actions"
52
+ >
53
+ <div
54
+ className="role"
55
+ />
56
+ <Tooltip
57
+ constrainToScrollParent={false}
58
+ constrainToWindow={true}
59
+ isDisabled={false}
60
+ isTabbable={false}
61
+ position="top-center"
62
+ text={
63
+ <FormattedMessage
64
+ defaultMessage="Remove"
65
+ id="be.remove"
66
+ />
67
+ }
68
+ theme="default"
69
+ >
70
+ <PlainButton
71
+ className="remove-button"
72
+ onClick={[Function]}
73
+ type="button"
74
+ >
75
+ <X16
76
+ color="##6f6f6f"
77
+ height={16}
78
+ width={16}
79
+ />
80
+ </PlainButton>
81
+ </Tooltip>
82
+ </div>
83
+ </div>
84
+ </li>
85
+ `;
86
+
87
+ exports[`features/collaborator-avatars/CollaboratorListItem render() should not call onRemoveCollaborator when onRemoveCollaborator prop is undefined 1`] = `
88
+ <li>
89
+ <div
90
+ className="collaborator-list-item"
91
+ >
92
+ <div
93
+ className="bdl-CollaboratorListItem-user user"
94
+ >
95
+ <div
96
+ className="info"
97
+ >
98
+ <div
99
+ className="name"
100
+ >
101
+ <Link
102
+ className=""
103
+ href="/profile/undefined"
104
+ rel="noopener"
105
+ target="_blank"
106
+ >
107
+ test c
108
+ </Link>
109
+ </div>
110
+ <div
111
+ className="email"
112
+ >
113
+ <Link
114
+ className=""
115
+ href="mailto:testc@example.com"
116
+ >
117
+ testc@example.com
118
+ </Link>
119
+ </div>
120
+ </div>
121
+ <CollaboratorAvatarItem
122
+ allowBadging={true}
123
+ email="testc@example.com"
124
+ expiration={
125
+ {
126
+ "expiresAt": "Jan 1, 1966",
127
+ }
128
+ }
129
+ hasCustomAvatar={true}
130
+ id={1}
131
+ name="test c"
132
+ />
133
+ </div>
134
+ <div
135
+ className="user-actions"
136
+ >
137
+ <div
138
+ className="role"
139
+ />
140
+ <Tooltip
141
+ constrainToScrollParent={false}
142
+ constrainToWindow={true}
143
+ isDisabled={false}
144
+ isTabbable={false}
145
+ position="top-center"
146
+ text={
147
+ <FormattedMessage
148
+ defaultMessage="Remove"
149
+ id="be.remove"
150
+ />
151
+ }
152
+ theme="default"
153
+ >
154
+ <PlainButton
155
+ className="remove-button"
156
+ onClick={[Function]}
157
+ type="button"
158
+ >
159
+ <X16
160
+ color="##6f6f6f"
161
+ height={16}
162
+ width={16}
163
+ />
164
+ </PlainButton>
165
+ </Tooltip>
166
+ </div>
167
+ </div>
168
+ </li>
169
+ `;
170
+
171
+ exports[`features/collaborator-avatars/CollaboratorListItem render() should render component when canRemoveCollaborators prop is true and collaborator is not removable 1`] = `
172
+ <li>
173
+ <div
174
+ className="collaborator-list-item"
175
+ >
176
+ <div
177
+ className="bdl-CollaboratorListItem-user user"
178
+ >
179
+ <div
180
+ className="info"
181
+ >
182
+ <div
183
+ className="name"
184
+ >
185
+ <Link
186
+ className=""
187
+ href="/profile/undefined"
188
+ rel="noopener"
189
+ target="_blank"
190
+ >
191
+ test c
192
+ </Link>
193
+ </div>
194
+ <div
195
+ className="email"
196
+ >
197
+ <Link
198
+ className=""
199
+ href="mailto:testc@example.com"
200
+ >
201
+ testc@example.com
202
+ </Link>
203
+ </div>
204
+ </div>
205
+ <CollaboratorAvatarItem
206
+ allowBadging={true}
207
+ email="testc@example.com"
208
+ expiration={
209
+ {
210
+ "expiresAt": "Jan 1, 1966",
211
+ }
212
+ }
213
+ hasCustomAvatar={true}
214
+ id={1}
215
+ name="test c"
216
+ />
217
+ </div>
218
+ <div
219
+ className="user-actions"
220
+ >
221
+ <div
222
+ className="role"
223
+ />
224
+ </div>
225
+ </div>
226
+ </li>
227
+ `;
228
+
229
+ exports[`features/collaborator-avatars/CollaboratorListItem render() should render component when canRemoveCollaborators prop is true and collaborator is removable 1`] = `
230
+ <li>
231
+ <div
232
+ className="collaborator-list-item"
233
+ >
234
+ <div
235
+ className="bdl-CollaboratorListItem-user user"
236
+ >
237
+ <div
238
+ className="info"
239
+ >
240
+ <div
241
+ className="name"
242
+ >
243
+ <Link
244
+ className=""
245
+ href="/profile/undefined"
246
+ rel="noopener"
247
+ target="_blank"
248
+ >
249
+ test c
250
+ </Link>
251
+ </div>
252
+ <div
253
+ className="email"
254
+ >
255
+ <Link
256
+ className=""
257
+ href="mailto:testc@example.com"
258
+ >
259
+ testc@example.com
260
+ </Link>
261
+ </div>
262
+ </div>
263
+ <CollaboratorAvatarItem
264
+ allowBadging={true}
265
+ email="testc@example.com"
266
+ expiration={
267
+ {
268
+ "expiresAt": "Jan 1, 1966",
269
+ }
270
+ }
271
+ hasCustomAvatar={true}
272
+ id={1}
273
+ name="test c"
274
+ />
275
+ </div>
276
+ <div
277
+ className="user-actions"
278
+ >
279
+ <div
280
+ className="role"
281
+ />
282
+ <Tooltip
283
+ constrainToScrollParent={false}
284
+ constrainToWindow={true}
285
+ isDisabled={false}
286
+ isTabbable={false}
287
+ position="top-center"
288
+ text={
289
+ <FormattedMessage
290
+ defaultMessage="Remove"
291
+ id="be.remove"
292
+ />
293
+ }
294
+ theme="default"
295
+ >
296
+ <PlainButton
297
+ className="remove-button"
298
+ onClick={[Function]}
299
+ type="button"
300
+ >
301
+ <X16
302
+ color="##6f6f6f"
303
+ height={16}
304
+ width={16}
305
+ />
306
+ </PlainButton>
307
+ </Tooltip>
308
+ </div>
309
+ </div>
310
+ </li>
311
+ `;
312
+
3
313
  exports[`features/collaborator-avatars/CollaboratorListItem render() should render default component 1`] = `
4
314
  <li>
5
315
  <div
@@ -172,4 +172,14 @@ describe('components/message-center/MessageCenter.integration', () => {
172
172
 
173
173
  expect(wrapper.find(Message)).toHaveLength(2);
174
174
  });
175
+
176
+ test('should render ButtonComponent with badgeCount prop passed from MessageCenter', async () => {
177
+ const wrapper = await getWrapper();
178
+ const badgeCount = countResponse.count;
179
+
180
+ await actWait();
181
+ wrapper.update();
182
+
183
+ expect(wrapper.find('ButtonComponent').props().badgeCount).toBe(badgeCount);
184
+ });
175
185
  });
@@ -16,7 +16,7 @@ import Internationalize from '../../../elements/common/Internationalize';
16
16
 
17
17
  type Props = {|
18
18
  apiHost: string,
19
- buttonComponent: React.ComponentType<{ render: () => React.Node }>,
19
+ buttonComponent: React.ComponentType<{ render: () => React.Node, badgeCount: null | number }>,
20
20
  contentPreviewProps?: ContentPreviewProps,
21
21
  getEligibleMessages: () => Promise<GetEligibleMessageCenterMessages>,
22
22
  getToken: (fileId: string) => Promise<Token>,
@@ -102,6 +102,7 @@ function MessageCenter({
102
102
 
103
103
  const icon = (
104
104
  <ButtonComponent
105
+ badgeCount={unreadMessageCount}
105
106
  data-resin-target="messageCenterOpenModal"
106
107
  data-testid="message-center-unread-count"
107
108
  onClick={handleOnClick}
@@ -1,6 +1,6 @@
1
1
  ### Description
2
2
 
3
- This is the simplified sharing modal, interally referred to as the Unified Share Modal
3
+ This is the simplified sharing modal, internally referred to as the Unified Share Modal
4
4
  (a combination of the previous invite collaborators modal and the shared link modal).
5
5
 
6
6
  ### Examples
@@ -95,6 +95,7 @@ class USMExample extends React.Component {
95
95
  }
96
96
 
97
97
  getInitialData() {
98
+ const { canRemoveCollaborators } = this.props;
98
99
  const initialPromise = this.fakeRequest();
99
100
  const fetchCollaborators = new Promise(resolved => {
100
101
  setTimeout(() => {
@@ -112,6 +113,10 @@ class USMExample extends React.Component {
112
113
  }
113
114
  }
114
115
 
116
+ if (canRemoveCollaborators) {
117
+ contact.isRemovable = contact.translatedRole !== 'Owner';
118
+ }
119
+
115
120
  return contact;
116
121
  }),
117
122
  };
@@ -248,6 +253,8 @@ class USMExample extends React.Component {
248
253
  modalTracking: {},
249
254
  collaboratorListTracking: {},
250
255
  } }
256
+ canRemoveCollaborators={this.props.canRemoveCollaborators}
257
+ onRemoveCollaborator={this.props.onRemoveCollaborator}
251
258
  /> }
252
259
  <Button
253
260
  onClick={ () =>
@@ -310,6 +317,10 @@ class USMSharedLinkExample extends USMExample {
310
317
  This shows the Unified share modal when it needs to generate a shared link, and should auto-focus.
311
318
  <USMExample buttonText="Open USM Modal" shouldFocusSharedLinkOnLoad shouldCreateSharedLinkOnLoad />
312
319
  </div>
320
+ <div>
321
+ This shows the Unified share modal with functionality to remove collaborators
322
+ <USMExample buttonText="Open USM Modal" canRemoveCollaborators onRemoveCollaborator={() => {}} />
323
+ </div>
313
324
  </div>
314
325
 
315
326
  ```