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.
Files changed (81) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/components/FederatedFolder/DumbFederatedFolderModal.js +15 -16
  3. package/dist/components/FederatedFolder/FederatedFolderModal.js +78 -103
  4. package/dist/components/FederatedFolder/FederatedFolderModal.spec.js +102 -292
  5. package/dist/components/Recipient/GroupRecipientPermissions.js +15 -11
  6. package/dist/components/Recipient/LinkRecipient.js +15 -11
  7. package/dist/components/Recipient/LinkRecipientLite.js +1 -1
  8. package/dist/components/Recipient/LinkRecipientPermissions.js +2 -1
  9. package/dist/components/Recipient/MemberRecipient.spec.js +8 -10
  10. package/dist/components/Recipient/MemberRecipientLite.js +1 -1
  11. package/dist/components/Recipient/MemberRecipientPermissions.js +16 -12
  12. package/dist/components/Recipient/MemberRecipientPermissions.spec.js +62 -50
  13. package/dist/components/Recipient/RecipientConfirm.js +0 -5
  14. package/dist/components/ShareAutosuggest.js +9 -4
  15. package/dist/components/ShareByEmail.js +29 -274
  16. package/dist/components/ShareByEmail.spec.js +52 -230
  17. package/dist/components/ShareByLink.js +1 -3
  18. package/dist/components/ShareDialogCozyToCozy.js +169 -35
  19. package/dist/components/ShareDialogCozyToCozy.spec.js +123 -36
  20. package/dist/components/ShareDialogTwoStepsConfirmationContainer.js +13 -3
  21. package/dist/components/ShareModal/SharingDetailsModal.js +0 -5
  22. package/dist/components/ShareRecipientsInput.js +6 -3
  23. package/dist/components/SharedDrive/SharedDriveForm.js +17 -25
  24. package/dist/components/SharedDrive/SharedDriveModal.js +1 -1
  25. package/dist/components/SharedDrive/SharedDriveRecipientPermissions.js +15 -10
  26. package/dist/components/SharedDrive/useSharedDrive.js +33 -57
  27. package/dist/components/SharedDrive/useSharedDrive.spec.js +29 -93
  28. package/dist/components/SharedFolder/DumbBatchSharedFolderModal.js +15 -26
  29. package/dist/components/Sharetypeselect.js +85 -90
  30. package/dist/hooks/usePendingRecipients.js +20 -0
  31. package/dist/hooks/usePendingRecipients.spec.js +30 -0
  32. package/dist/styles/autosuggest.styl +8 -2
  33. package/dist/styles/share.styl +0 -39
  34. package/dist/stylesheet.css +8 -36
  35. package/locales/en.json +14 -44
  36. package/locales/fr.json +14 -44
  37. package/locales/ru.json +14 -44
  38. package/locales/vi.json +14 -42
  39. package/package.json +2 -2
  40. package/src/components/FederatedFolder/DumbFederatedFolderModal.jsx +14 -15
  41. package/src/components/FederatedFolder/FederatedFolderModal.jsx +50 -67
  42. package/src/components/FederatedFolder/FederatedFolderModal.spec.jsx +63 -186
  43. package/src/components/Recipient/GroupRecipientPermissions.jsx +15 -13
  44. package/src/components/Recipient/LinkRecipient.jsx +9 -9
  45. package/src/components/Recipient/LinkRecipientLite.jsx +1 -3
  46. package/src/components/Recipient/LinkRecipientPermissions.jsx +2 -1
  47. package/src/components/Recipient/MemberRecipient.spec.jsx +4 -6
  48. package/src/components/Recipient/MemberRecipientLite.jsx +2 -2
  49. package/src/components/Recipient/MemberRecipientPermissions.jsx +16 -21
  50. package/src/components/Recipient/MemberRecipientPermissions.spec.jsx +21 -23
  51. package/src/components/ShareAutosuggest.jsx +7 -2
  52. package/src/components/ShareByEmail.jsx +35 -186
  53. package/src/components/ShareByEmail.spec.jsx +22 -173
  54. package/src/components/ShareByLink.jsx +1 -7
  55. package/src/components/ShareDialogCozyToCozy.jsx +171 -38
  56. package/src/components/ShareDialogCozyToCozy.spec.jsx +67 -1
  57. package/src/components/ShareDialogTwoStepsConfirmationContainer.jsx +11 -1
  58. package/src/components/ShareRecipientsInput.jsx +5 -2
  59. package/src/components/SharedDrive/SharedDriveForm.jsx +16 -25
  60. package/src/components/SharedDrive/SharedDriveModal.jsx +1 -1
  61. package/src/components/SharedDrive/SharedDriveRecipientPermissions.jsx +15 -17
  62. package/src/components/SharedDrive/useSharedDrive.js +24 -50
  63. package/src/components/SharedDrive/useSharedDrive.spec.js +19 -67
  64. package/src/components/SharedFolder/DumbBatchSharedFolderModal.jsx +15 -29
  65. package/src/components/Sharetypeselect.jsx +75 -58
  66. package/src/hooks/usePendingRecipients.js +13 -0
  67. package/src/hooks/usePendingRecipients.spec.js +21 -0
  68. package/src/styles/autosuggest.styl +8 -2
  69. package/src/styles/share.styl +0 -39
  70. package/dist/components/Recipient/actions/revokeGroup.js +0 -42
  71. package/dist/components/Recipient/actions/revokeMember.js +0 -42
  72. package/dist/components/Recipient/actions/revokeSharedDriveMember.js +0 -41
  73. package/dist/components/SharedDrive/helpers.js +0 -102
  74. package/dist/components/SharedDrive/helpers.spec.js +0 -227
  75. package/dist/components/Sharesubmit.js +0 -28
  76. package/src/components/Recipient/actions/revokeGroup.js +0 -42
  77. package/src/components/Recipient/actions/revokeMember.js +0 -42
  78. package/src/components/Recipient/actions/revokeSharedDriveMember.js +0 -41
  79. package/src/components/SharedDrive/helpers.js +0 -108
  80. package/src/components/SharedDrive/helpers.spec.js +0 -177
  81. package/src/components/Sharesubmit.jsx +0 -31
