cozy-sharing 4.9.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/CHANGELOG.md +90 -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/ContactSuggestion.js +15 -27
  9. package/dist/components/EditLinkPermissionDialog.js +72 -0
  10. package/dist/components/EditLinkPermissionDialog.spec.js +48 -0
  11. package/dist/components/EditableSharingModal.js +15 -62
  12. package/dist/components/{AvatarPlusX.js → Recipient/AvatarPlusX.js} +1 -1
  13. package/dist/components/{Identity.js → Recipient/Identity.js} +17 -16
  14. package/dist/components/Recipient/LinkRecipient.js +72 -0
  15. package/dist/components/Recipient/LinkRecipientPermissions.js +159 -0
  16. package/dist/components/Recipient/OwnerIdentity.js +44 -0
  17. package/dist/components/Recipient/Recipient.js +72 -0
  18. package/dist/components/{Recipient.spec.js → Recipient/Recipient.spec.js} +4 -45
  19. package/dist/components/Recipient/RecipientAvatar.js +33 -0
  20. package/dist/components/Recipient/RecipientConfirm.js +63 -0
  21. package/dist/components/Recipient/RecipientPermissions.js +126 -0
  22. package/dist/components/Recipient/RecipientPlusX.js +45 -0
  23. package/dist/components/Recipient/RecipientStatus.js +64 -0
  24. package/dist/components/Recipient/RecipientWithoutStatus.js +45 -0
  25. package/dist/components/Recipient/RecipientsAvatars.js +100 -0
  26. package/dist/components/{RecipientsAvatars.spec.js → Recipient/RecipientsAvatars.spec.js} +43 -2
  27. package/dist/components/{recipient.styl → Recipient/recipient.styl} +6 -2
  28. package/dist/components/ShareAutosuggest.js +176 -252
  29. package/dist/components/ShareAutosuggest.spec.js +3 -2
  30. package/dist/components/ShareByEmail.js +142 -193
  31. package/dist/components/ShareByEmail.spec.js +42 -23
  32. package/dist/components/ShareByLink.js +251 -357
  33. package/dist/components/ShareDialogCozyToCozy.js +16 -4
  34. package/dist/components/ShareDialogCozyToCozy.spec.js +12 -1
  35. package/dist/components/ShareDialogOnlyByLink.js +23 -10
  36. package/dist/components/ShareDialogTwoStepsConfirmationContainer.js +7 -7
  37. package/dist/components/ShareModal.js +5 -1
  38. package/dist/components/ShareRecipientsInput.js +44 -128
  39. package/dist/components/WhoHasAccess.js +43 -5
  40. package/dist/components/WhoHasAccessLight.js +3 -19
  41. package/dist/components/autosuggest.styl +21 -36
  42. package/dist/components/badge.styl +1 -1
  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 +68 -93
  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/ContactSuggestion.jsx +25 -10
  65. package/src/components/EditLinkPermissionDialog.jsx +89 -0
  66. package/src/components/EditLinkPermissionDialog.spec.jsx +52 -0
  67. package/src/components/EditableSharingModal.jsx +58 -100
  68. package/src/components/{AvatarPlusX.jsx → Recipient/AvatarPlusX.jsx} +1 -1
  69. package/src/components/{Identity.jsx → Recipient/Identity.jsx} +0 -0
  70. package/src/components/Recipient/LinkRecipient.jsx +59 -0
  71. package/src/components/Recipient/LinkRecipientPermissions.jsx +157 -0
  72. package/src/components/Recipient/OwnerIdentity.jsx +20 -0
  73. package/src/components/Recipient/Recipient.jsx +79 -0
  74. package/src/components/{Recipient.spec.jsx → Recipient/Recipient.spec.jsx} +4 -42
  75. package/src/components/Recipient/RecipientAvatar.jsx +38 -0
  76. package/src/components/Recipient/RecipientConfirm.jsx +37 -0
  77. package/src/components/Recipient/RecipientPermissions.jsx +114 -0
  78. package/src/components/Recipient/RecipientPlusX.jsx +28 -0
  79. package/src/components/Recipient/RecipientStatus.jsx +48 -0
  80. package/src/components/Recipient/RecipientWithoutStatus.jsx +21 -0
  81. package/src/components/Recipient/RecipientsAvatars.jsx +108 -0
  82. package/src/components/{RecipientsAvatars.spec.jsx → Recipient/RecipientsAvatars.spec.jsx} +43 -2
  83. package/src/components/{recipient.styl → Recipient/recipient.styl} +6 -2
  84. package/src/components/ShareAutosuggest.jsx +136 -127
  85. package/src/components/ShareAutosuggest.spec.jsx +12 -8
  86. package/src/components/ShareByEmail.jsx +65 -90
  87. package/src/components/ShareByEmail.spec.jsx +39 -11
  88. package/src/components/ShareByLink.jsx +146 -238
  89. package/src/components/ShareDialogCozyToCozy.jsx +14 -2
  90. package/src/components/ShareDialogCozyToCozy.spec.jsx +8 -1
  91. package/src/components/ShareDialogOnlyByLink.jsx +30 -13
  92. package/src/components/ShareDialogTwoStepsConfirmationContainer.jsx +5 -5
  93. package/src/components/ShareModal.jsx +5 -1
  94. package/src/components/ShareRecipientsInput.jsx +30 -44
  95. package/src/components/WhoHasAccess.jsx +85 -27
  96. package/src/components/WhoHasAccessLight.jsx +2 -1
  97. package/src/components/__snapshots__/ContactSuggestion.spec.jsx.snap +915 -132
  98. package/src/components/__snapshots__/ShareRecipientsInput.spec.jsx.snap +86 -102
  99. package/src/components/autosuggest.styl +21 -36
  100. package/src/components/badge.styl +1 -1
  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,270 +1,178 @@
