cozy-sharing 31.1.0 → 32.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.
- package/CHANGELOG.md +28 -0
- package/dist/components/FederatedFolder/DumbFederatedFolderModal.js +15 -16
- package/dist/components/FederatedFolder/FederatedFolderModal.js +78 -103
- package/dist/components/FederatedFolder/FederatedFolderModal.spec.js +102 -292
- package/dist/components/Recipient/RecipientConfirm.js +0 -5
- package/dist/components/ShareAutosuggest.js +9 -4
- package/dist/components/ShareByEmail.js +29 -274
- package/dist/components/ShareByEmail.spec.js +52 -230
- package/dist/components/ShareByLink.js +1 -3
- package/dist/components/ShareDialogCozyToCozy.js +169 -35
- package/dist/components/ShareDialogCozyToCozy.spec.js +122 -35
- package/dist/components/ShareDialogTwoStepsConfirmationContainer.js +13 -3
- package/dist/components/ShareModal/SharingDetailsModal.js +0 -5
- package/dist/components/ShareRecipientsInput.js +6 -3
- package/dist/components/SharedDrive/SharedDriveForm.js +11 -23
- package/dist/components/SharedDrive/SharedDriveModal.js +1 -1
- package/dist/components/SharedDrive/useSharedDrive.js +33 -57
- package/dist/components/SharedDrive/useSharedDrive.spec.js +29 -93
- package/dist/components/SharedFolder/DumbBatchSharedFolderModal.js +15 -26
- package/dist/components/Sharetypeselect.js +85 -90
- package/dist/hooks/usePendingRecipients.js +20 -0
- package/dist/hooks/usePendingRecipients.spec.js +30 -0
- package/dist/styles/autosuggest.styl +8 -2
- package/dist/styles/share.styl +0 -39
- package/dist/stylesheet.css +8 -44
- package/locales/en.json +5 -9
- package/locales/fr.json +5 -9
- package/locales/ru.json +5 -9
- package/locales/vi.json +5 -9
- package/package.json +4 -5
- package/src/components/FederatedFolder/DumbFederatedFolderModal.jsx +14 -15
- package/src/components/FederatedFolder/FederatedFolderModal.jsx +50 -67
- package/src/components/FederatedFolder/FederatedFolderModal.spec.jsx +63 -186
- package/src/components/ShareAutosuggest.jsx +7 -2
- package/src/components/ShareByEmail.jsx +35 -186
- package/src/components/ShareByEmail.spec.jsx +22 -173
- package/src/components/ShareByLink.jsx +1 -7
- package/src/components/ShareDialogCozyToCozy.jsx +171 -38
- package/src/components/ShareDialogCozyToCozy.spec.jsx +66 -0
- package/src/components/ShareDialogTwoStepsConfirmationContainer.jsx +11 -1
- package/src/components/ShareRecipientsInput.jsx +5 -2
- package/src/components/SharedDrive/SharedDriveForm.jsx +10 -23
- package/src/components/SharedDrive/SharedDriveModal.jsx +1 -1
- package/src/components/SharedDrive/useSharedDrive.js +24 -50
- package/src/components/SharedDrive/useSharedDrive.spec.js +19 -67
- package/src/components/SharedFolder/DumbBatchSharedFolderModal.jsx +15 -29
- package/src/components/Sharetypeselect.jsx +75 -58
- package/src/hooks/usePendingRecipients.js +13 -0
- package/src/hooks/usePendingRecipients.spec.js +21 -0
- package/src/styles/autosuggest.styl +8 -2
- package/src/styles/share.styl +0 -39
- package/dist/components/SharedDrive/helpers.js +0 -102
- package/dist/components/SharedDrive/helpers.spec.js +0 -227
- package/dist/components/SharedStatus.js +0 -61
- package/dist/components/SharedStatus.spec.js +0 -44
- package/dist/components/Sharesubmit.js +0 -28
- package/dist/components/__snapshots__/SharedStatus.spec.js.snap +0 -94
- package/dist/propTypes.js +0 -26
- package/src/components/SharedDrive/helpers.js +0 -108
- package/src/components/SharedDrive/helpers.spec.js +0 -177
- package/src/components/SharedStatus.jsx +0 -50
- package/src/components/SharedStatus.spec.js +0 -48
- package/src/components/Sharesubmit.jsx +0 -31
- package/src/components/__snapshots__/SharedStatus.spec.js.snap +0 -94
- package/src/propTypes.js +0 -29
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import cx from 'classnames'
|
|
2
|
-
import
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import React, { useCallback, useMemo, useState } from 'react'
|
|
3
4
|
|
|
5
|
+
import { useClient } from 'cozy-client'
|
|
6
|
+
import Button from 'cozy-ui/transpiled/react/Buttons'
|
|
4
7
|
import Typography from 'cozy-ui/transpiled/react/Typography'
|
|
8
|
+
import { useAlert } from 'cozy-ui/transpiled/react/providers/Alert'
|
|
5
9
|
import useBreakpoints from 'cozy-ui/transpiled/react/providers/Breakpoints'
|
|
6
10
|
import { useI18n } from 'twake-i18n'
|
|
7
11
|
|
|
@@ -9,31 +13,34 @@ import AntivirusAlert from './AntivirusAlert'
|
|
|
9
13
|
import { default as DumbShareByEmail } from './ShareByEmail'
|
|
10
14
|
import { default as DumbShareByLink } from './ShareByLink'
|
|
11
15
|
import ShareDialogTwoStepsConfirmationContainer from './ShareDialogTwoStepsConfirmationContainer'
|
|
16
|
+
import { ShareRecipientsLimitModal } from './ShareRecipientsLimitModal'
|
|
12
17
|
import WhoHasAccess from './WhoHasAccess'
|
|
18
|
+
import { getOrCreateFromArray } from '../helpers/contacts'
|
|
19
|
+
import { hasReachRecipientsLimit } from '../helpers/recipients'
|
|
20
|
+
import { getErrorMessage, getSuccessMessage } from '../helpers/share'
|
|
21
|
+
import { usePendingRecipients } from '../hooks/usePendingRecipients'
|
|
13
22
|
import styles from '../styles/share.styl'
|
|
14
23
|
|
|
15
|
-
/**
|
|
16
|
-
* Displays the sharing interface that can be used when ShareDialogCozyToCozy is in sharing state
|
|
17
|
-
*/
|
|
18
24
|
const SharingContent = ({
|
|
19
|
-
createContact,
|
|
20
25
|
document,
|
|
21
26
|
documentType,
|
|
22
27
|
hasSharedParent,
|
|
23
28
|
isOwner,
|
|
24
29
|
onRevoke,
|
|
25
30
|
onRevokeSelf,
|
|
26
|
-
onShare,
|
|
27
31
|
recipients,
|
|
28
32
|
sharing,
|
|
29
|
-
sharingDesc,
|
|
30
33
|
showShareByEmail,
|
|
31
34
|
showShareOnlyByLink,
|
|
32
35
|
showWhoHasAccess,
|
|
33
36
|
recipientsToBeConfirmed,
|
|
34
37
|
verifyRecipient,
|
|
35
38
|
link,
|
|
36
|
-
permissions
|
|
39
|
+
permissions,
|
|
40
|
+
pendingRecipients,
|
|
41
|
+
onPendingRecipientsChange,
|
|
42
|
+
selectedOption,
|
|
43
|
+
onSelectedOptionChange
|
|
37
44
|
}) => {
|
|
38
45
|
const { t } = useI18n()
|
|
39
46
|
const { isMobile } = useBreakpoints()
|
|
@@ -64,13 +71,14 @@ const SharingContent = ({
|
|
|
64
71
|
</Typography>
|
|
65
72
|
{showShareByEmail && (
|
|
66
73
|
<DumbShareByEmail
|
|
67
|
-
createContact={createContact}
|
|
68
74
|
currentRecipients={recipients}
|
|
69
75
|
document={document}
|
|
70
76
|
documentType={documentType}
|
|
71
|
-
onShare={onShare}
|
|
72
77
|
sharing={sharing}
|
|
73
|
-
|
|
78
|
+
pendingRecipients={pendingRecipients}
|
|
79
|
+
onPendingRecipientsChange={onPendingRecipientsChange}
|
|
80
|
+
selectedOption={selectedOption}
|
|
81
|
+
onSelectedOptionChange={onSelectedOptionChange}
|
|
74
82
|
/>
|
|
75
83
|
)}
|
|
76
84
|
</div>
|
|
@@ -92,55 +100,180 @@ const SharingContent = ({
|
|
|
92
100
|
)
|
|
93
101
|
}
|
|
94
102
|
|
|
95
|
-
/**
|
|
96
|
-
* Displays the dialog's title that can be used when ShareDialogCozyToCozy is in sharing state
|
|
97
|
-
*/
|
|
98
103
|
const SharingTitleFunction = ({ documentType, document }) =>
|
|
99
104
|
function SharingTitle() {
|
|
100
105
|
const { t } = useI18n()
|
|
101
|
-
|
|
102
106
|
const title = t(`${documentType}.share.title`, {
|
|
103
107
|
name: document.name || document.attributes?.name
|
|
104
108
|
})
|
|
105
|
-
|
|
106
109
|
return title
|
|
107
110
|
}
|
|
108
111
|
|
|
109
|
-
/**
|
|
110
|
-
* Displays a sharing dialog that allows to share a document between multiple Cozy users
|
|
111
|
-
*/
|
|
112
112
|
const ShareDialogCozyToCozy = ({
|
|
113
113
|
showShareByLink,
|
|
114
114
|
showGenerateLinkButton,
|
|
115
115
|
autoOpenShareRestriction,
|
|
116
116
|
documentType,
|
|
117
117
|
document,
|
|
118
|
+
onShare,
|
|
119
|
+
recipients,
|
|
120
|
+
sharingDesc,
|
|
121
|
+
createContact,
|
|
122
|
+
onClose,
|
|
118
123
|
...props
|
|
119
124
|
}) => {
|
|
125
|
+
const { t } = useI18n()
|
|
126
|
+
const client = useClient()
|
|
127
|
+
const { showAlert } = useAlert()
|
|
128
|
+
|
|
129
|
+
const {
|
|
130
|
+
pendingRecipients,
|
|
131
|
+
setPendingRecipients,
|
|
132
|
+
selectedOption,
|
|
133
|
+
setSelectedOption
|
|
134
|
+
} = usePendingRecipients()
|
|
135
|
+
|
|
136
|
+
const [submitting, setSubmitting] = useState(false)
|
|
137
|
+
const [showRecipientsLimit, setShowRecipientsLimit] = useState(false)
|
|
138
|
+
|
|
139
|
+
const handleShare = useCallback(async () => {
|
|
140
|
+
if (pendingRecipients.length === 0) {
|
|
141
|
+
onClose()
|
|
142
|
+
return
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (hasReachRecipientsLimit(recipients, pendingRecipients)) {
|
|
146
|
+
setShowRecipientsLimit(true)
|
|
147
|
+
return
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
setSubmitting(true)
|
|
151
|
+
try {
|
|
152
|
+
const contacts = await getOrCreateFromArray(
|
|
153
|
+
client,
|
|
154
|
+
pendingRecipients,
|
|
155
|
+
createContact
|
|
156
|
+
)
|
|
157
|
+
const readWriteRecipients = selectedOption === 'readOnly' ? [] : contacts
|
|
158
|
+
const readOnlyRecipients = selectedOption === 'readOnly' ? contacts : []
|
|
159
|
+
|
|
160
|
+
await onShare({
|
|
161
|
+
document,
|
|
162
|
+
recipients: readWriteRecipients,
|
|
163
|
+
readOnlyRecipients,
|
|
164
|
+
description: sharingDesc,
|
|
165
|
+
openSharing: readWriteRecipients.length > 0
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
showAlert({
|
|
169
|
+
message: t(...getSuccessMessage(recipients, contacts, documentType)),
|
|
170
|
+
severity: 'success',
|
|
171
|
+
variant: 'filled'
|
|
172
|
+
})
|
|
173
|
+
onClose()
|
|
174
|
+
} catch (err) {
|
|
175
|
+
showAlert({
|
|
176
|
+
message: t(
|
|
177
|
+
...getErrorMessage({
|
|
178
|
+
t,
|
|
179
|
+
err,
|
|
180
|
+
documentType,
|
|
181
|
+
recipients: pendingRecipients,
|
|
182
|
+
selectedOption
|
|
183
|
+
})
|
|
184
|
+
),
|
|
185
|
+
severity: 'error',
|
|
186
|
+
variant: 'filled'
|
|
187
|
+
})
|
|
188
|
+
} finally {
|
|
189
|
+
setSubmitting(false)
|
|
190
|
+
}
|
|
191
|
+
}, [
|
|
192
|
+
pendingRecipients,
|
|
193
|
+
selectedOption,
|
|
194
|
+
client,
|
|
195
|
+
showAlert,
|
|
196
|
+
t,
|
|
197
|
+
recipients,
|
|
198
|
+
onShare,
|
|
199
|
+
onClose,
|
|
200
|
+
createContact,
|
|
201
|
+
document,
|
|
202
|
+
documentType,
|
|
203
|
+
sharingDesc
|
|
204
|
+
])
|
|
205
|
+
|
|
120
206
|
const dialogActionsOnShare = useMemo(() => {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
207
|
+
const Actions = dialogActionProps => (
|
|
208
|
+
<>
|
|
209
|
+
{showShareByLink && (
|
|
210
|
+
<DumbShareByLink
|
|
211
|
+
{...dialogActionProps}
|
|
212
|
+
showGenerateLinkButton={showGenerateLinkButton}
|
|
213
|
+
autoOpenShareRestriction={autoOpenShareRestriction}
|
|
214
|
+
/>
|
|
215
|
+
)}
|
|
216
|
+
<Button
|
|
217
|
+
variant="primary"
|
|
218
|
+
label={t(`${documentType}.share.shareByEmail.send`)}
|
|
219
|
+
busy={submitting}
|
|
220
|
+
onClick={handleShare}
|
|
221
|
+
/>
|
|
222
|
+
</>
|
|
128
223
|
)
|
|
129
|
-
|
|
130
|
-
return
|
|
131
|
-
}, [
|
|
224
|
+
Actions.displayName = 'ShareDialogCozyToCozyActions'
|
|
225
|
+
return Actions
|
|
226
|
+
}, [
|
|
227
|
+
handleShare,
|
|
228
|
+
submitting,
|
|
229
|
+
t,
|
|
230
|
+
documentType,
|
|
231
|
+
showShareByLink,
|
|
232
|
+
showGenerateLinkButton,
|
|
233
|
+
autoOpenShareRestriction
|
|
234
|
+
])
|
|
132
235
|
|
|
133
236
|
return (
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
237
|
+
<>
|
|
238
|
+
<ShareDialogTwoStepsConfirmationContainer
|
|
239
|
+
{...props}
|
|
240
|
+
documentType={documentType}
|
|
241
|
+
document={document}
|
|
242
|
+
recipients={recipients}
|
|
243
|
+
sharingDesc={sharingDesc}
|
|
244
|
+
createContact={createContact}
|
|
245
|
+
onShare={onShare}
|
|
246
|
+
onClose={onClose}
|
|
247
|
+
dialogContentOnShare={SharingContent}
|
|
248
|
+
dialogActionsOnShare={dialogActionsOnShare}
|
|
249
|
+
dialogTitleOnShare={SharingTitleFunction({ documentType, document })}
|
|
250
|
+
disableGutters
|
|
251
|
+
pendingRecipients={pendingRecipients}
|
|
252
|
+
onPendingRecipientsChange={setPendingRecipients}
|
|
253
|
+
selectedOption={selectedOption}
|
|
254
|
+
onSelectedOptionChange={setSelectedOption}
|
|
255
|
+
/>
|
|
256
|
+
{showRecipientsLimit && (
|
|
257
|
+
<ShareRecipientsLimitModal
|
|
258
|
+
documentName={document?.name}
|
|
259
|
+
onConfirm={() => setShowRecipientsLimit(false)}
|
|
260
|
+
/>
|
|
261
|
+
)}
|
|
262
|
+
</>
|
|
143
263
|
)
|
|
144
264
|
}
|
|
145
265
|
|
|
266
|
+
ShareDialogCozyToCozy.propTypes = {
|
|
267
|
+
showShareByLink: PropTypes.bool,
|
|
268
|
+
showGenerateLinkButton: PropTypes.bool,
|
|
269
|
+
autoOpenShareRestriction: PropTypes.bool,
|
|
270
|
+
documentType: PropTypes.string.isRequired,
|
|
271
|
+
document: PropTypes.object.isRequired,
|
|
272
|
+
onShare: PropTypes.func.isRequired,
|
|
273
|
+
recipients: PropTypes.array.isRequired,
|
|
274
|
+
sharingDesc: PropTypes.string,
|
|
275
|
+
createContact: PropTypes.func.isRequired,
|
|
276
|
+
onClose: PropTypes.func.isRequired
|
|
277
|
+
}
|
|
278
|
+
|
|
146
279
|
export default ShareDialogCozyToCozy
|
|
@@ -20,6 +20,12 @@ jest.mock('../hooks/useSharingContext', () => ({
|
|
|
20
20
|
})
|
|
21
21
|
}))
|
|
22
22
|
|
|
23
|
+
jest.mock('../helpers/contacts', () => ({
|
|
24
|
+
getOrCreateFromArray: jest.fn((client, recipients) =>
|
|
25
|
+
Promise.resolve(recipients)
|
|
26
|
+
)
|
|
27
|
+
}))
|
|
28
|
+
|
|
23
29
|
describe('ShareDialogCozyToCozy', () => {
|
|
24
30
|
const client = createMockClient({})
|
|
25
31
|
client.options = {
|
|
@@ -163,6 +169,65 @@ describe('ShareDialogCozyToCozy', () => {
|
|
|
163
169
|
).not.toBeInTheDocument()
|
|
164
170
|
})
|
|
165
171
|
|
|
172
|
+
it('main Share button calls onClose when there are no pending chips', () => {
|
|
173
|
+
const onClose = jest.fn()
|
|
174
|
+
const onShare = jest.fn()
|
|
175
|
+
const props = { ...getMockProps(), onClose, onShare }
|
|
176
|
+
|
|
177
|
+
const { getByRole } = setup(props)
|
|
178
|
+
|
|
179
|
+
fireEvent.click(getByRole('button', { name: 'Share' }))
|
|
180
|
+
|
|
181
|
+
expect(onShare).not.toHaveBeenCalled()
|
|
182
|
+
expect(onClose).toHaveBeenCalledTimes(1)
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
it('main Share button calls onShare with chips then closes', async () => {
|
|
186
|
+
const onClose = jest.fn()
|
|
187
|
+
const onShare = jest.fn().mockResolvedValue(undefined)
|
|
188
|
+
const props = { ...getMockProps(), onClose, onShare }
|
|
189
|
+
|
|
190
|
+
const { getByPlaceholderText, getByRole } = setup(props)
|
|
191
|
+
|
|
192
|
+
act(() => {
|
|
193
|
+
fireEvent.change(
|
|
194
|
+
getByPlaceholderText(
|
|
195
|
+
'Enter the email address or name of the recipient'
|
|
196
|
+
),
|
|
197
|
+
{
|
|
198
|
+
target: { value: 'new@cozycloud.cc' }
|
|
199
|
+
}
|
|
200
|
+
)
|
|
201
|
+
})
|
|
202
|
+
act(() => {
|
|
203
|
+
fireEvent.keyPress(
|
|
204
|
+
getByPlaceholderText(
|
|
205
|
+
'Enter the email address or name of the recipient'
|
|
206
|
+
),
|
|
207
|
+
{
|
|
208
|
+
key: 'Enter',
|
|
209
|
+
code: 'Enter',
|
|
210
|
+
charCode: 13
|
|
211
|
+
}
|
|
212
|
+
)
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
await act(async () => {
|
|
216
|
+
fireEvent.click(getByRole('button', { name: 'Share' }))
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
expect(onShare).toHaveBeenCalledWith(
|
|
220
|
+
expect.objectContaining({
|
|
221
|
+
document: props.document,
|
|
222
|
+
recipients: [{ email: 'new@cozycloud.cc' }],
|
|
223
|
+
readOnlyRecipients: [],
|
|
224
|
+
description: props.sharingDesc,
|
|
225
|
+
openSharing: true
|
|
226
|
+
})
|
|
227
|
+
)
|
|
228
|
+
expect(onClose).toHaveBeenCalledTimes(1)
|
|
229
|
+
})
|
|
230
|
+
|
|
166
231
|
it(`should display confirmation of 'contact rejection' when user click on the 'reject' button`, async () => {
|
|
167
232
|
const { promise, resolve } = deferablePromise()
|
|
168
233
|
|
|
@@ -372,6 +437,7 @@ const getMockProps = () => {
|
|
|
372
437
|
showWhoHasAccess: true,
|
|
373
438
|
onRevoke: jest.fn(),
|
|
374
439
|
onShare: jest.fn(),
|
|
440
|
+
onClose: jest.fn(),
|
|
375
441
|
createContact: jest.fn()
|
|
376
442
|
}
|
|
377
443
|
}
|
|
@@ -108,7 +108,11 @@ const ShareDialogTwoStepsConfirmationContainer = ({
|
|
|
108
108
|
twoStepsConfirmationMethods = {},
|
|
109
109
|
dialogContentOnShare: DialogContentOnShare,
|
|
110
110
|
dialogActionsOnShare: DialogActionsOnShare,
|
|
111
|
-
dialogTitleOnShare: DialogTitleOnShare
|
|
111
|
+
dialogTitleOnShare: DialogTitleOnShare,
|
|
112
|
+
pendingRecipients,
|
|
113
|
+
onPendingRecipientsChange,
|
|
114
|
+
selectedOption,
|
|
115
|
+
onSelectedOptionChange
|
|
112
116
|
}) => {
|
|
113
117
|
const { t } = useI18n()
|
|
114
118
|
|
|
@@ -222,6 +226,10 @@ const ShareDialogTwoStepsConfirmationContainer = ({
|
|
|
222
226
|
permissions={permissions}
|
|
223
227
|
onUpdateShareLinkPermissions={onUpdateShareLinkPermissions}
|
|
224
228
|
onRevokeLink={onRevokeLink}
|
|
229
|
+
pendingRecipients={pendingRecipients}
|
|
230
|
+
onPendingRecipientsChange={onPendingRecipientsChange}
|
|
231
|
+
selectedOption={selectedOption}
|
|
232
|
+
onSelectedOptionChange={onSelectedOptionChange}
|
|
225
233
|
/>
|
|
226
234
|
)
|
|
227
235
|
|
|
@@ -230,6 +238,8 @@ const ShareDialogTwoStepsConfirmationContainer = ({
|
|
|
230
238
|
link={link}
|
|
231
239
|
document={document}
|
|
232
240
|
documentType={documentType}
|
|
241
|
+
pendingRecipients={pendingRecipients}
|
|
242
|
+
selectedOption={selectedOption}
|
|
233
243
|
/>
|
|
234
244
|
) : null
|
|
235
245
|
} else if (status === 'confirmingRecipient') {
|
|
@@ -23,7 +23,8 @@ const ShareRecipientsInput = ({
|
|
|
23
23
|
placeholder,
|
|
24
24
|
onPick,
|
|
25
25
|
onRemove,
|
|
26
|
-
disabled
|
|
26
|
+
disabled,
|
|
27
|
+
endAdornment
|
|
27
28
|
}) => {
|
|
28
29
|
const reachableContactsQuery = buildReachableContactsQuery()
|
|
29
30
|
const reachableContactsResult = useQueryAll(
|
|
@@ -109,6 +110,7 @@ const ShareRecipientsInput = ({
|
|
|
109
110
|
onPick={onPick}
|
|
110
111
|
onRemove={onRemove}
|
|
111
112
|
placeholder={placeholder}
|
|
113
|
+
endAdornment={endAdornment}
|
|
112
114
|
/>
|
|
113
115
|
)
|
|
114
116
|
}
|
|
@@ -119,7 +121,8 @@ ShareRecipientsInput.propTypes = {
|
|
|
119
121
|
placeholder: PropTypes.string,
|
|
120
122
|
onPick: PropTypes.func.isRequired,
|
|
121
123
|
onRemove: PropTypes.func.isRequired,
|
|
122
|
-
disabled: PropTypes.bool
|
|
124
|
+
disabled: PropTypes.bool,
|
|
125
|
+
endAdornment: PropTypes.node
|
|
123
126
|
}
|
|
124
127
|
|
|
125
128
|
ShareRecipientsInput.defaultProps = {
|
|
@@ -8,20 +8,18 @@ import { useI18n } from 'twake-i18n'
|
|
|
8
8
|
|
|
9
9
|
import withLocales from '../../hoc/withLocales'
|
|
10
10
|
import { default as DumbShareByEmail } from '../ShareByEmail'
|
|
11
|
-
import WhoHasAccess from '../WhoHasAccess'
|
|
12
11
|
import { useSharedDrive } from './useSharedDrive'
|
|
13
12
|
|
|
14
13
|
export const SharedDriveForm = withLocales(({ onSuccess, onCancel }) => {
|
|
15
14
|
const { t } = useI18n()
|
|
16
15
|
const {
|
|
17
16
|
sharedDriveName,
|
|
18
|
-
recipients,
|
|
19
17
|
handleSharedDriveNameChange,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
pendingRecipients,
|
|
19
|
+
setPendingRecipients,
|
|
20
|
+
selectedOption,
|
|
21
|
+
setSelectedOption,
|
|
22
|
+
onCreate
|
|
25
23
|
} = useSharedDrive({ onSuccess })
|
|
26
24
|
|
|
27
25
|
return (
|
|
@@ -40,25 +38,14 @@ export const SharedDriveForm = withLocales(({ onSuccess, onCancel }) => {
|
|
|
40
38
|
{t('SharedDrive.sharedDriveModal.addPeople')}
|
|
41
39
|
</Typography>
|
|
42
40
|
<DumbShareByEmail
|
|
43
|
-
|
|
44
|
-
currentRecipients={recipients}
|
|
41
|
+
currentRecipients={[]}
|
|
45
42
|
documentType="Files"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
sharingDesc=""
|
|
43
|
+
pendingRecipients={pendingRecipients}
|
|
44
|
+
onPendingRecipientsChange={setPendingRecipients}
|
|
45
|
+
selectedOption={selectedOption}
|
|
46
|
+
onSelectedOptionChange={setSelectedOption}
|
|
51
47
|
/>
|
|
52
48
|
</div>
|
|
53
|
-
<WhoHasAccess
|
|
54
|
-
isOwner
|
|
55
|
-
isSharedDrive
|
|
56
|
-
recipients={recipients}
|
|
57
|
-
documentType="Files"
|
|
58
|
-
className="u-w-100"
|
|
59
|
-
onRevoke={onRevoke}
|
|
60
|
-
onSetType={onSetType}
|
|
61
|
-
/>
|
|
62
49
|
<div className="u-flex u-ph-2 u-pv-1">
|
|
63
50
|
<Button
|
|
64
51
|
variant="text"
|
|
@@ -4,8 +4,8 @@ import React from 'react'
|
|
|
4
4
|
import { FixedDialog } from 'cozy-ui/transpiled/react/CozyDialogs'
|
|
5
5
|
import { useI18n } from 'twake-i18n'
|
|
6
6
|
|
|
7
|
-
import withLocales from '../../hoc/withLocales'
|
|
8
7
|
import { SharedDriveForm } from './SharedDriveForm'
|
|
8
|
+
import withLocales from '../../hoc/withLocales'
|
|
9
9
|
|
|
10
10
|
export const SharedDriveModal = withLocales(({ onClose }) => {
|
|
11
11
|
const { t } = useI18n()
|
|
@@ -4,13 +4,8 @@ import { useClient } from 'cozy-client'
|
|
|
4
4
|
import { useAlert } from 'cozy-ui/transpiled/react/providers/Alert'
|
|
5
5
|
import { useI18n } from 'twake-i18n'
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
formatRecipients,
|
|
10
|
-
mergeAndDeduplicateRecipients,
|
|
11
|
-
moveRecipientToReadOnly,
|
|
12
|
-
moveRecipientToReadWrite
|
|
13
|
-
} from './helpers'
|
|
7
|
+
import { getOrCreateFromArray } from '../../helpers/contacts'
|
|
8
|
+
import { usePendingRecipients } from '../../hooks/usePendingRecipients'
|
|
14
9
|
import { Contact } from '../../models'
|
|
15
10
|
|
|
16
11
|
export const useSharedDrive = ({ onSuccess }) => {
|
|
@@ -18,36 +13,35 @@ export const useSharedDrive = ({ onSuccess }) => {
|
|
|
18
13
|
const { t } = useI18n()
|
|
19
14
|
const { showAlert } = useAlert()
|
|
20
15
|
|
|
21
|
-
const [sharedDriveRecipients, setSharedDriveRecipients] = useState({
|
|
22
|
-
recipients: [],
|
|
23
|
-
readOnlyRecipients: []
|
|
24
|
-
})
|
|
25
16
|
const [sharedDriveName, setSharedDriveName] = useState('')
|
|
17
|
+
const {
|
|
18
|
+
pendingRecipients,
|
|
19
|
+
setPendingRecipients,
|
|
20
|
+
selectedOption,
|
|
21
|
+
setSelectedOption
|
|
22
|
+
} = usePendingRecipients()
|
|
26
23
|
|
|
27
24
|
const handleSharedDriveNameChange = event => {
|
|
28
25
|
setSharedDriveName(event.target.value)
|
|
29
26
|
}
|
|
30
27
|
|
|
31
|
-
const
|
|
32
|
-
setSharedDriveRecipients(prev => ({
|
|
33
|
-
recipients: mergeAndDeduplicateRecipients([
|
|
34
|
-
prev.recipients,
|
|
35
|
-
params.recipients
|
|
36
|
-
]),
|
|
37
|
-
readOnlyRecipients: mergeAndDeduplicateRecipients([
|
|
38
|
-
prev.readOnlyRecipients,
|
|
39
|
-
params.readOnlyRecipients
|
|
40
|
-
])
|
|
41
|
-
}))
|
|
42
|
-
}
|
|
28
|
+
const createContact = contact => client.create(Contact.doctype, contact)
|
|
43
29
|
|
|
44
30
|
const onCreate = async () => {
|
|
45
31
|
try {
|
|
32
|
+
const contacts = await getOrCreateFromArray(
|
|
33
|
+
client,
|
|
34
|
+
pendingRecipients,
|
|
35
|
+
createContact
|
|
36
|
+
)
|
|
37
|
+
const readWriteRecipients = selectedOption === 'readOnly' ? [] : contacts
|
|
38
|
+
const readOnlyRecipients = selectedOption === 'readOnly' ? contacts : []
|
|
39
|
+
|
|
46
40
|
await client.collection('io.cozy.sharings').createSharedDrive({
|
|
47
41
|
name: sharedDriveName,
|
|
48
42
|
description: sharedDriveName,
|
|
49
|
-
recipients:
|
|
50
|
-
readOnlyRecipients
|
|
43
|
+
recipients: readWriteRecipients,
|
|
44
|
+
readOnlyRecipients
|
|
51
45
|
})
|
|
52
46
|
|
|
53
47
|
showAlert({
|
|
@@ -66,33 +60,13 @@ export const useSharedDrive = ({ onSuccess }) => {
|
|
|
66
60
|
}
|
|
67
61
|
}
|
|
68
62
|
|
|
69
|
-
const onSetType = (index, newType) => {
|
|
70
|
-
const _id = index.split(RECIPIENT_INDEX_PREFIX)[1]
|
|
71
|
-
setSharedDriveRecipients(prev =>
|
|
72
|
-
newType === 'two-way'
|
|
73
|
-
? moveRecipientToReadWrite(prev, _id)
|
|
74
|
-
: moveRecipientToReadOnly(prev, _id)
|
|
75
|
-
)
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const onRevoke = index => {
|
|
79
|
-
const _id = index.split(RECIPIENT_INDEX_PREFIX)[1]
|
|
80
|
-
setSharedDriveRecipients(prev => ({
|
|
81
|
-
recipients: prev.recipients.filter(r => r._id !== _id),
|
|
82
|
-
readOnlyRecipients: prev.readOnlyRecipients.filter(r => r._id !== _id)
|
|
83
|
-
}))
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const createContact = contact => client.create(Contact.doctype, contact)
|
|
87
|
-
|
|
88
63
|
return {
|
|
89
64
|
sharedDriveName,
|
|
90
|
-
recipients: formatRecipients(sharedDriveRecipients),
|
|
91
65
|
handleSharedDriveNameChange,
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
66
|
+
pendingRecipients,
|
|
67
|
+
setPendingRecipients,
|
|
68
|
+
selectedOption,
|
|
69
|
+
setSelectedOption,
|
|
70
|
+
onCreate
|
|
97
71
|
}
|
|
98
72
|
}
|