cozy-sharing 5.0.0 → 6.0.1

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/CHANGELOG.md +80 -0
  2. package/dist/SharedRecipients.js +1 -1
  3. package/dist/SharedStatus.js +1 -1
  4. package/dist/SharingBanner/hooks/useSharingInfos.js +1 -1
  5. package/dist/SharingDetailsModal.js +1 -1
  6. package/dist/SharingOwnerAvatar.js +1 -1
  7. package/dist/SharingProvider.js +21 -8
  8. package/dist/components/ConfirmTrustedRecipientsDialog.js +1 -1
  9. package/dist/components/ContactSuggestion.js +15 -27
  10. package/dist/components/EditLinkPermissionDialog.js +72 -0
  11. package/dist/components/EditLinkPermissionDialog.spec.js +48 -0
  12. package/dist/components/EditableSharingModal.js +15 -62
  13. package/dist/components/{AvatarPlusX.js → Recipient/AvatarPlusX.js} +1 -1
  14. package/dist/components/{Identity.js → Recipient/Identity.js} +17 -16
  15. package/dist/components/Recipient/LinkRecipient.js +72 -0
  16. package/dist/components/Recipient/LinkRecipientPermissions.js +159 -0
  17. package/dist/components/Recipient/OwnerIdentity.js +44 -0
  18. package/dist/components/Recipient/Recipient.js +72 -0
  19. package/dist/components/{Recipient.spec.js → Recipient/Recipient.spec.js} +4 -45
  20. package/dist/components/Recipient/RecipientAvatar.js +33 -0
  21. package/dist/components/Recipient/RecipientConfirm.js +63 -0
  22. package/dist/components/Recipient/RecipientPermissions.js +126 -0
  23. package/dist/components/Recipient/RecipientPlusX.js +45 -0
  24. package/dist/components/Recipient/RecipientStatus.js +64 -0
  25. package/dist/components/Recipient/RecipientWithoutStatus.js +45 -0
  26. package/dist/components/Recipient/RecipientsAvatars.js +100 -0
  27. package/dist/components/{RecipientsAvatars.spec.js → Recipient/RecipientsAvatars.spec.js} +43 -2
  28. package/dist/components/{recipient.styl → Recipient/recipient.styl} +6 -2
  29. package/dist/components/ShareAutosuggest.js +176 -252
  30. package/dist/components/ShareAutosuggest.spec.js +3 -2
  31. package/dist/components/ShareByEmail.js +142 -193
  32. package/dist/components/ShareByEmail.spec.js +42 -23
  33. package/dist/components/ShareByLink.js +251 -357
  34. package/dist/components/ShareDialogCozyToCozy.js +16 -4
  35. package/dist/components/ShareDialogCozyToCozy.spec.js +12 -1
  36. package/dist/components/ShareDialogOnlyByLink.js +23 -10
  37. package/dist/components/ShareDialogTwoStepsConfirmationContainer.js +7 -7
  38. package/dist/components/ShareModal.js +5 -1
  39. package/dist/components/ShareRecipientsInput.js +44 -128
  40. package/dist/components/WhoHasAccess.js +43 -5
  41. package/dist/components/WhoHasAccessLight.js +3 -19
  42. package/dist/components/autosuggest.styl +21 -36
  43. package/dist/helpers/documentType.js +6 -0
  44. package/dist/helpers/hooks.js +8 -1
  45. package/dist/helpers/link.js +5 -0
  46. package/dist/helpers/permissions.js +8 -0
  47. package/dist/helpers/recipients.js +24 -0
  48. package/dist/helpers/sharings.js +72 -53
  49. package/dist/helpers/synchronousJobQueue.js +67 -0
  50. package/dist/helpers/synchronousJobQueue.spec.js +97 -0
  51. package/dist/index.js +2 -1
  52. package/dist/queries/queries.js +72 -0
  53. package/dist/share.styl +0 -15
  54. package/dist/stylesheet.css +67 -92
  55. package/locales/en.json +29 -41
  56. package/locales/fr.json +26 -39
  57. package/package.json +10 -10
  58. package/src/SharedRecipients.jsx +1 -1
  59. package/src/SharedStatus.jsx +1 -1
  60. package/src/SharingBanner/hooks/useSharingInfos.jsx +1 -1
  61. package/src/SharingDetailsModal.jsx +1 -1
  62. package/src/SharingOwnerAvatar.jsx +1 -1
  63. package/src/SharingProvider.jsx +17 -4
  64. package/src/components/ConfirmTrustedRecipientsDialog.jsx +1 -1
  65. package/src/components/ContactSuggestion.jsx +25 -10
  66. package/src/components/EditLinkPermissionDialog.jsx +89 -0
  67. package/src/components/EditLinkPermissionDialog.spec.jsx +52 -0
  68. package/src/components/EditableSharingModal.jsx +58 -100
  69. package/src/components/{AvatarPlusX.jsx → Recipient/AvatarPlusX.jsx} +1 -1
  70. package/src/components/{Identity.jsx → Recipient/Identity.jsx} +0 -0
  71. package/src/components/Recipient/LinkRecipient.jsx +59 -0
  72. package/src/components/Recipient/LinkRecipientPermissions.jsx +157 -0
  73. package/src/components/Recipient/OwnerIdentity.jsx +20 -0
  74. package/src/components/Recipient/Recipient.jsx +79 -0
  75. package/src/components/{Recipient.spec.jsx → Recipient/Recipient.spec.jsx} +4 -42
  76. package/src/components/Recipient/RecipientAvatar.jsx +38 -0
  77. package/src/components/Recipient/RecipientConfirm.jsx +37 -0
  78. package/src/components/Recipient/RecipientPermissions.jsx +114 -0
  79. package/src/components/Recipient/RecipientPlusX.jsx +28 -0
  80. package/src/components/Recipient/RecipientStatus.jsx +48 -0
  81. package/src/components/Recipient/RecipientWithoutStatus.jsx +21 -0
  82. package/src/components/Recipient/RecipientsAvatars.jsx +108 -0
  83. package/src/components/{RecipientsAvatars.spec.jsx → Recipient/RecipientsAvatars.spec.jsx} +43 -2
  84. package/src/components/{recipient.styl → Recipient/recipient.styl} +6 -2
  85. package/src/components/ShareAutosuggest.jsx +136 -127
  86. package/src/components/ShareAutosuggest.spec.jsx +12 -8
  87. package/src/components/ShareByEmail.jsx +65 -90
  88. package/src/components/ShareByEmail.spec.jsx +39 -11
  89. package/src/components/ShareByLink.jsx +146 -238
  90. package/src/components/ShareDialogCozyToCozy.jsx +14 -2
  91. package/src/components/ShareDialogCozyToCozy.spec.jsx +8 -1
  92. package/src/components/ShareDialogOnlyByLink.jsx +30 -13
  93. package/src/components/ShareDialogTwoStepsConfirmationContainer.jsx +5 -5
  94. package/src/components/ShareModal.jsx +5 -1
  95. package/src/components/ShareRecipientsInput.jsx +30 -44
  96. package/src/components/WhoHasAccess.jsx +85 -27
  97. package/src/components/WhoHasAccessLight.jsx +2 -1
  98. package/src/components/__snapshots__/ContactSuggestion.spec.jsx.snap +915 -132
  99. package/src/components/__snapshots__/ShareRecipientsInput.spec.jsx.snap +86 -102
  100. package/src/components/autosuggest.styl +21 -36
  101. package/src/helpers/documentType.js +6 -0
  102. package/src/helpers/hooks.js +11 -1
  103. package/src/helpers/link.js +4 -0
  104. package/src/helpers/permissions.js +15 -0
  105. package/src/helpers/recipients.js +21 -0
  106. package/src/helpers/sharings.js +15 -12
  107. package/src/helpers/synchronousJobQueue.js +22 -0
  108. package/src/helpers/synchronousJobQueue.spec.js +75 -0
  109. package/src/index.jsx +1 -0
  110. package/src/queries/queries.js +75 -0
  111. package/src/share.styl +0 -15
  112. package/dist/SharingBanner/helpers/queries.js +0 -12
  113. package/dist/components/ContactsAndGroupsDataLoader.js +0 -50
  114. package/dist/components/Recipient.js +0 -450
  115. package/src/SharingBanner/helpers/queries.js +0 -14
  116. package/src/components/ContactsAndGroupsDataLoader.jsx +0 -30
  117. package/src/components/Recipient.jsx +0 -415