1
- import React from 'react'
1
+ import React, { useState, useEffect, useCallback } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import copy from 'copy-text-to-clipboard'
4
- import { models } from 'cozy-client'
5
- import Alerter from 'cozy-ui/transpiled/react/Alerter'
6
- import Button from 'cozy-ui/transpiled/react/Button'
7
- import CompositeRow from 'cozy-ui/transpiled/react/CompositeRow'
8
- import Circle from 'cozy-ui/transpiled/react/Circle'
4
+ import useBreakpoints from 'cozy-ui/transpiled/react/hooks/useBreakpoints'
5
+ import Button from 'cozy-ui/transpiled/react/Buttons'
9
6
  import Icon from 'cozy-ui/transpiled/react/Icon'
10
- import Radio from 'cozy-ui/transpiled/react/Radio'
11
- import DropdownButton from 'cozy-ui/transpiled/react/DropdownButton'
12
- import ActionMenu, { ActionMenuItem } from 'cozy-ui/transpiled/react/ActionMenu'
13
- import { translate } from 'cozy-ui/transpiled/react/I18n'
14
- import get from 'lodash/get'
15
- import logger from '../logger'
16
- import styles from '../share.styl'
17
-
18
7
  import LinkIcon from 'cozy-ui/transpiled/react/Icons/Link'
19
- import TrashIcon from 'cozy-ui/transpiled/react/Icons/Trash'
20
-
21
- import Typography from 'cozy-ui/transpiled/react/Typography'
8
+ import CopyIcon from 'cozy-ui/transpiled/react/Icons/Copy'
9
+ import Snackbar from 'cozy-ui/transpiled/react/Snackbar'
10
+ import Alert from 'cozy-ui/transpiled/react/Alert'
11
+ import { useI18n } from 'cozy-ui/transpiled/react/I18n'
22
12
 
23
- const permissionModel = models.permission
13
+ import { isOnlyReadOnlyLinkAllowed } from '../helpers/link'
14
+ import EditLinkPermissionDialog from './EditLinkPermissionDialog'
15
+ import logger from '../logger'
24
16
 
