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
@@ -0,0 +1,67 @@
1
+ // @flow
2
+ import React, { useEffect } from 'react';
3
+ import { FormattedMessage } from 'react-intl';
4
+
5
+ import { Modal, ModalActions } from '../../components/modal';
6
+ import Button from '../../components/button';
7
+ import PrimaryButton from '../../components/primary-button';
8
+ import commonMessages from '../../common/messages';
9
+ import messages from './messages';
10
+ import type { collaboratorType } from './flowTypes';
11
+
12
+ type Props = {
13
+ cancelButtonProps?: Object,
14
+ collaborator: ?collaboratorType,
15
+ isOpen: boolean,
16
+ modalProps?: Object,
17
+ okayButtonProps?: Object,
18
+ onLoad?: Function,
19
+ onRequestClose: Function,
20
+ onSubmit: Function,
21
+ submitting: boolean,
22
+ };
23
+
24
+ const RemoveCollaboratorConfirmModal = ({
25
+ isOpen,
26
+ onRequestClose,
27
+ onSubmit,
28
+ submitting,
29
+ collaborator,
30
+ okayButtonProps,
31
+ modalProps,
32
+ cancelButtonProps,
33
+ onLoad,
34
+ }: Props) => {
35
+ useEffect(() => {
36
+ onLoad?.();
37
+ }, [onLoad]);
38
+
39
+ return (
40
+ <Modal
41
+ className="be-modal"
42
+ focusElementSelector=".btn-primary"
43
+ isOpen={isOpen}
44
+ onRequestClose={submitting ? undefined : onRequestClose}
45
+ title={<FormattedMessage {...messages.removeCollaboratorConfirmationTitle} />}
46
+ type="alert"
47
+ {...modalProps}
48
+ >
49
+ <FormattedMessage
50
+ {...messages.removeCollaboratorConfirmationDescription}
51
+ values={{
52
+ name: collaborator?.email ?? collaborator?.name,
53
+ }}
54
+ />
55
+ <ModalActions>
56
+ <Button isDisabled={submitting} onClick={onRequestClose} {...cancelButtonProps}>
57
+ <FormattedMessage {...commonMessages.cancel} />
58
+ </Button>
59
+ <PrimaryButton isDisabled={submitting} isLoading={submitting} onClick={onSubmit} {...okayButtonProps}>
60
+ <FormattedMessage {...commonMessages.okay} />
61
+ </PrimaryButton>
62
+ </ModalActions>
63
+ </Modal>
64
+ );
65
+ };
66
+
67
+ export default RemoveCollaboratorConfirmModal;
@@ -66,6 +66,7 @@ class UnifiedShareForm extends React.Component<USFProps, State> {
66
66
  removeLinkConfirmModalTracking: {},
67
67
  sharedLinkEmailTracking: {},
68
68
  sharedLinkTracking: {},
69
+ removeCollaboratorConfirmModalTracking: {},
69
70
  },
70
71
  };
71
72
 
@@ -647,7 +648,8 @@ class UnifiedShareForm extends React.Component<USFProps, State> {
647
648
  }
648
649
 
649
650
  renderCollaboratorList() {
650
- const { item, collaboratorsList, trackingProps } = this.props;
651
+ const { item, collaboratorsList, trackingProps, canRemoveCollaborators, onRemoveCollaboratorClick } =
652
+ this.props;
651
653
  const { name, type } = item;
652
654
  const { collaboratorListTracking } = trackingProps;
653
655
  let listContent = null;
@@ -663,6 +665,8 @@ class UnifiedShareForm extends React.Component<USFProps, State> {
663
665
  item={item}
664
666
  collaborators={collaborators}
665
667
  trackingProps={collaboratorListTracking}
668
+ canRemoveCollaborators={canRemoveCollaborators}
669
+ onRemoveCollaboratorClick={onRemoveCollaboratorClick}
666
670
  />
667
671
  );
668
672
  }
@@ -8,15 +8,18 @@ import { Modal } from '../../components/modal';
8
8
  import UnifiedShareModalTitle from './UnifiedShareModalTitle';