@@ -73,7 +73,7 @@ describe('MemberRecipient component', () => {
73
73
  const onRevoke = jest.fn()
74
74
  const onRevokeSelf = jest.fn()
75
75
 
76
- const { getByText } = setup({
76
+ const { getByLabelText } = setup({
77
77
  instance: 'foo.mycozy.cloud',
78
78
  status: 'ready',
79
79
  type: 'two-way',
@@ -82,8 +82,7 @@ describe('MemberRecipient component', () => {
82
82
  onRevokeSelf
83
83
  })
84
84
 
85
- fireEvent.click(getByText('can change'))
86
- fireEvent.click(getByText('Remove me from sharing'))
85
+ fireEvent.click(getByLabelText('Remove from sharing'))
87
86
  expect(onRevoke).not.toHaveBeenCalled()
88
87
  expect(onRevokeSelf).toHaveBeenCalled()
89
88
  })
@@ -92,7 +91,7 @@ describe('MemberRecipient component', () => {
92
91
  const onRevoke = jest.fn()
93
92
  const onRevokeSelf = jest.fn()
94
93
 
95
- const { getByText } = setup({
94
+ const { getByLabelText } = setup({
96
95
  instance: 'foo.mycozy.cloud',
97
96
  status: 'ready',
98
97
  type: 'two-way',
@@ -102,8 +101,7 @@ describe('MemberRecipient component', () => {
102
101
  onRevokeSelf
103
102
  })
104
103
 
105
- fireEvent.click(getByText('can change'))
106
- fireEvent.click(getByText('Remove from sharing'))
104
+ fireEvent.click(getByLabelText('Remove from sharing'))
107
105
  expect(onRevoke).toHaveBeenCalled()
108
106
  expect(onRevokeSelf).not.toHaveBeenCalled()
109
107
  })
@@ -44,8 +44,8 @@ const MemberRecipientLite = ({ recipient, isOwner, ...props }) => {
44
44
  />
45
45
  <Typography className="u-flex-shrink-0" variant="body2">
46
46
  {recipientOwner
47
- ? t(`Share.status.${recipient.status}`).toLowerCase()
48
- : t(`Share.type.${recipient.type ?? 'one-way'}`).toLowerCase()}
47
+ ? t(`Share.status.${recipient.status}`)
48
+ : t(`Share.type.${recipient.type ?? 'one-way'}`)}
49
49
  </Typography>
50
50
  </ListItem>
51
51
  )
@@ -3,17 +3,16 @@ import React, { useState, useRef, useCallback } from 'react'
3
3
  import { useClient } from 'cozy-client'
4
4
  import minilog from 'cozy-minilog'
5
5
  import ActionsMenu from 'cozy-ui/transpiled/react/ActionsMenu'
6
- import {
7
- makeActions,
8
- divider
9
- } from 'cozy-ui/transpiled/react/ActionsMenu/Actions'
6
+ import { makeActions } from 'cozy-ui/transpiled/react/ActionsMenu/Actions'
10
7
  import DropdownButton from 'cozy-ui/transpiled/react/DropdownButton'
8
+ import Icon from 'cozy-ui/transpiled/react/Icon'
9
+ import IconButton from 'cozy-ui/transpiled/react/IconButton'
10
+ import CrossCircleOutlineIcon from 'cozy-ui/transpiled/react/Icons/CrossCircleOutline'
11
11
  import Spinner from 'cozy-ui/transpiled/react/Spinner'
12
12
  import Typography from 'cozy-ui/transpiled/react/Typography'
13
13
  import { useAlert } from 'cozy-ui/transpiled/react/providers/Alert'
14
14
  import { useI18n } from 'twake-i18n'
15
15
 
16
- import { revokeMember } from './actions/revokeMember'
17
16
  import { setReadOnlySharedPermission } from './actions/setReadOnlySharedPermission'
18
17
  import { setReadWriteSharedPermission } from './actions/setReadWriteSharedPermission'
19
18
  import { useSharingContext } from '../../hooks/useSharingContext'
@@ -22,7 +21,6 @@ const log = minilog('MemberRecipientPermissions')
22
21
 
23
22
  const MemberRecipientPermissions = ({
24
23
  isOwner,
25
- isSharedDrive,
26
24
  status,
27
25
  instance,
28
26
  type,
@@ -100,20 +98,11 @@ const MemberRecipientPermissions = ({
100
98
  )
101
99
 
102
100
  const actions = makeActions(
103
- [
104
- setReadOnlySharedPermission,
105
- setReadWriteSharedPermission,
106
- divider,
107
- revokeMember
108
- ],
101
+ [setReadOnlySharedPermission, setReadWriteSharedPermission],
109
102
  {
110
- client,
111
103
  t,
112
104
  type: type ?? 'one-way',
113
- isOwner,
114
- isSharedDrive,
115
- setType,
116
- handleRevocation
105
+ setType
117
106
  }
118
107
  )
119
108
 
@@ -121,9 +110,7 @@ const MemberRecipientPermissions = ({
121
110
  <div className={className}>
122
111
  {revoking && <Spinner />}
123
112
  {!shouldShowMenu && !revoking && (
124
- <Typography variant="body2">
125
- {t(`Share.status.${status}`).toLowerCase()}
126
- </Typography>
113
+ <Typography variant="body2">{t(`Share.status.${status}`)}</Typography>
127
114
  )}
128
115
  {shouldShowMenu && (
129
116
  <>
@@ -134,7 +121,7 @@ const MemberRecipientPermissions = ({
134
121
  onClick={toggleMenu}
135
122
  textVariant="body2"
136
123
  >
137
- {t(`Share.type.${type}`).toLowerCase()}
124
+ {t(`Share.type.${type}`)}
138
125
  </DropdownButton>
139
126
  <ActionsMenu
140
127
  ref={buttonRef}
@@ -143,6 +130,14 @@ const MemberRecipientPermissions = ({
143
130
  autoClose
144
131
  onClose={hideMenu}
145
132
  />
133
+ <IconButton
134
+ onClick={handleRevocation}
135
+ size="small"
136
+ className="u-ml-half"
137
+ aria-label={t('Share.members.revoke')}
138
+ >
139
+ <Icon icon={CrossCircleOutlineIcon} />
140
+ </IconButton>
146
141
  </>
147
142
  )}
148
143
  </div>
@@ -1,4 +1,4 @@
1
- import { render, fireEvent, screen, act, waitFor } from '@testing-library/react'
1
+ import { render, fireEvent, screen, waitFor } from '@testing-library/react'
2
2
  import React from 'react'
3
3
 
4
4
  import { createMockClient } from 'cozy-client'
@@ -74,16 +74,16 @@ describe('MemberRecipientPermissions component', () => {
74
74
 
75
75
  it('should render the current permission type', () => {
76
76
  setup()
77
- expect(screen.getByText('can change')).toBeInTheDocument()
77
+ expect(screen.getByRole('button', { name: 'Editor' })).toBeInTheDocument()
78
78
  })
79
79
 
80
80
  it('should call updateSharingMemberType when changing to one-way', async () => {
81
81
  mockUpdateSharingMemberType.mockResolvedValue(undefined)
82
82
 
83
- const { getByText } = setup({ type: 'two-way' })
83
+ const { getByRole } = setup({ type: 'two-way' })
84
84
 
85
- fireEvent.click(getByText('can change'))
86
- fireEvent.click(getByText('Can view'))
85
+ fireEvent.click(getByRole('button', { name: 'Editor' }))
86
+ fireEvent.click(getByRole('menuitem', { name: 'Viewer' }))
87
87
 
88
88
  expect(mockUpdateSharingMemberType).toHaveBeenCalledWith(
89
89
  'sharing-123',
@@ -95,10 +95,10 @@ describe('MemberRecipientPermissions component', () => {
95
95
  it('should call updateSharingMemberType when changing to two-way', async () => {
96
96
  mockUpdateSharingMemberType.mockResolvedValue(undefined)
97
97
 
98
- const { getByText } = setup({ type: 'one-way' })
98
+ const { getByRole } = setup({ type: 'one-way' })
99
99
 
100
- fireEvent.click(getByText('can view'))
101
- fireEvent.click(getByText('Can change'))
100
+ fireEvent.click(getByRole('button', { name: 'Viewer' }))
101
+ fireEvent.click(getByRole('menuitem', { name: 'Editor' }))
102
102
 
103
103
  expect(mockUpdateSharingMemberType).toHaveBeenCalledWith(
104
104
  'sharing-123',
@@ -110,12 +110,10 @@ describe('MemberRecipientPermissions component', () => {
110
110
  it('should show error alert when updateSharingMemberType fails', async () => {
111
111
  mockUpdateSharingMemberType.mockRejectedValue(new Error('Network error'))
112
112
 
113
- const { getByText } = setup({ type: 'two-way' })
113
+ const { getByRole } = setup({ type: 'two-way' })
114
114
 
115
- await act(async () => {
116
- fireEvent.click(getByText('can change'))
117
- fireEvent.click(getByText('Can view'))
118
- })
115
+ fireEvent.click(getByRole('button', { name: 'Editor' }))
116
+ fireEvent.click(getByRole('menuitem', { name: 'Viewer' }))
119
117
 
120
118
  await waitFor(() => {
121
119
  expect(mockShowAlert).toHaveBeenCalledWith({
@@ -130,36 +128,36 @@ describe('MemberRecipientPermissions component', () => {
130
128
  it('should not call updateSharingMemberType when selecting same type', async () => {
131
129
  mockUpdateSharingMemberType.mockResolvedValue(undefined)
132
130
 
133
- const { getByText } = setup({ type: 'two-way' })
131
+ const { getByRole } = setup({ type: 'two-way' })
134
132
 
135
- fireEvent.click(getByText('can change'))
136
- fireEvent.click(getByText('Can change'))
133
+ fireEvent.click(getByRole('button', { name: 'Editor' }))
134
+ fireEvent.click(getByRole('menuitem', { name: 'Editor' }))
137
135
 
138
136
  expect(mockUpdateSharingMemberType).not.toHaveBeenCalled()
139
137
  })
140
138
 
141
139
  it('should not render menu when user is not owner and not the shared drive contact', () => {
142
- const { queryByText } = setup({
140
+ const { queryByRole } = setup({
143
141
  isOwner: false,
144
142
  instance: 'http://other-cozy.local:8080'
145
143
  })
146
144
 
147
- expect(queryByText('can change')).not.toBeInTheDocument()
148
- expect(queryByText('can view')).not.toBeInTheDocument()
145
+ expect(queryByRole('button', { name: 'Editor' })).not.toBeInTheDocument()
146
+ expect(queryByRole('button', { name: 'Viewer' })).not.toBeInTheDocument()
149
147
  })
150
148
 
151
149
  it('should render menu for owner', () => {
152
- const { getByText } = setup({ isOwner: true })
150
+ const { getByRole } = setup({ isOwner: true })
153
151
 
154
- expect(getByText('can change')).toBeInTheDocument()
152
+ expect(getByRole('button', { name: 'Editor' })).toBeInTheDocument()
155
153
  })
156
154
 
157
155
  it('should render menu for the user themselves', () => {
158
- const { getByText } = setup({
156
+ const { getByRole } = setup({
159
157
  isOwner: false,
160
158
  instance: 'http://cozy.local:8080'
161
159
  })
162
160
 
163
- expect(getByText('can change')).toBeInTheDocument()
161
+ expect(getByRole('button', { name: 'Editor' })).toBeInTheDocument()
164
162
  })
165
163
  })
@@ -25,7 +25,8 @@ const ShareAutocomplete = ({
25
25
  recipients,
26
26
  onPick,
27
27
  onRemove,
28
- placeholder
28
+ placeholder,
29
+ endAdornment
29
30
  }) => {
30
31
  const [inputValue, setInputValue] = useState('')
31
32
  const [suggestions, setSuggestions] = useState([])
@@ -180,6 +181,9 @@ const ShareAutocomplete = ({
180
181
  {loading && isLoadingDisplayed ? (
181
182
  <Spinner color="var(--primaryColor)" />
182
183
  ) : null}
184
+ {endAdornment ? (
185
+ <div className={styles['endAdornment']}>{endAdornment}</div>
186
+ ) : null}
183
187
  </div>
184
188
  )
185
189
 
@@ -223,7 +227,8 @@ ShareAutocomplete.propTypes = {
223
227
  recipients: PropTypes.array.isRequired,
224
228
  onPick: PropTypes.func.isRequired,
225
229
  onRemove: PropTypes.func.isRequired,
226
- placeholder: PropTypes.string
230
+ placeholder: PropTypes.string,
231
+ endAdornment: PropTypes.node
227
232
  }
228
233
 
229
234
  export default ShareAutocomplete
@@ -1,167 +1,43 @@
1
1
  import PropTypes from 'prop-types'
2
- import React, { useState } from 'react'
2
+ import React from 'react'
3
3
 
4
- import { useClient } from 'cozy-client'
5
4
  import flag from 'cozy-flags'
6
- import { useAlert } from 'cozy-ui/transpiled/react/providers/Alert'
7
5
  import { useI18n } from 'twake-i18n'
8
6
 
9
7
  import ShareRecipientsInput from './ShareRecipientsInput'
10
- import { ShareRecipientsLimitModal } from './ShareRecipientsLimitModal'
11
- import ShareSubmit from './Sharesubmit'
12
8
  import ShareTypeSelect from './Sharetypeselect'
13
- import { getOrCreateFromArray } from '../helpers/contacts'
14
9
  import {
15
10
  mergeRecipients,
16
- spreadGroupAndMergeRecipients,
17
- hasReachRecipientsLimit
11
+ spreadGroupAndMergeRecipients
18
12
  } from '../helpers/recipients'
19
- import { getSuccessMessage, getErrorMessage } from '../helpers/share'
20
13
  import { isReadOnlySharing } from '../state'
21
14
  import styles from '../styles/share.styl'
22
15
 
23
16
  export const ShareByEmail = ({
24
17
  document,
25
- sharingDesc,
26
- onShare,
27
- createContact,
28
18
  documentType,
29
19
  currentRecipients,
30
- sharing,
31
- submitLabel,
32
- showNotifications = true,
33
- sharedDrive = false
20
+ pendingRecipients,
21
+ onPendingRecipientsChange,
22
+ selectedOption,
23
+ onSelectedOptionChange,
24
+ sharing
34
25
  }) => {
35
- const client = useClient()
36
26
  const { t } = useI18n()
37
- const { showAlert } = useAlert()
38
27
 
39
- const isFederatedMode = flag('drive.federated-shared-folder.enabled')
40
-
41
- const [recipients, setRecipients] = useState([])
42
- const [loading, setLoading] = useState(false)
43
- const [selectedOption, setSelectedOption] = useState('readWrite')
44
- const [showRecipientsLimit, setRecipientsLimit] = useState(false)
45
-
46
- const reset = () => {
47
- setSelectedOption('readWrite')
48
- setRecipients([])
49
- setLoading(false)
50
- }
51
-
52
- const onChange = value => {
53
- setSelectedOption(value)
54
- }
55
-
56
- const onRecipientPick = async recipient => {
57
- // In federated mode, directly share with the recipient with readWrite access
58
- if (isFederatedMode) {
59
- setLoading(true)
60
- try {
61
- const contacts = await getOrCreateFromArray(
62
- client,
63
- [recipient],
64
- createContact
65
- )
66
- await onShare({
67
- document,
68
- recipients: contacts,
69
- readOnlyRecipients: [],
70
- description: sharingDesc,
71
- openSharing: false,
72
- sharedDrive: true
73
- })
74
- } catch (_err) {
75
- if (showNotifications) {
76
- showAlert({
77
- message: t('Share.shareByEmail.error.addingRecipient'),
78
- severity: 'error',
79
- variant: 'filled'
80
- })
81
- }
82
- } finally {
83
- reset()
84
- }
85
- return
86
- }
87
-
88
- // Normal mode: just add to the list
89
- const mergedRecipients = flag('sharing.show-recipient-groups')
90
- ? mergeRecipients(recipients, recipient)
91
- : spreadGroupAndMergeRecipients(recipients, recipient)
92
- setRecipients(mergedRecipients)
28
+ const onRecipientPick = recipient => {
29
+ const merged = flag('sharing.show-recipient-groups')
30
+ ? mergeRecipients(pendingRecipients, recipient)
31
+ : spreadGroupAndMergeRecipients(pendingRecipients, recipient)
32
+ onPendingRecipientsChange(merged)
93
33
  }
94
34
 
95
35
  const onRecipientRemove = recipient => {
96
- const idx = recipients.findIndex(r => r === recipient)
97
- setRecipients([...recipients.slice(0, idx), ...recipients.slice(idx + 1)])
98
- }
99
-
100
- const share = async () => {
101
- if (recipients.length === 0) {
102
- return
103
- }
104
-
105
- // we can't use currentRecipients prop in getSuccessMessage because it may use
106
- // the updated prop to count the new recipients
107
- const recipientsBefore = currentRecipients
108
-
109
- if (hasReachRecipientsLimit(recipientsBefore, recipients)) {
110
- setRecipientsLimit(true)
111
- return
112
- }
113
-
114
- setLoading(true)
115
- try {
116
- const contacts = await getOrCreateFromArray(
117
- client,
118
- recipients,
119
- createContact
120
- )
121
- let readWriteRecipients = []
122
- let readOnlyRecipients = []
123
- if (selectedOption === 'readOnly') {
124
- readOnlyRecipients = contacts
125
- } else {
126
- readWriteRecipients = contacts
127
- }
128
- await onShare({
129
- document,
130
- recipients: readWriteRecipients,
131
- readOnlyRecipients,
132
- description: sharingDesc,
133
- openSharing: readWriteRecipients.length > 0,
134
- sharedDrive
135
- })
136
-
137
- if (showNotifications) {
138
- showAlert({
139
- message: t(
140
- ...getSuccessMessage(recipientsBefore, contacts, documentType)
141
- ),
142
- severity: 'success',
143
- variant: 'filled'
144
- })
145
- }
146
- } catch (err) {
147
- if (showNotifications) {
148
- showAlert({
149
- message: t(
150
- ...getErrorMessage({
151
- t,
152
- err,
153
- documentType,
154
- recipients,
155
- selectedOption
156
- })
157
- ),
158
- severity: 'error',
159
- variant: 'filled'
160
- })
161
- }
162
- } finally {
163
- reset()
164
- }
36
+ const idx = pendingRecipients.findIndex(r => r === recipient)
37
+ onPendingRecipientsChange([
38
+ ...pendingRecipients.slice(0, idx),
39
+ ...pendingRecipients.slice(idx + 1)
40
+ ])
165
41
  }
166
42
 
167
43
  const getSharingOptions = () => {
@@ -170,58 +46,37 @@ export const ShareByEmail = ({
170
46
  : false
171
47
  const readWrite = {
172
48
  value: 'readWrite',
173
- label: t('Share.type.two-way'),
174
- desc: t('Share.type.desc.two-way'),
175
- disabled: false
49
+ label: t('Share.type.two-way')
176
50
  }
177
51
  const readOnly = {
178
52
  value: 'readOnly',
179
- label: t('Share.type.one-way'),
180
- desc: t('Share.type.desc.one-way'),
181
- disabled: false
53
+ label: t('Share.type.one-way')
182
54
  }
183
55
  return isSharingReadOnly ? [readOnly] : [readWrite, readOnly]
184
56
  }
185
57
 
186
- const showShareControl = recipients.length > 0
187
-
188
58
  return (
189
59
  <div className={styles['coz-form-group']}>
190
60
  <div className={styles['coz-form']}>
191
61
  <ShareRecipientsInput
192
62
  placeholder={
193
- recipients.length === 0
63
+ pendingRecipients.length === 0
194
64
  ? t(`${documentType}.share.shareByEmail.emailPlaceholder`)
195
65
  : ''
196
66
  }
197
- onPick={recipient => onRecipientPick(recipient)}
198
- onRemove={recipient => onRecipientRemove(recipient)}
67
+ onPick={onRecipientPick}
68
+ onRemove={onRecipientRemove}
199
69
  currentRecipients={currentRecipients}
200
- recipients={recipients}
201
- disabled={loading}
70
+ recipients={pendingRecipients}
71
+ endAdornment={
72
+ <ShareTypeSelect
73
+ value={selectedOption}
74
+ options={getSharingOptions()}
75
+ onChange={onSelectedOptionChange}
76
+ />
77
+ }
202
78
  />
203
79
  </div>
204
- {!isFederatedMode && showShareControl && (
205
- <div className={styles['share-type-control']}>
206
- <ShareTypeSelect
207
- value={selectedOption}
208
- options={getSharingOptions()}
209
- onChange={onChange}
210
- />
211
- <ShareSubmit
212
- label={submitLabel || t(`${documentType}.share.shareByEmail.send`)}
213
- onSubmit={share}
214
- loading={loading}
215
- disabled={recipients.length === 0}
216
- />
217
- </div>
218
- )}
219
- {showRecipientsLimit ? (
220
- <ShareRecipientsLimitModal
221
- documentName={document?.name}
222
- onConfirm={() => setRecipientsLimit(false)}
223
- />
224
- ) : null}
225
80
  </div>
226
81
  )
227
82
  }
@@ -230,17 +85,11 @@ ShareByEmail.propTypes = {
230
85
  currentRecipients: PropTypes.arrayOf(PropTypes.object),
231
86
  document: PropTypes.object,
232
87
  documentType: PropTypes.string.isRequired,
233
- sharingDesc: PropTypes.string.isRequired,
234
- onShare: PropTypes.func.isRequired,
235
- createContact: PropTypes.func.isRequired,
236
- // We can display this component without having created the sharing yet
237
- sharing: PropTypes.object,
238
- // Customize the label of the button that submit contacts
239
- submitLabel: PropTypes.string,
240
- // Display success or error notifications
241
- showNotifications: PropTypes.bool,
242
- // Set to true for shared drive context
243
- sharedDrive: PropTypes.bool
88
+ pendingRecipients: PropTypes.array.isRequired,
89
+ onPendingRecipientsChange: PropTypes.func.isRequired,
90
+ selectedOption: PropTypes.oneOf(['readWrite', 'readOnly']).isRequired,
91
+ onSelectedOptionChange: PropTypes.func.isRequired,
92
+ sharing: PropTypes.object
244
93
  }
245
94
 
246
95
  export default ShareByEmail