25
- const checkIsReadOnlyPermissions = permissions => {
26
- const permissionCategories = get(
27
- permissions,
28
- '[0].attributes.permissions',
29
- {}
17
+ const ShareByLink = ({ link, document, documentType, onEnable }) => {
18
+ const { t } = useI18n()
19
+ const { isMobile } = useBreakpoints()
20
+ const [loading, setLoading] = useState(false)
21
+ const [shouldCopyToClipboard, setShouldCopyToClipboard] = useState(false)
22
+ const [alert, setAlert] = useState(false)
23
+
24
+ const [isEditDialogOpen, setIsEditDialogOpen] = useState(false)
25
+
26
+ const copyLinkToClipboard = useCallback(
27
+ ({ isAutomaticCopy }) => {
28
+ if (copy(link)) {
29
+ setAlert({
30
+ open: true,
31
+ severity: 'success',
32
+ message: t(`${documentType}.share.shareByLink.copied`)
33
+ })
34
+ } else if (!isAutomaticCopy) {
35
+ // In case of automatic copy, the browser can block the copy request. This is not shown to the user since it is expected and can be circumvented by clicking directly on the copy link
36
+ setAlert({
37
+ open: true,
38
+ severity: 'error',
39
+ message: t(`${documentType}.share.shareByLink.failed`)
40
+ })
41
+ }
42
+ },
43
+ [documentType, link, t]
30
44
  )
31
- return (
32
- Object.values(permissionCategories).filter(permissionCategory =>
33
- permissionModel.isReadOnly(permissionCategory)
34
- ).length > 0
35
- )
36
- }
37
-
38
- class ShareByLink extends React.Component {
39
- constructor(props) {
40
- super(props)
41
- this.state = {
42
- loading: false,
43
- menuIsOpen: false
44
- }
45
-
46
- this.containerRef = React.createRef()
47
- }
48
-
49
- toggleShareLink = checked => {
50
- if (checked) {
51
- this.createShareLink()
52
- } else {
53
- this.deleteShareLink()
54
- }
55
- }
56
-
57
- copyLinkToClipboard = ({ isAutomaticCopy }) => {
58
- if (copy(this.props.link))
59
- Alerter.success(
60
- this.props.t(`${this.props.documentType}.share.shareByLink.copied`)
61
- )
62
- else if (!isAutomaticCopy)
63
- // In case of automatic copy, the browser can block the copy request. This is not shown to the user since it is expected and can be circumvented by clicking directly on the copy link
64
- Alerter.error(
65
- this.props.t(`${this.props.documentType}.share.shareByLink.failed`)
66
- )
67
- }
68
45
 
69
- async createShareLink() {
46
+ const onPermissionsSelected = async options => {
70
47
  try {
71
- this.setState(state => ({ ...state, loading: true }))
72
- await this.props.onEnable(this.props.document)
48
+ setLoading(true)
49
+ await onEnable(document, options)
73
50
  } catch (e) {
74
- Alerter.error(
75
- this.props.t(`${this.props.documentType}.share.error.generic`)
76
- )
51
+ setAlert({
52
+ open: true,
53
+ severity: 'error',
54
+ message: t(`${documentType}.share.error.generic`)
55
+ })
77
56
  logger.log(e)
78
57
  } finally {
79
- this.setState(state => ({ ...state, loading: false }))
58
+ setLoading(false)
59
+ setShouldCopyToClipboard(true)
80
60
  }
81
61
  }
82
62
 
83
- async deleteShareLink() {
84
- try {
85
- this.setState(state => ({ ...state, loading: true }))
86
- await this.props.onDisable(this.props.document)
87
- } catch (e) {
88
- Alerter.error(
89
- this.props.t(`${this.props.documentType}.share.error.revoke`)
90
- )
91
- logger.log(e)
92
- } finally {
93
- this.setState(state => ({ ...state, loading: false }))
63
+ const onCreate = async () => {
64
+ if (isOnlyReadOnlyLinkAllowed({ documentType })) {
65
+ onPermissionsSelected({ verbs: ['GET'] })
66
+ } else {
67
+ setIsEditDialogOpen(true)
94
68
  }
95
69
  }
96
70
 
97
- updateLinkPermissions({ isReadOnly }) {
98
- const { document, documentType, onChangePermissions, t } = this.props
99
- const verbs = isReadOnly ? ['GET'] : ['GET', 'POST', 'PUT', 'PATCH']
100
- try {
101
- onChangePermissions(document, verbs)
102
- } catch (err) {
103
- Alerter.error(t(`${documentType}.share.shareByLink.permserror`))
104
- logger.log(err)
71
+ useEffect(() => {
72
+ if (link && shouldCopyToClipboard) {
73
+ copyLinkToClipboard({ isAutomaticCopy: true })
74
+ setShouldCopyToClipboard(false)
105
75
  }
76
+ }, [link, shouldCopyToClipboard, copyLinkToClipboard])
77
+
78
+ const onClose = () => {
79
+ setIsEditDialogOpen(false)
106
80
  }
107
81
 
108
- toggleMenu = () => {
109
- this.setState(state => ({ ...state, menuIsOpen: !state.menuIsOpen }))
82
+ const onCloseAlert = () => {
83
+ setAlert({ ...alert, open: false })
110
84
  }
111
85
 
112
- render() {
113
- const { loading, menuIsOpen } = this.state
114
- const { checked, documentType, permissions, t, popperOptions } = this.props
86
+ const showCopyAndSendButtons = link && isMobile && navigator.share
87
+ const showOnlyCopyButton =
88
+ (link && !isMobile) || (link && isMobile && !navigator.share)
115
89
 
116
- const hasReadOnlyPermissions = checkIsReadOnlyPermissions(permissions)
90
+ const shareLink = async () => {
91
+ try {
92
+ const shareData = {
93
+ text: t(`${documentType}.share.shareByLink.shareDescription`, {
94
+ name: document.name || ''
95
+ }),
96
+ url: link
97
+ }
98
+ await navigator.share(shareData)
99
+ } catch (error) {
100
+ setAlert({
101
+ open: true,
102
+ severity: 'error',
103
+ message: t(`${documentType}.share.error.generic`)
104
+ })
105
+ }
106
+ }
117
107
 
118
- return (
119
- <div className="u-w-100">
120
- <div className="u-flex u-flex-row u-flex-justify-between u-flex-items-center">
121
- <Typography variant="body1">
122
- {t(`${documentType}.share.shareByLink.subtitle`)}
123
- </Typography>
124
- {!checked && (
125
- <Button
126
- style={{ position: 'initial' }} // fix z-index bug on iOS when under a BottomDrawer due to relative position
127
- theme="text"
128
- className={styles['aligned-dropdown-button']}
129
- onClick={async () => {
130
- await this.createShareLink()
131
- this.copyLinkToClipboard({ isAutomaticCopy: true })
132
- }}
133
- busy={loading}
134
- label={t(`${documentType}.share.shareByLink.create`)}
135
- />
136
- )}
137
- </div>
138
- {checked && (
139
- <CompositeRow
140
- className="u-ph-0"
141
- primaryText={
142
- <Typography
143
- onClick={this.copyLinkToClipboard}
144
- className="u-c-pointer"
145
- variant="body1"
146
- >
147
- {t(`${documentType}.share.shareByLink.activated`)}
148
- </Typography>
149
- }
150
- secondaryText={
151
- <Typography
152
- className="u-primaryColor u-fz-tiny u-c-pointer"
153
- onClick={this.copyLinkToClipboard}
154
- variant="body1"
155
- >
156
- {t(`${documentType}.share.shareByLink.copy`)}
157
- </Typography>
158
- }
159
- image={
160
- <Circle backgroundColor="var(--silver)">
161
- <Icon icon={LinkIcon} color="var(--charcoalGrey)" />
162
- </Circle>
163
- }
164
- right={
165
- <div ref={this.containerRef}>
166
- <DropdownButton onClick={this.toggleMenu}>
167
- <Typography variant="body1">
168
- {t(
169
- `${documentType}.share.shareByLink.${
170
- hasReadOnlyPermissions ? 'ro' : 'rw'
171
- }`
172
- )}
173
- </Typography>
174
- </DropdownButton>
175
- {menuIsOpen && (
176
- <ActionMenu
177
- onClose={this.toggleMenu}
178
- popperOptions={{
179
- ...popperOptions,
180
- placement: 'bottom-end'
181
- }}
182
- containerElRef={this.containerRef}
183
- anchorElRef={this.containerRef}
184
- >
185
- <ActionMenuItem
186
- left={
187
- <Radio
188
- name="permissions"
189
- value="ro"
190
- className="u-w-1 u-h-1"
191
- checked={hasReadOnlyPermissions}
192
- readOnly
193
- />
194
- }
195
- onClick={() => {
196
- this.toggleMenu()
197
- this.updateLinkPermissions({ isReadOnly: true })
198
- }}
199
- >
200
- <>
201
- {t(`${documentType}.share.shareByLink.ro`)}
202
- <Typography
203
- className="u-mt-half"
204
- variant="caption"
205
- color="textSecondary"
206
- >
207
- {t(`${documentType}.share.shareByLink.desc.ro`)}
208
- </Typography>
209
- </>
210
- </ActionMenuItem>
211
- <ActionMenuItem
212
- left={
213
- <Radio
214
- name="permissions"
215
- value="rw"
216
- className="u-w-1 u-h-1"
217
- checked={!hasReadOnlyPermissions}
218
- readOnly
219
- />
220
- }
221
- onClick={() => {
222
- this.toggleMenu()
223
- this.updateLinkPermissions({ isReadOnly: false })
224
- }}
225
- >
226
- <>
227
- {t(`${documentType}.share.shareByLink.rw`)}
228
- <Typography
229
- className="u-mt-half"
230
- variant="caption"
231
- color="textSecondary"
232
- >
233
- {t(`${documentType}.share.shareByLink.desc.rw`)}
234
- </Typography>
235
- </>
236
- </ActionMenuItem>
237
- <hr />
238
- <ActionMenuItem
239
- left={<Icon icon={TrashIcon} color="var(--errorColor)" />}
240
- onClick={() => {
241
- this.toggleMenu()
242
- this.deleteShareLink()
243
- }}
244
- >
245
- <Typography className="u-error" variant="body1">
246
- {t(`${documentType}.share.shareByLink.deactivate`)}
247
- </Typography>
248
- </ActionMenuItem>
249
- </ActionMenu>
250
- )}
251
- </div>
252
- }
108
+ return (
109
+ <div className="u-w-100 u-flex u-flex-justify-center">
110
+ {!link && (
111
+ <Button
112
+ label={t(`${documentType}.share.shareByLink.create`)}
113
+ variant="secondary"
114
+ size="medium"
115
+ startIcon={<Icon icon={LinkIcon} />}
116
+ className="u-flex-auto"
117
+ busy={loading}
118
+ style={{ position: 'initial' }} // fix z-index bug on iOS when under a BottomDrawer due to relative position
119
+ onClick={onCreate}
120
+ />
121
+ )}
122
+ {showCopyAndSendButtons && (
123
+ <>
124
+ <Button
125
+ label={t(`${documentType}.share.shareByLink.send`)}
126
+ variant="secondary"
127
+ size="medium"
128
+ startIcon={<Icon icon={LinkIcon} />}
129
+ className="u-flex-auto u-mr-half"
130
+ onClick={shareLink}
253
131
  />
254
- )}
255
- </div>
256
- )
257
- }
132
+ <Button
133
+ label={<Icon icon={CopyIcon} />}
134
+ variant="secondary"
135
+ size="medium"
136
+ onClick={copyLinkToClipboard}
137
+ />
138
+ </>
139
+ )}
140
+ {showOnlyCopyButton && (
141
+ <Button
142
+ label={t(`${documentType}.share.shareByLink.copy`)}
143
+ variant="secondary"
144
+ size="medium"
145
+ startIcon={<Icon icon={LinkIcon} />}
146
+ className="u-flex-auto u-mr-half"
147
+ onClick={copyLinkToClipboard}
148
+ />
149
+ )}
150
+ {isEditDialogOpen && (
151
+ <EditLinkPermissionDialog
152
+ open
153
+ onClose={onClose}
154
+ document={document}
155
+ onPermissionsSelected={onPermissionsSelected}
156
+ />
157
+ )}
158
+ <Snackbar open={alert.open} onClose={onCloseAlert}>
159
+ <Alert
160
+ variant="filled"
161
+ severity={alert.severity}
162
+ onClose={onCloseAlert}
163
+ >
164
+ {alert.message}
165
+ </Alert>
166
+ </Snackbar>
167
+ </div>
168
+ )
258
169
  }
259
170
 
260
171
  ShareByLink.propTypes = {
261
- permissions: PropTypes.array.isRequired,
262
- checked: PropTypes.bool.isRequired,
263
- documentType: PropTypes.string.isRequired,
172
+ link: PropTypes.string,
264
173
  document: PropTypes.object.isRequired,
265
- link: PropTypes.string.isRequired,
266
- onEnable: PropTypes.func.isRequired,
267
- onDisable: PropTypes.func.isRequired
174
+ documentType: PropTypes.string.isRequired,
175
+ onEnable: PropTypes.func.isRequired
268
176
  }
269
177
 
270
- export default translate()(ShareByLink)
178
+ export default ShareByLink
@@ -1,5 +1,6 @@
1
1
  import React from 'react'
2
2
  import { useI18n } from 'cozy-ui/transpiled/react/I18n'
3
+ import Typography from 'cozy-ui/transpiled/react/Typography'
3
4
 
4
5
  import { default as DumbShareByLink } from './ShareByLink'
5
6
  import { default as DumbShareByEmail } from './ShareByEmail'
@@ -32,7 +33,11 @@ const SharingContent = ({
32
33
  showShareOnlyByLink,
33
34
  showWhoHasAccess,
34
35
  recipientsToBeConfirmed,
35
- verifyRecipient
36
+ verifyRecipient,
37
+ link,
38
+ permissions,
39
+ onUpdateShareLinkPermissions,
40
+ onRevokeLink
36
41
  }) => {
37
42
  const { t } = useI18n()
38
43
 
@@ -56,6 +61,9 @@ const SharingContent = ({
56
61
  </strong>
57
62
  </div>
58
63
  )}
64
+ <Typography variant="h6" className="u-mb-1-half">
65
+ {t('Share.contacts.whoHasAccess')}
66
+ </Typography>
59
67
  {showShareByEmail && (
60
68
  <DumbShareByEmail
61
69
  contacts={contacts}
@@ -72,7 +80,7 @@ const SharingContent = ({
72
80
  )}
73
81
  {showWhoHasAccess && (
74
82
  <WhoHasAccess
75
- className="u-mt-1"
83
+ className="u-mt-half"
76
84
  document={document}
77
85
  documentType={documentType}
78
86
  isOwner={isOwner}
@@ -81,6 +89,10 @@ const SharingContent = ({
81
89
  recipients={recipients}
82
90
  recipientsToBeConfirmed={recipientsToBeConfirmed}
83
91
  verifyRecipient={verifyRecipient}
92
+ link={link}
93
+ permissions={permissions}
94
+ onUpdateShareLinkPermissions={onUpdateShareLinkPermissions}
95
+ onRevokeLink={onRevokeLink}
84
96
  />
85
97
  )}
86
98
  </div>
@@ -5,6 +5,12 @@ import AppLike from '../../test/AppLike'
5
5
  import { createMockClient } from 'cozy-client'
6
6
  import { act, render, fireEvent } from '@testing-library/react'
7
7
 
8
+ jest.mock('cozy-client', () => ({
9
+ ...jest.requireActual('cozy-client'),
10
+ useQuery: jest.fn().mockReturnValue({ data: { public_name: 'Alice' } }),
11
+ hasQueryBeenLoaded: jest.fn().mockReturnValue(true)
12
+ }))
13
+
8
14
  describe('ShareDialogCozyToCozy', () => {
9
15
  const client = createMockClient({})
10
16
  client.options = {
@@ -26,7 +32,8 @@ describe('ShareDialogCozyToCozy', () => {
26
32
 
27
33
  const { getByText } = setup(props)
28
34
 
29
- expect(getByText('Owner')).toBeTruthy()
35
+ expect(getByText('You')).toBeTruthy()
36
+ expect(getByText('owner')).toBeTruthy()
30
37
  })
31
38
 
32
39
  it('should show loading while calling getRecipientsToBeConfirmed', async () => {
@@ -3,8 +3,14 @@ import { Dialog } from 'cozy-ui/transpiled/react/CozyDialogs'
3
3
  import { useI18n } from 'cozy-ui/transpiled/react/I18n'
4
4
 
5
5
  import { default as DumbShareByLink } from './ShareByLink'
6
+ import WhoHasAccess from './WhoHasAccess'
7
+ import Typography from 'cozy-ui/transpiled/react/Typography'
6
8
 
7
9
  const ShareDialogOnlyByLink = ({
10
+ isOwner,
11
+ onRevoke,
12
+ onRevokeSelf,
13
+ recipients,
8
14
  document,
9
15
  documentType,
10
16
  link,
@@ -24,19 +30,30 @@ const ShareDialogOnlyByLink = ({
24
30
  name: document.name || document.attributes.name
25
31
  })}
26
32
  content={
27
- <DumbShareByLink
28
- checked={link !== null}
29
- document={document}
30
- documentType={documentType}
31
- link={link}
32
- onChangePermissions={onUpdateShareLinkPermissions}
33
- onDisable={onRevokeLink}
34
- onEnable={onShareByLink}
35
- permissions={permissions}
36
- popperOptions={{
37
- strategy: 'fixed'
38
- }}
39
- />
33
+ <>
34
+ <Typography variant="h6">
35
+ {t('Share.contacts.whoHasAccess')}
36
+ </Typography>
37
+ <WhoHasAccess
38
+ className="u-mt-half"
39
+ document={document}
40
+ documentType={documentType}
41
+ isOwner={isOwner}
42
+ onRevoke={onRevoke}
43
+ onRevokeSelf={onRevokeSelf}
44
+ recipients={recipients}
45
+ link={link}
46
+ permissions={permissions}
47
+ onUpdateShareLinkPermissions={onUpdateShareLinkPermissions}
48
+ onRevokeLink={onRevokeLink}
49
+ />
50
+ <DumbShareByLink
51
+ link={link}
52
+ document={document}
53
+ documentType={documentType}
54
+ onEnable={onShareByLink}
55
+ />
56
+ </>
40
57
  }
41
58
  />
42
59
  )
@@ -228,19 +228,19 @@ const ShareDialogTwoStepsConfirmationContainer = ({
228
228
  showWhoHasAccess={showWhoHasAccess}
229
229
  recipientsToBeConfirmed={recipientsToBeConfirmed}
230
230
  verifyRecipient={showConfirmationDialog}
231
+ link={link}
232
+ permissions={permissions}
233
+ onUpdateShareLinkPermissions={onUpdateShareLinkPermissions}
234
+ onRevokeLink={onRevokeLink}
231
235
  />
232
236
  )
233
237
 
234
238
  dialogActions = DialogActionsOnShare ? (
235
239
  <DialogActionsOnShare
236
- checked={link !== null}
240
+ link={link}
237
241
  document={document}
238
242
  documentType={documentType}
239
- link={link}
240
- onChangePermissions={onUpdateShareLinkPermissions}
241
- onDisable={onRevokeLink}
242
243
  onEnable={onShareByLink}
243
- permissions={permissions}
244
244
  />
245
245
  ) : null
246
246
  } else if (status === 'confirmingRecipient') {
@@ -41,6 +41,10 @@ export const ShareModal = ({
41
41
 
42
42
  return shareDialogOnlyByLink ? (
43
43
  <ShareDialogOnlyByLink
44
+ isOwner={isOwner}
45
+ onRevoke={onRevoke}
46
+ onRevokeSelf={onRevokeSelf}
47
+ recipients={recipients}
44
48
  document={document}
45
49
  documentType={documentType}
46
50
  link={link}
@@ -92,7 +96,7 @@ ShareModal.propTypes = {
92
96
  hasSharedChild: PropTypes.bool,
93
97
  hasSharedParent: PropTypes.bool,
94
98
  isOwner: PropTypes.bool,
95
- link: PropTypes.string.isRequired,
99
+ link: PropTypes.string,
96
100
  needsContactsPermission: PropTypes.bool,
97
101
  onClose: PropTypes.func.isRequired,
98
102
  onRevoke: PropTypes.func.isRequired,