9
9
  import UnifiedShareForm from './UnifiedShareForm';
10
10
  import RemoveLinkConfirmModal from './RemoveLinkConfirmModal';
11
- import type { USMProps } from './flowTypes';
11
+ import RemoveCollaboratorConfirmModal from './RemoveCollaboratorConfirmModal';
12
+ import type { USMProps, collaboratorType } from './flowTypes';
12
13
 
13
14
  import './UnifiedShareModal.scss';
14
15
 
15
16
  type State = {
17
+ collaboratorToRemove: ?collaboratorType,
16
18
  getInitialDataCalled: boolean,
17
- isConfirmModalOpen: boolean,
18
19
  isEmailLinkSectionExpanded: boolean,
19
20
  isFetching: boolean,
21
+ isRemoveCollaboratorConfirmModalOpen: boolean,
22
+ isRemoveLinkConfirmModalOpen: boolean,
20
23
  sharedLinkLoaded: boolean,
21
24
  shouldRenderFTUXTooltip: boolean,
22
25
  showCollaboratorList: boolean,
@@ -24,6 +27,7 @@ type State = {
24
27
 
25
28
  class UnifiedShareModal extends React.Component<USMProps, State> {
26
29
  static defaultProps = {
30
+ canRemoveCollaborators: false,
27
31
  displayInModal: true,
28
32
  initiallySelectedContacts: [],
29
33
  isAllowEditSharedLinkForFileEnabled: false,
@@ -38,6 +42,7 @@ class UnifiedShareModal extends React.Component<USMProps, State> {
38
42
  inviteCollabTracking: {},
39
43
  modalTracking: {},
40
44
  removeLinkConfirmModalTracking: {},
45
+ removeCollaboratorConfirmModalTracking: {},
41
46
  collaboratorListTracking: {},
42
47
  },
43
48
  };
@@ -48,8 +53,10 @@ class UnifiedShareModal extends React.Component<USMProps, State> {
48
53
  const { initialDataReceived } = props;
49
54
 
50
55
  this.state = {
56
+ collaboratorToRemove: null,
51
57
  getInitialDataCalled: !!initialDataReceived,
52
- isConfirmModalOpen: false,
58
+ isRemoveLinkConfirmModalOpen: false,
59
+ isRemoveCollaboratorConfirmModalOpen: false,
53
60
  isEmailLinkSectionExpanded: false,
54
61
  isFetching: !initialDataReceived,
55
62
  sharedLinkLoaded: false,
@@ -121,11 +128,26 @@ class UnifiedShareModal extends React.Component<USMProps, State> {
121
128
  };
122
129
 
123
130
  openConfirmModal = () => {
124
- this.setState({ isConfirmModalOpen: true });
131
+ this.setState({ isRemoveLinkConfirmModalOpen: true });
132
+ };
133
+
134
+ openRemoveCollaboratorConfirmModal = (collaborator: collaboratorType) => {
135
+ const { canRemoveCollaborators } = this.props;
136
+ if (canRemoveCollaborators) {
137
+ this.setState({ isRemoveCollaboratorConfirmModalOpen: true, collaboratorToRemove: collaborator });
138
+ }
125
139
  };
126
140
 
127
141
  closeConfirmModal = () => {
128
- this.setState({ isConfirmModalOpen: false });
142
+ this.setState({ isRemoveLinkConfirmModalOpen: false });
143
+ };
144
+
145
+ closeRemoveCollaboratorConfirmModal = () => {
146
+ this.setState({
147
+ isRemoveCollaboratorConfirmModalOpen: false,
148
+ collaboratorToRemove: null,
149
+ shouldRenderFTUXTooltip: false,
150
+ });
129
151
  };
130
152
 
131
153
  removeLink = () => {
@@ -136,6 +158,15 @@ class UnifiedShareModal extends React.Component<USMProps, State> {
136
158
  }
137
159
  };
138
160
 
161
+ removeCollaborator = async () => {
162
+ const { onRemoveCollaborator } = this.props;
163
+ if (this.state.collaboratorToRemove) {
164
+ await onRemoveCollaborator?.(this.state.collaboratorToRemove);
165
+ }
166
+
167
+ this.closeRemoveCollaboratorConfirmModal();
168
+ };
169
+
139
170
  renderUSF = () => {
140
171
  const { onCollaboratorAvatarsClick, sharedLinkEditTagTargetingApi, sharedLinkEditTooltipTargetingApi } =
141
172
  this.props;
@@ -146,6 +177,7 @@ class UnifiedShareModal extends React.Component<USMProps, State> {
146
177
  {...this.props}
147
178
  onCollaboratorAvatarsClick={onCollaboratorAvatarsClick}
148
179
  handleFtuxCloseClick={this.handleFtuxCloseClick}
180
+ onRemoveCollaboratorClick={this.openRemoveCollaboratorConfirmModal}
149
181
  isFetching={isFetching}
150
182
  openConfirmModal={this.openConfirmModal}
151
183
  sharedLinkEditTagTargetingApi={sharedLinkEditTagTargetingApi}
@@ -159,14 +191,19 @@ class UnifiedShareModal extends React.Component<USMProps, State> {
159
191
  render() {
160
192
  // Shared link section props
161
193
  const { canInvite, displayInModal, isOpen, item, onRequestClose, submitting, trackingProps } = this.props;
162
- const { modalTracking, removeLinkConfirmModalTracking } = trackingProps;
194
+ const { modalTracking, removeLinkConfirmModalTracking, removeCollaboratorConfirmModalTracking } = trackingProps;
163
195
  const { modalProps } = modalTracking;
164
- const { isEmailLinkSectionExpanded, isConfirmModalOpen, showCollaboratorList } = this.state;
196
+ const {
197
+ isEmailLinkSectionExpanded,
198
+ isRemoveLinkConfirmModalOpen,
199
+ isRemoveCollaboratorConfirmModalOpen,
200
+ showCollaboratorList,
201
+ } = this.state;
165
202
 
166
203
  // focus logic at modal level
167
204
  const extendedModalProps = {
168
205
  focusElementSelector: canInvite
169
- ? '.bdl-PillSelector-input' // focus on invite collabs field
206
+ ? '.bdl-PillSelector-input' // focus on invite collaborators field
170
207
  : '.toggle-simple', // focus on shared link toggle
171
208
  ...modalProps,
172
209
  };
@@ -176,7 +213,7 @@ class UnifiedShareModal extends React.Component<USMProps, State> {
176
213
  {displayInModal ? (
177
214
  <Modal
178
215
  className="be-modal unified-share-modal"
179
- isOpen={isConfirmModalOpen ? false : isOpen}
216
+ isOpen={isRemoveLinkConfirmModalOpen || isRemoveCollaboratorConfirmModalOpen ? false : isOpen}
180
217
  onRequestClose={submitting ? undefined : onRequestClose}
181
218
  title={
182
219
  <UnifiedShareModalTitle
@@ -192,15 +229,26 @@ class UnifiedShareModal extends React.Component<USMProps, State> {
192
229
  ) : (
193
230
  <div className="bdl-UnifiedShareForm-container">{this.renderUSF()}</div>
194
231
  )}
195
- {isConfirmModalOpen && (
232
+ {isRemoveLinkConfirmModalOpen && (
196
233
  <RemoveLinkConfirmModal
197
- isOpen={isConfirmModalOpen}
234
+ isOpen={isRemoveLinkConfirmModalOpen}
198
235
  onRequestClose={this.closeConfirmModal}
199
236
  removeLink={this.removeLink}
200
237
  submitting={submitting}
201
238
  {...removeLinkConfirmModalTracking}
202
239
  />
203
240
  )}
241
+ {isRemoveCollaboratorConfirmModalOpen && (
242
+ <RemoveCollaboratorConfirmModal
243
+ isOpen={isRemoveCollaboratorConfirmModalOpen}
244
+ onRequestClose={this.closeRemoveCollaboratorConfirmModal}
245
+ onSubmit={this.removeCollaborator}
246
+ submitting={submitting}
247
+ collaborator={this.state.collaboratorToRemove}
248
+ modalProps={{ className: 'remove-collaborator-confirm-modal' }}
249
+ {...removeCollaboratorConfirmModalTracking}
250
+ />
251
+ )}
204
252
  </>
205
253
  );
206
254
  }
@@ -53,7 +53,7 @@
53
53
  }
54
54
 
55
55
  .unified-share-modal {
56
- /** title and classifiction label */
56
+ /** title and classification label */
57
57
  .bdl-UnifiedShareModalTitle-classification {
58
58
  display: inline;
59
59
  }
@@ -99,7 +99,8 @@
99
99
  margin-bottom: 20px;
100
100
  }
101
101
 
102
- .bdl-PillSelectorDropdown .bdl-PillSelector, // need both selectors for specificity
102
+ // need both selectors for specificity
103
+ .bdl-PillSelectorDropdown .bdl-PillSelector,
103
104
  textarea {
104
105
  /* override for DOM element in `TextArea` which provides no id/class for targeting */
105
106
  width: 100%;
@@ -328,6 +329,12 @@
328
329
  }
329
330
  }
330
331
 
332
+ .remove-collaborator-confirm-modal {
333
+ & .modal-content {
334
+ word-break: break-word;
335
+ }
336
+ }
337
+
331
338
  @include breakpoint($medium-screen) {
332
339
  .usm-menu-description {
333
340
  white-space: normal;
@@ -0,0 +1,64 @@
1
+ import * as React from 'react';
2
+ import userEvent from '@testing-library/user-event';
3
+ import { screen, render } from '../../../test-utils/testing-library';
4
+ import RemoveCollaboratorConfirmModal from '../RemoveCollaboratorConfirmModal';
5
+
6
+ describe('features/unified-share-modal/RemoveCollaboratorConfirmModal', () => {
7
+ const renderComponent = (props = {}) =>
8
+ render(<RemoveCollaboratorConfirmModal isOpen onRequestClose={jest.fn()} onSubmit={jest.fn()} {...props} />);
9
+
10
+ test('should render a confirmation Modal', async () => {
11
+ const collaborator = { email: 'dt@example.com' };
12
+ const onRequestClose = jest.fn();
13
+ renderComponent({
14
+ onRequestClose,
15
+ collaborator,
16
+ });
17
+
18
+ const modal = screen.getByRole('alertdialog');
19
+ expect(modal).toBeInTheDocument();
20
+
21
+ const title = screen.getByRole('heading', { name: 'Remove Collaborator' });
22
+ expect(title).toBeInTheDocument();
23
+
24
+ const description = screen.getByRole('paragraph');
25
+ expect(description).toHaveTextContent(
26
+ `Are you sure you want to remove ${collaborator.email} as a collaborator?`,
27
+ );
28
+
29
+ const submitButton = screen.getByRole('button', { name: 'Okay' });
30
+ expect(submitButton).toBeInTheDocument();
31
+
32
+ const cancelButton = screen.getByRole('button', { name: 'Cancel' });
33
+ expect(cancelButton).toBeInTheDocument();
34
+ await userEvent.click(cancelButton);
35
+
36
+ expect(onRequestClose).toHaveBeenCalledTimes(1);
37
+ });
38
+
39
+ test('should call onSubmit callback when submit button is clicked', async () => {
40
+ const onSubmit = jest.fn();
41
+ renderComponent({
42
+ onSubmit,
43
+ collaborator: { email: 'dt@example.com' },
44
+ });
45
+
46
+ const submitButton = screen.getByRole('button', { name: 'Okay' });
47
+ await userEvent.click(submitButton);
48
+
49
+ expect(onSubmit).toHaveBeenCalledTimes(1);
50
+ });
51
+
52
+ test('should disable modal buttons and set loading state when props.submitting is true', () => {
53
+ renderComponent({
54
+ submitting: true,
55
+ collaborator: { email: 'dt@example.com' },
56
+ });
57
+
58
+ const submitButton = screen.getByRole('button', { name: 'Okay' });
59
+ expect(submitButton).toHaveAttribute('aria-disabled', 'true');
60
+
61
+ const cancelButton = screen.getByRole('button', { name: 'Cancel' });
62
+ expect(cancelButton).toHaveAttribute('aria-disabled', 'true');
63
+ });
64
+ });
@@ -131,7 +131,11 @@ describe('features/unified-share-modal/UnifiedShareForm', () => {
131
131
  });
132
132
 
133
133
  test('should render a default component with confirm modal open', () => {
134
- const wrapper = getWrapper({ isConfirmModalOpen: true, isFetching: false, closeConfirmModal: () => null });
134
+ const wrapper = getWrapper({
135
+ isRemoveLinkConfirmModalOpen: true,
136
+ isFetching: false,
137
+ closeConfirmModal: () => null,
138
+ });
135
139
  expect(wrapper).toMatchSnapshot();
136
140
  });
137
141
 
@@ -376,6 +380,35 @@ describe('features/unified-share-modal/UnifiedShareForm', () => {
376
380
  const wrapper = getWrapper();
377
381
  expect(wrapper.exists('AdvancedContentInsightsToggle')).toBe(false);
378
382
  });
383
+
384
+ test('should render a collaborator list when canRemoveCollaborators prop is set to true and onRemoveCollaboratorClick is defined', () => {
385
+ const onRemoveCollaboratorMock = jest.fn();
386
+ const collaborators = [
387
+ { name: 'test a', hasCustomAvatar: false },
388
+ { name: 'test b', hasCustomAvatar: false, isRemovable: true },
389
+ ];
390
+
391
+ const wrapper = getWrapper({
392
+ collaboratorsList: {
393
+ ...collaboratorsList,
394
+ collaborators,
395
+ },
396
+ canRemoveCollaborators: true,
397
+ onRemoveCollaboratorClick: onRemoveCollaboratorMock,
398
+ trackingProps: {
399
+ collaboratorListTracking: {},
400
+ modalTracking: {},
401
+ inviteCollabTracking: {},
402
+ },
403
+ });
404
+
405
+ wrapper.setState({ showCollaboratorList: false });
406
+ wrapper.instance().showCollaboratorList();
407
+
408
+ expect(wrapper.find('CollaboratorList').exists()).toBe(true);
409
+ expect(wrapper.find('CollaboratorList').prop('canRemoveCollaborators')).toBe(true);
410
+ expect(wrapper.find('CollaboratorList').prop('onRemoveCollaboratorClick')).toBe(onRemoveCollaboratorMock);
411
+ });
379
412
  });
380
413
 
381
414
  describe('renderCollaboratorAvatars()', () => {
@@ -117,7 +117,7 @@ describe('features/unified-share-modal/UnifiedShareModal', () => {
117
117
 
118
118
  test('should render a default component with confirm modal open', () => {
119
119
  const wrapper = getWrapper();
120
- wrapper.setState({ isFetching: false, isConfirmModalOpen: true });
120
+ wrapper.setState({ isFetching: false, isRemoveLinkConfirmModalOpen: true });
121
121
  expect(wrapper).toMatchSnapshot();
122
122
  });
123
123
 
@@ -260,6 +260,35 @@ describe('features/unified-share-modal/UnifiedShareModal', () => {
260
260
  wrapper.setState({ showCollaboratorList: true });
261
261
  expect(wrapper).toMatchSnapshot();
262
262
  });
263
+
264
+ test('should render a default component with confirm remove collaborator modal open', () => {
265
+ const wrapper = getWrapper({ canRemoveCollaborators: true, onRemoveCollaborator: jest.fn() });
266
+ wrapper.setState({
267
+ isFetching: false,
268
+ isRemoveCollaboratorConfirmModalOpen: true,
269
+ collaboratorToRemove: {
270
+ name: 'Collaborator a',
271
+ hasCustomAvatar: false,
272
+ },
273
+ });
274
+ expect(wrapper).toMatchSnapshot();
275
+ });
276
+
277
+ test('should render a default component with collaborator list when showCollaboratorList state is true', () => {
278
+ const collaborators = [
279
+ { name: 'test a', hasCustomAvatar: false, isRemovable: false },
280
+ { name: 'test b', hasCustomAvatar: false, isRemovable: true },
281
+ ];
282
+
283
+ const wrapper = getWrapper({
284
+ collaboratorsList: { ...collaboratorsList, collaborators },
285
+ canRemoveCollaborators: true,
286
+ onRemoveCollaborator: jest.fn(),
287
+ });
288
+ wrapper.setState({ showCollaboratorList: true });
289
+
290
+ expect(wrapper).toMatchSnapshot();
291
+ });
263
292
  });
264
293
 
265
294
  describe('getInitialData()', () => {
@@ -321,7 +350,7 @@ describe('features/unified-share-modal/UnifiedShareModal', () => {
321
350
 
322
351
  wrapper.instance().closeConfirmModal();
323
352
 
324
- expect(wrapper.state('isConfirmModalOpen')).toBe(false);
353
+ expect(wrapper.state('isRemoveLinkConfirmModalOpen')).toBe(false);
325
354
  });
326
355
 
327
356
  test('should set the state to closed if it was formerly open', () => {
@@ -329,11 +358,52 @@ describe('features/unified-share-modal/UnifiedShareModal', () => {
329
358
 
330
359
  wrapper.instance().openConfirmModal();
331
360
 
332
- expect(wrapper.state('isConfirmModalOpen')).toBe(true);
361
+ expect(wrapper.state('isRemoveLinkConfirmModalOpen')).toBe(true);
333
362
 
334
363
  wrapper.instance().closeConfirmModal();
335
364
 
336
- expect(wrapper.state('isConfirmModalOpen')).toBe(false);
365
+ expect(wrapper.state('isRemoveLinkConfirmModalOpen')).toBe(false);
366
+ });
367
+ });
368
+
369
+ describe('closeRemoveCollaboratorConfirmModal()', () => {
370
+ test('should keep the state as closed when called', () => {
371
+ const wrapper = getWrapper({
372
+ canRemoveCollaborators: true,
373
+ onRemoveCollaborator: jest.fn(),
374
+ });
375
+
376
+ wrapper.instance().closeRemoveCollaboratorConfirmModal();
377
+
378
+ expect(wrapper.state('isRemoveCollaboratorConfirmModalOpen')).toBe(false);
379
+ expect(wrapper.state('collaboratorToRemove')).toBe(null);
380
+ expect(wrapper.state('shouldRenderFTUXTooltip')).toBe(false);
381
+ });
382
+
383
+ test('should set the state to closed when it was previously open', () => {
384
+ const wrapper = getWrapper({
385
+ canRemoveCollaborators: true,
386
+ onRemoveCollaborator: jest.fn(),
387
+ });
388
+
389
+ wrapper.instance().openRemoveCollaboratorConfirmModal();
390
+
391
+ expect(wrapper.state('isRemoveCollaboratorConfirmModalOpen')).toBe(true);
392
+ expect(wrapper.state('collaboratorToRemove')).not.toBe(null);
393
+
394
+ wrapper.instance().closeRemoveCollaboratorConfirmModal();
395
+
396
+ expect(wrapper.state('isRemoveCollaboratorConfirmModalOpen')).toBe(false);
397
+ expect(wrapper.state('collaboratorToRemove')).toBe(null);
398
+ });
399
+
400
+ test('should not set the state to open when canRemoveCollaborators prop is not defined', () => {
401
+ const wrapper = getWrapper();
402
+
403
+ wrapper.instance().openRemoveCollaboratorConfirmModal();
404
+
405
+ expect(wrapper.state('isRemoveCollaboratorConfirmModalOpen')).toBe(false);
406
+ expect(wrapper.state('collaboratorToRemove')).toBe(null);
337
407
  });
338
408
  });
339
409
  });