@@ -1,10 +1,10 @@
1
- import React, { Component } from 'react'
1
+ import React, { useState } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import get from 'lodash/get'
4
4
 
5
- import { withClient } from 'cozy-client'
5
+ import { useClient } from 'cozy-client'
6
+ import { useI18n } from 'cozy-ui/transpiled/react/I18n'
6
7
  import Alerter from 'cozy-ui/transpiled/react/Alerter'
7
- import { translate } from 'cozy-ui/transpiled/react/I18n'
8
8
 
9
9
  import ShareSubmit from './Sharesubmit'
10
10
  import ShareTypeSelect from './Sharetypeselect'
@@ -16,38 +16,38 @@ import styles from '../share.styl'
16
16
  import { getSuccessMessage } from '../helpers/successMessage'
17
17
  import { getOrCreateFromArray } from '../helpers/contacts'
18
18
  import { isReadOnlySharing } from '../state'
19
- export class ShareByEmail extends Component {
20
- constructor(props) {
21
- super(props)
22
- this.initialState = {
23
- recipients: [],
24
- loading: false
25
- }
26
- this.state = { ...this.initialState }
27
- }
28
-
29
- state = { ...this.initialState }
30
19
 
31
- reset = () => {
32
- this.setState({ ...this.initialState })
20
+ export const ShareByEmail = ({
21
+ contacts,
22
+ groups,
23
+ document,
24
+ sharingDesc,
25
+ onShare,
26
+ createContact,
27
+ documentType,
28
+ currentRecipients,
29
+ sharing
30
+ }) => {
31
+ const client = useClient()
32
+ const { t } = useI18n()
33
+ const [recipients, setRecipients] = useState([])
34
+ const [loading, setLoading] = useState(false)
35
+ const [selectedOption, setSelectedOption] = useState()
36
+
37
+ const reset = () => {
38
+ setRecipients([])
39
+ setLoading(false)
33
40
  }
34
41
 
35
- onChange = value => {
36
- this.setState(state => ({
37
- ...state,
38
- selectedOption: value
39
- }))
42
+ const onChange = value => {
43
+ setSelectedOption(value)
40
44
  }
41
45
 
42
- onSubmit = () => {
43
- this.sendSharingLink()
44
- }
45
-
46
- onRecipientPick = recipient => {
46
+ const onRecipientPick = recipient => {
47
47
  let contactsToAdd
48
48
  if (recipient._type === Group.doctype) {
49
49
  const groupId = recipient.id
50
- contactsToAdd = this.props.contacts.data.filter(contact => {
50
+ contactsToAdd = contacts.data.filter(contact => {
51
51
  const contactGroupIds = get(
52
52
  contact,
53
53
  'relationships.groups.data',
@@ -66,45 +66,26 @@ export class ShareByEmail extends Component {
66
66
  (contact.email && contact.email.length > 0) ||
67
67
  (contact.cozy && contact.cozy.length > 0)
68
68
  )
69
- .filter(contact => !this.state.recipients.find(r => r === contact))
69
+ .filter(contact => !recipients.find(r => r === contact))
70
70
 
71
- this.setState(state => ({
72
- ...state,
73
- recipients: [...state.recipients, ...filtered]
74
- }))
71
+ setRecipients([...recipients, ...filtered])
75
72
  }
76
73
 
77
- onRecipientRemove = recipient => {
78
- const idx = this.state.recipients.findIndex(r => r === recipient)
79
- this.setState(state => ({
80
- ...state,
81
- recipients: [
82
- ...state.recipients.slice(0, idx),
83
- ...state.recipients.slice(idx + 1)
84
- ]
85
- }))
74
+ const onRecipientRemove = recipient => {
75
+ const idx = recipients.findIndex(r => r === recipient)
76
+ setRecipients([...recipients.slice(0, idx), ...recipients.slice(idx + 1)])
86
77
  }
87
78
 
88
- share = async () => {
89
- const {
90
- document,
91
- sharingDesc,
92
- onShare,
93
- createContact,
94
- documentType,
95
- client,
96
- t
97
- } = this.props
98
- const { recipients, selectedOption } = this.state
79
+ const share = async () => {
99
80
  if (recipients.length === 0) {
100
81
  return
101
82
  }
102
83
 
103
84
  // we can't use currentRecipients prop in getSuccessMessage because it may use
104
85
  // the updated prop to count the new recipients
105
- const recipientsBefore = this.props.currentRecipients
86
+ const recipientsBefore = currentRecipients
106
87
 
107
- this.setState(state => ({ ...state, loading: true }))
88
+ setLoading(true)
108
89
  try {
109
90
  const contacts = await getOrCreateFromArray(
110
91
  client,
@@ -129,16 +110,15 @@ export class ShareByEmail extends Component {
129
110
  Alerter.success(
130
111
  t(...getSuccessMessage(recipientsBefore, contacts, documentType))
131
112
  )
132
- this.reset()
113
+ reset()
133
114
  } catch (err) {
134
115
  Alerter.error('Error.generic')
135
- this.reset()
116
+ reset()
136
117
  throw err
137
118
  }
138
119
  }
139
120
 
140
- getSharingOptions = () => {
141
- const { t, sharing, document } = this.props
121
+ const getSharingOptions = () => {
142
122
  const isSharingReadOnly = sharing
143
123
  ? isReadOnlySharing(sharing, document._id)
144
124
  : false
@@ -156,43 +136,38 @@ export class ShareByEmail extends Component {
156
136
  }
157
137
  return isSharingReadOnly ? [readOnly] : [readWrite, readOnly]
158
138
  }
159
- render() {
160
- const { contacts, documentType, groups, t } = this.props
161
- const { recipients } = this.state
162
-
163
- return (
164
- <div className={styles['coz-form-group']}>
165
- <div className={styles['coz-form']}>
166
- <ShareRecipientsInput
167
- label={t(`${documentType}.share.shareByEmail.email`)}
168
- placeholder={
169
- recipients.length === 0
170
- ? t(`${documentType}.share.shareByEmail.emailPlaceholder`)
171
- : ''
172
- }
173
- onFocus={this.onInputFocus}
174
- onPick={recipient => this.onRecipientPick(recipient)}
175
- onRemove={recipient => this.onRecipientRemove(recipient)}
176
- contacts={contacts}
177
- groups={groups}
178
- recipients={recipients}
179
- />
180
- </div>
139
+
140
+ const showShareControl = recipients.length > 0
141
+
142
+ return (
143
+ <div className={styles['coz-form-group']}>
144
+ <div className={styles['coz-form']}>
145
+ <ShareRecipientsInput
146
+ placeholder={
147
+ recipients.length === 0
148
+ ? t(`${documentType}.share.shareByEmail.emailPlaceholder`)
149
+ : ''
150
+ }
151
+ onPick={recipient => onRecipientPick(recipient)}
152
+ onRemove={recipient => onRecipientRemove(recipient)}
153
+ contacts={contacts}
154
+ groups={groups}
155
+ recipients={recipients}
156
+ />
157
+ </div>
158
+ {showShareControl && (
181
159
  <div className={styles['share-type-control']}>
182
- <ShareTypeSelect
183
- options={this.getSharingOptions()}
184
- onChange={this.onChange}
185
- />
160
+ <ShareTypeSelect options={getSharingOptions()} onChange={onChange} />
186
161
  <ShareSubmit
187
162
  label={t(`${documentType}.share.shareByEmail.send`)}
188
- onSubmit={this.share}
189
- loading={this.state.loading}
163
+ onSubmit={share}
164
+ loading={loading}
190
165
  disabled={recipients.length === 0}
191
166
  />
192
167
  </div>
193
- </div>
194
- )
195
- }
168
+ )}
169
+ </div>
170
+ )
196
171
  }
197
172
 
198
173
  ShareByEmail.propTypes = {
@@ -208,4 +183,4 @@ ShareByEmail.propTypes = {
208
183
  sharing: PropTypes.object
209
184
  }
210
185
 
211
- export default translate()(withClient(ShareByEmail))
186
+ export default ShareByEmail
@@ -1,6 +1,12 @@
1
1
  import React from 'react'
2
- import { mount } from 'enzyme'
2
+ import { render, fireEvent, waitFor } from '@testing-library/react'
3
3
  import { ShareByEmail } from './ShareByEmail'
4
+ import AppLike from '../../test/AppLike'
5
+ import { act } from 'react-dom/test-utils'
6
+
7
+ jest.mock('../helpers/contacts', () => ({
8
+ getOrCreateFromArray: (client, recipients) => recipients
9
+ }))
4
10
 
5
11
  describe('ShareByEmailComponent', () => {
6
12
  it('shoud call share if submited', async () => {
@@ -9,7 +15,6 @@ describe('ShareByEmailComponent', () => {
9
15
  contacts: {
10
16
  data: []
11
17
  },
12
- t: x => x,
13
18
  groups: { data: [] },
14
19
  documentType: 'Files',
15
20
  onShare: onShare,
@@ -19,15 +24,38 @@ describe('ShareByEmailComponent', () => {
19
24
  sharingDesc: 'test',
20
25
  createContact: jest.fn()
21
26
  }
22
- const comp = mount(<ShareByEmail {...props} />)
23
- comp.instance().onRecipientPick({ id: 1, email: 'quentin@cozycloud.cc' })
24
- await comp.instance().share()
25
- expect(onShare).toHaveBeenCalledWith({
26
- description: props.sharingDesc,
27
- document: props.document,
28
- openSharing: true,
29
- readOnlyRecipients: [],
30
- recipients: [{ id: 1, email: 'quentin@cozycloud.cc' }]
27
+ const root = render(
28
+ <AppLike>
29
+ <ShareByEmail {...props} />
30
+ </AppLike>
31
+ )
32
+
33
+ act(() => {
34
+ fireEvent.change(root.getByPlaceholderText('Add contacts or groups'), {
35
+ target: { value: 'quentin@cozycloud.cc' }
36
+ })
37
+ })
38
+
39
+ act(() => {
40
+ fireEvent.keyPress(root.getByPlaceholderText('Add contacts or groups'), {
41
+ key: 'Enter',
42
+ code: 'Enter',
43
+ charCode: 13
44
+ })
45
+ })
46
+
47
+ act(() => {
48
+ fireEvent.click(root.getByRole('button', { name: 'Send' }))
49
+ })
50
+
51
+ await waitFor(() => {
52
+ expect(onShare).toHaveBeenCalledWith({
53
+ description: props.sharingDesc,
54
+ document: props.document,
55
+ openSharing: true,
56
+ readOnlyRecipients: [],
57
+ recipients: [{ email: 'quentin@cozycloud.cc' }]
58
+ })
31
59
  })
32
60
  })
33
61
  })