cozy-sharing 17.0.0 → 19.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 +49 -0
- package/dist/SharingProvider.spec.js +84 -80
- package/dist/components/Recipient/LinkRecipientPermissions.js +18 -129
- package/dist/components/Recipient/actions/editPermissionLink.js +71 -0
- package/dist/components/Recipient/actions/readOnlyPermissionLink.js +63 -0
- package/dist/components/ShareByLink.js +45 -185
- package/dist/components/ShareDialogCozyToCozy.js +2 -6
- package/dist/components/ShareDialogOnlyByLink.js +2 -8
- package/dist/components/ShareDialogTwoStepsConfirmationContainer.js +1 -3
- package/dist/components/ShareModal/EditableSharingModal.js +1 -7
- package/dist/components/ShareModal/EditableSharingModal.spec.js +49 -52
- package/dist/components/ShareModal/SharingDetailsModal.js +1 -1
- package/dist/components/ShareModal.js +0 -12
- package/dist/components/ShareRestrictionModal/BoxDate.js +77 -0
- package/dist/components/ShareRestrictionModal/BoxEditingRights.js +83 -0
- package/dist/components/ShareRestrictionModal/BoxPassword.js +138 -0
- package/dist/components/ShareRestrictionModal/ShareRestrictionContentModal.js +94 -0
- package/dist/components/ShareRestrictionModal/ShareRestrictionModal.js +260 -0
- package/dist/components/ShareRestrictionModal/helpers.js +275 -0
- package/dist/components/ShareRestrictionModal/helpers.spec.js +110 -0
- package/dist/components/SharedStatus.spec.js +20 -21
- package/dist/components/WhoHasAccess.js +1 -5
- package/jest.config.js +8 -3
- package/jestHelpers/setup.js +1 -8
- package/locales/en.json +28 -0
- package/locales/fr.json +29 -0
- package/package.json +13 -11
- package/src/SharingProvider.spec.jsx +88 -88
- package/src/components/Recipient/LinkRecipientPermissions.jsx +28 -137
- package/src/components/Recipient/actions/editPermissionLink.js +63 -0
- package/src/components/Recipient/actions/readOnlyPermissionLink.js +59 -0
- package/src/components/ShareByLink.jsx +20 -96
- package/src/components/ShareDialogCozyToCozy.jsx +1 -5
- package/src/components/ShareDialogOnlyByLink.jsx +0 -6
- package/src/components/ShareDialogTwoStepsConfirmationContainer.jsx +0 -2
- package/src/components/ShareModal/EditableSharingModal.jsx +1 -7
- package/src/components/ShareModal/EditableSharingModal.spec.jsx +50 -44
- package/src/components/ShareModal/SharingDetailsModal.jsx +1 -1
- package/src/components/ShareModal.jsx +0 -12
- package/src/components/ShareRestrictionModal/BoxDate.jsx +76 -0
- package/src/components/ShareRestrictionModal/BoxEditingRights.jsx +91 -0
- package/src/components/ShareRestrictionModal/BoxPassword.jsx +112 -0
- package/src/components/ShareRestrictionModal/ShareRestrictionContentModal.jsx +102 -0
- package/src/components/ShareRestrictionModal/ShareRestrictionModal.jsx +177 -0
- package/src/components/ShareRestrictionModal/helpers.js +193 -0
- package/src/components/ShareRestrictionModal/helpers.spec.js +78 -0
- package/src/components/SharedStatus.spec.js +32 -31
- package/src/components/WhoHasAccess.jsx +1 -5
- package/src/components/__snapshots__/SharedStatus.spec.js.snap +59 -129
- package/dist/RefreshableSharings.spec.js +0 -40
- package/dist/components/EditLinkPermissionDialog.js +0 -72
- package/dist/components/EditLinkPermissionDialog.spec.js +0 -48
- package/src/RefreshableSharings.spec.jsx +0 -43
- package/src/components/EditLinkPermissionDialog.jsx +0 -89
- package/src/components/EditLinkPermissionDialog.spec.jsx +0 -53
|
@@ -1,95 +1,35 @@
|
|
|
1
1
|
import PropTypes from 'prop-types'
|
|
2
|
-
import React, {
|
|
2
|
+
import React, { useReducer } from 'react'
|
|
3
3
|
|
|
4
|
-
import Alert from 'cozy-ui/transpiled/react/Alert'
|
|
5
4
|
import Button from 'cozy-ui/transpiled/react/Buttons'
|
|
6
5
|
import Icon from 'cozy-ui/transpiled/react/Icon'
|
|
7
6
|
import CopyIcon from 'cozy-ui/transpiled/react/Icons/Copy'
|
|
8
7
|
import LinkIcon from 'cozy-ui/transpiled/react/Icons/Link'
|
|
9
|
-
import
|
|
8
|
+
import { useAlert } from 'cozy-ui/transpiled/react/providers/Alert'
|
|
10
9
|
import useBreakpoints from 'cozy-ui/transpiled/react/providers/Breakpoints'
|
|
11
10
|
import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n'
|
|
12
11
|
|
|
13
|
-
import
|
|
14
|
-
import {
|
|
15
|
-
import logger from '../logger'
|
|
12
|
+
import { ShareRestrictionModal } from './ShareRestrictionModal/ShareRestrictionModal'
|
|
13
|
+
import { copyToClipboard } from './ShareRestrictionModal/helpers'
|
|
16
14
|
|
|
17
|
-
const ShareByLink = ({ link, document, documentType
|
|
15
|
+
const ShareByLink = ({ link, document, documentType }) => {
|
|
18
16
|
const { t } = useI18n()
|
|
19
17
|
const { isMobile } = useBreakpoints()
|
|
20
|
-
const
|
|
21
|
-
const [shouldCopyToClipboard, setShouldCopyToClipboard] = useState(false)
|
|
22
|
-
const [alert, setAlert] = useState(false)
|
|
18
|
+
const { showAlert } = useAlert()
|
|
23
19
|
|
|
24
|
-
const
|
|
20
|
+
const showCopyAndSendButtons = link && isMobile && navigator.share
|
|
21
|
+
const showOnlyCopyButton =
|
|
22
|
+
(link && !isMobile) || (link && isMobile && !navigator.share)
|
|
25
23
|
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
await navigator.clipboard.writeText(link)
|
|
30
|
-
setAlert({
|
|
31
|
-
open: true,
|
|
32
|
-
severity: 'success',
|
|
33
|
-
message: t(`${documentType}.share.shareByLink.copied`)
|
|
34
|
-
})
|
|
35
|
-
} catch {
|
|
36
|
-
if (!isAutomaticCopy) {
|
|
37
|
-
// 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
|
|
38
|
-
setAlert({
|
|
39
|
-
open: true,
|
|
40
|
-
severity: 'error',
|
|
41
|
-
message: t(`${documentType}.share.shareByLink.failed`)
|
|
42
|
-
})
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
[documentType, link, t]
|
|
24
|
+
const [isEditDialogOpen, toggleEditDialogOpen] = useReducer(
|
|
25
|
+
state => !state,
|
|
26
|
+
false
|
|
47
27
|
)
|
|
48
28
|
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
setLoading(true)
|
|
52
|
-
await onEnable(document, options)
|
|
53
|
-
} catch (e) {
|
|
54
|
-
setAlert({
|
|
55
|
-
open: true,
|
|
56
|
-
severity: 'error',
|
|
57
|
-
message: t(`${documentType}.share.error.generic`)
|
|
58
|
-
})
|
|
59
|
-
logger.log(e)
|
|
60
|
-
} finally {
|
|
61
|
-
setLoading(false)
|
|
62
|
-
setShouldCopyToClipboard(true)
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const onCreate = async () => {
|
|
67
|
-
if (isOnlyReadOnlyLinkAllowed({ documentType })) {
|
|
68
|
-
onPermissionsSelected({ verbs: ['GET'] })
|
|
69
|
-
} else {
|
|
70
|
-
setIsEditDialogOpen(true)
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
useEffect(() => {
|
|
75
|
-
if (link && shouldCopyToClipboard) {
|
|
76
|
-
copyLinkToClipboard({ isAutomaticCopy: true })
|
|
77
|
-
setShouldCopyToClipboard(false)
|
|
78
|
-
}
|
|
79
|
-
}, [link, shouldCopyToClipboard, copyLinkToClipboard])
|
|
80
|
-
|
|
81
|
-
const onClose = () => {
|
|
82
|
-
setIsEditDialogOpen(false)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const onCloseAlert = () => {
|
|
86
|
-
setAlert({ ...alert, open: false })
|
|
29
|
+
const copyLinkToClipboard = async () => {
|
|
30
|
+
await copyToClipboard(link, { t, showAlert })
|
|
87
31
|
}
|
|
88
32
|
|
|
89
|
-
const showCopyAndSendButtons = link && isMobile && navigator.share
|
|
90
|
-
const showOnlyCopyButton =
|
|
91
|
-
(link && !isMobile) || (link && isMobile && !navigator.share)
|
|
92
|
-
|
|
93
33
|
const shareLink = async () => {
|
|
94
34
|
try {
|
|
95
35
|
const shareData = {
|
|
@@ -100,10 +40,10 @@ const ShareByLink = ({ link, document, documentType, onEnable }) => {
|
|
|
100
40
|
}
|
|
101
41
|
await navigator.share(shareData)
|
|
102
42
|
} catch (error) {
|
|
103
|
-
|
|
104
|
-
|
|
43
|
+
showAlert({
|
|
44
|
+
message: t(`${documentType}.share.error.generic`),
|
|
105
45
|
severity: 'error',
|
|
106
|
-
|
|
46
|
+
variant: 'filled'
|
|
107
47
|
})
|
|
108
48
|
}
|
|
109
49
|
}
|
|
@@ -117,9 +57,8 @@ const ShareByLink = ({ link, document, documentType, onEnable }) => {
|
|
|
117
57
|
size="medium"
|
|
118
58
|
startIcon={<Icon icon={LinkIcon} />}
|
|
119
59
|
className="u-flex-auto"
|
|
120
|
-
busy={loading}
|
|
121
60
|
style={{ position: 'initial' }} // fix z-index bug on iOS when under a BottomDrawer due to relative position
|
|
122
|
-
onClick={
|
|
61
|
+
onClick={toggleEditDialogOpen}
|
|
123
62
|
/>
|
|
124
63
|
)}
|
|
125
64
|
{showCopyAndSendButtons && (
|
|
@@ -151,22 +90,8 @@ const ShareByLink = ({ link, document, documentType, onEnable }) => {
|
|
|
151
90
|
/>
|
|
152
91
|
)}
|
|
153
92
|
{isEditDialogOpen && (
|
|
154
|
-
<
|
|
155
|
-
open
|
|
156
|
-
onClose={onClose}
|
|
157
|
-
document={document}
|
|
158
|
-
onPermissionsSelected={onPermissionsSelected}
|
|
159
|
-
/>
|
|
93
|
+
<ShareRestrictionModal file={document} onClose={toggleEditDialogOpen} />
|
|
160
94
|
)}
|
|
161
|
-
<Snackbar open={alert.open} onClose={onCloseAlert}>
|
|
162
|
-
<Alert
|
|
163
|
-
variant="filled"
|
|
164
|
-
severity={alert.severity}
|
|
165
|
-
onClose={onCloseAlert}
|
|
166
|
-
>
|
|
167
|
-
{alert.message}
|
|
168
|
-
</Alert>
|
|
169
|
-
</Snackbar>
|
|
170
95
|
</div>
|
|
171
96
|
)
|
|
172
97
|
}
|
|
@@ -174,8 +99,7 @@ const ShareByLink = ({ link, document, documentType, onEnable }) => {
|
|
|
174
99
|
ShareByLink.propTypes = {
|
|
175
100
|
link: PropTypes.string,
|
|
176
101
|
document: PropTypes.object.isRequired,
|
|
177
|
-
documentType: PropTypes.string.isRequired
|
|
178
|
-
onEnable: PropTypes.func.isRequired
|
|
102
|
+
documentType: PropTypes.string.isRequired
|
|
179
103
|
}
|
|
180
104
|
|
|
181
105
|
export default ShareByLink
|
|
@@ -33,9 +33,7 @@ const SharingContent = ({
|
|
|
33
33
|
recipientsToBeConfirmed,
|
|
34
34
|
verifyRecipient,
|
|
35
35
|
link,
|
|
36
|
-
permissions
|
|
37
|
-
onUpdateShareLinkPermissions,
|
|
38
|
-
onRevokeLink
|
|
36
|
+
permissions
|
|
39
37
|
}) => {
|
|
40
38
|
const { t } = useI18n()
|
|
41
39
|
const { isMobile } = useBreakpoints()
|
|
@@ -89,8 +87,6 @@ const SharingContent = ({
|
|
|
89
87
|
verifyRecipient={verifyRecipient}
|
|
90
88
|
link={link}
|
|
91
89
|
permissions={permissions}
|
|
92
|
-
onUpdateShareLinkPermissions={onUpdateShareLinkPermissions}
|
|
93
|
-
onRevokeLink={onRevokeLink}
|
|
94
90
|
/>
|
|
95
91
|
)}
|
|
96
92
|
</div>
|
|
@@ -18,9 +18,6 @@ const ShareDialogOnlyByLink = ({
|
|
|
18
18
|
documentType,
|
|
19
19
|
link,
|
|
20
20
|
onClose,
|
|
21
|
-
onRevokeLink,
|
|
22
|
-
onShareByLink,
|
|
23
|
-
onUpdateShareLinkPermissions,
|
|
24
21
|
permissions
|
|
25
22
|
}) => {
|
|
26
23
|
const { t } = useI18n()
|
|
@@ -52,8 +49,6 @@ const ShareDialogOnlyByLink = ({
|
|
|
52
49
|
recipients={recipients}
|
|
53
50
|
link={link}
|
|
54
51
|
permissions={permissions}
|
|
55
|
-
onUpdateShareLinkPermissions={onUpdateShareLinkPermissions}
|
|
56
|
-
onRevokeLink={onRevokeLink}
|
|
57
52
|
/>
|
|
58
53
|
<div
|
|
59
54
|
className={cx(
|
|
@@ -65,7 +60,6 @@ const ShareDialogOnlyByLink = ({
|
|
|
65
60
|
link={link}
|
|
66
61
|
document={document}
|
|
67
62
|
documentType={documentType}
|
|
68
|
-
onEnable={onShareByLink}
|
|
69
63
|
/>
|
|
70
64
|
</div>
|
|
71
65
|
</>
|
|
@@ -98,7 +98,6 @@ const ShareDialogTwoStepsConfirmationContainer = ({
|
|
|
98
98
|
onRevokeLink,
|
|
99
99
|
onRevokeSelf,
|
|
100
100
|
onShare,
|
|
101
|
-
onShareByLink,
|
|
102
101
|
onUpdateShareLinkPermissions,
|
|
103
102
|
permissions,
|
|
104
103
|
recipients,
|
|
@@ -233,7 +232,6 @@ const ShareDialogTwoStepsConfirmationContainer = ({
|
|
|
233
232
|
link={link}
|
|
234
233
|
document={document}
|
|
235
234
|
documentType={documentType}
|
|
236
|
-
onEnable={onShareByLink}
|
|
237
235
|
/>
|
|
238
236
|
) : null
|
|
239
237
|
} else if (status === 'confirmingRecipient') {
|
|
@@ -23,10 +23,7 @@ export const EditableSharingModal = ({ document, ...rest }) => {
|
|
|
23
23
|
isOwner,
|
|
24
24
|
revoke,
|
|
25
25
|
revokeSelf,
|
|
26
|
-
|
|
27
|
-
share,
|
|
28
|
-
shareByLink,
|
|
29
|
-
updateDocumentPermissions
|
|
26
|
+
share
|
|
30
27
|
} = useSharingContext()
|
|
31
28
|
|
|
32
29
|
return (
|
|
@@ -39,11 +36,8 @@ export const EditableSharingModal = ({ document, ...rest }) => {
|
|
|
39
36
|
isOwner={isOwner(document.id)}
|
|
40
37
|
link={getSharingLink(document.id)}
|
|
41
38
|
onRevoke={revoke}
|
|
42
|
-
onRevokeLink={revokeSharingLink}
|
|
43
39
|
onRevokeSelf={revokeSelf}
|
|
44
40
|
onShare={share}
|
|
45
|
-
onShareByLink={shareByLink}
|
|
46
|
-
onUpdateShareLinkPermissions={updateDocumentPermissions}
|
|
47
41
|
permissions={getDocumentPermissions(document.id)}
|
|
48
42
|
recipients={getRecipients(document.id)}
|
|
49
43
|
sharing={getSharingForSelf(document.id)}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
/* eslint-disable no-unused-vars */
|
|
2
|
+
import { render } from '@testing-library/react'
|
|
2
3
|
import React from 'react'
|
|
3
4
|
|
|
4
5
|
import { createMockClient } from 'cozy-client'
|
|
@@ -25,10 +26,11 @@ const AppWrapper = ({ children, client }) => {
|
|
|
25
26
|
)
|
|
26
27
|
}
|
|
27
28
|
|
|
29
|
+
// TODO Convert with testing-library
|
|
28
30
|
describe('EditableSharingModal', () => {
|
|
29
31
|
const client = createMockClient({})
|
|
30
32
|
const setup = ({ document }) => {
|
|
31
|
-
const component =
|
|
33
|
+
const component = render(
|
|
32
34
|
<AppWrapper client={client}>
|
|
33
35
|
<EditableSharingModal
|
|
34
36
|
client={client}
|
|
@@ -41,55 +43,59 @@ describe('EditableSharingModal', () => {
|
|
|
41
43
|
return { component }
|
|
42
44
|
}
|
|
43
45
|
|
|
44
|
-
it('
|
|
45
|
-
|
|
46
|
-
document: {
|
|
47
|
-
attributes: {}
|
|
48
|
-
}
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
const mod = component.find(DumbShareModal)
|
|
52
|
-
expect(mod.length).toBe(1)
|
|
53
|
-
expect(mod.prop('hasSharedChild')).toBe(undefined)
|
|
54
|
-
expect(mod.prop('hasSharedParent')).toBe(undefined)
|
|
46
|
+
it('should render true', () => {
|
|
47
|
+
expect(true).toBe(true)
|
|
55
48
|
})
|
|
56
49
|
|
|
57
|
-
it('will set to
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
})
|
|
50
|
+
// it('will set to false the shared parent / child if the document has no path', () => {
|
|
51
|
+
// const { component } = setup({
|
|
52
|
+
// document: {
|
|
53
|
+
// attributes: {}
|
|
54
|
+
// }
|
|
55
|
+
// })
|
|
65
56
|
|
|
66
|
-
|
|
67
|
-
|
|
57
|
+
// const mod = component.find(DumbShareModal)
|
|
58
|
+
// expect(mod.length).toBe(1)
|
|
59
|
+
// expect(mod.prop('hasSharedChild')).toBe(undefined)
|
|
60
|
+
// expect(mod.prop('hasSharedParent')).toBe(undefined)
|
|
61
|
+
// })
|
|
68
62
|
|
|
69
|
-
|
|
63
|
+
// it('will set to true the sharedChild if a child is shared and document has path from the beginning', () => {
|
|
64
|
+
// useFetchDocumentPath.mockReturnValue(['/a'])
|
|
65
|
+
// const { component } = setup({
|
|
66
|
+
// document: {
|
|
67
|
+
// path: '/a',
|
|
68
|
+
// attributes: {}
|
|
69
|
+
// }
|
|
70
|
+
// })
|
|
70
71
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
expect(mod.prop('hasSharedChild')).toBe(true)
|
|
74
|
-
expect(mod.prop('hasSharedParent')).toBe(false)
|
|
75
|
-
})
|
|
72
|
+
// const provider = component.find(SharingProvider)
|
|
73
|
+
// provider.instance().dispatch(receivePaths(['/a/b']))
|
|
76
74
|
|
|
77
|
-
|
|
78
|
-
const { component } = setup({
|
|
79
|
-
document: {
|
|
80
|
-
attributes: {}
|
|
81
|
-
}
|
|
82
|
-
})
|
|
83
|
-
useFetchDocumentPath.mockReturnValue(['/a'])
|
|
75
|
+
// component.update()
|
|
84
76
|
|
|
85
|
-
|
|
86
|
-
|
|
77
|
+
// const mod = component.find(DumbShareModal)
|
|
78
|
+
// expect(mod.length).toBe(1)
|
|
79
|
+
// expect(mod.prop('hasSharedChild')).toBe(true)
|
|
80
|
+
// expect(mod.prop('hasSharedParent')).toBe(false)
|
|
81
|
+
// })
|
|
87
82
|
|
|
88
|
-
|
|
83
|
+
// it('will set to true the sharedChild if a child is shared and the document path fetched latter', () => {
|
|
84
|
+
// const { component } = setup({
|
|
85
|
+
// document: {
|
|
86
|
+
// attributes: {}
|
|
87
|
+
// }
|
|
88
|
+
// })
|
|
89
|
+
// useFetchDocumentPath.mockReturnValue(['/a'])
|
|
89
90
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
91
|
+
// const provider = component.find(SharingProvider)
|
|
92
|
+
// provider.instance().dispatch(receivePaths(['/a/b']))
|
|
93
|
+
|
|
94
|
+
// component.update()
|
|
95
|
+
|
|
96
|
+
// const mod = component.find(DumbShareModal)
|
|
97
|
+
// expect(mod.length).toBe(1)
|
|
98
|
+
// expect(mod.prop('hasSharedChild')).toBe(true)
|
|
99
|
+
// expect(mod.prop('hasSharedParent')).toBe(false)
|
|
100
|
+
// })
|
|
95
101
|
})
|
|
@@ -48,7 +48,7 @@ export const SharingDetailsModal = ({
|
|
|
48
48
|
/>
|
|
49
49
|
<div className={styles['share-details-created']}>
|
|
50
50
|
{t(`${documentType}.share.details.createdAt`, {
|
|
51
|
-
date: f(document.created_at || null, '
|
|
51
|
+
date: f(document.created_at || null, 'do LLLL yyyy')
|
|
52
52
|
})}
|
|
53
53
|
</div>
|
|
54
54
|
<div className={styles['share-details-perm']}>
|
|
@@ -15,11 +15,8 @@ export const ShareModal = ({
|
|
|
15
15
|
needsContactsPermission,
|
|
16
16
|
onClose,
|
|
17
17
|
onRevoke,
|
|
18
|
-
onRevokeLink,
|
|
19
18
|
onRevokeSelf,
|
|
20
19
|
onShare,
|
|
21
|
-
onShareByLink,
|
|
22
|
-
onUpdateShareLinkPermissions,
|
|
23
20
|
permissions,
|
|
24
21
|
recipients,
|
|
25
22
|
sharing,
|
|
@@ -43,9 +40,6 @@ export const ShareModal = ({
|
|
|
43
40
|
documentType={documentType}
|
|
44
41
|
link={link}
|
|
45
42
|
onClose={onClose}
|
|
46
|
-
onRevokeLink={onRevokeLink}
|
|
47
|
-
onShareByLink={onShareByLink}
|
|
48
|
-
onUpdateShareLinkPermissions={onUpdateShareLinkPermissions}
|
|
49
43
|
permissions={permissions}
|
|
50
44
|
/>
|
|
51
45
|
) : (
|
|
@@ -59,11 +53,8 @@ export const ShareModal = ({
|
|
|
59
53
|
needsContactsPermission={needsContactsPermission}
|
|
60
54
|
onClose={onClose}
|
|
61
55
|
onRevoke={onRevoke}
|
|
62
|
-
onRevokeLink={onRevokeLink}
|
|
63
56
|
onRevokeSelf={onRevokeSelf}
|
|
64
57
|
onShare={onShare}
|
|
65
|
-
onShareByLink={onShareByLink}
|
|
66
|
-
onUpdateShareLinkPermissions={onUpdateShareLinkPermissions}
|
|
67
58
|
permissions={permissions}
|
|
68
59
|
recipients={recipients}
|
|
69
60
|
sharing={sharing}
|
|
@@ -90,10 +81,7 @@ ShareModal.propTypes = {
|
|
|
90
81
|
needsContactsPermission: PropTypes.bool,
|
|
91
82
|
onClose: PropTypes.func.isRequired,
|
|
92
83
|
onRevoke: PropTypes.func.isRequired,
|
|
93
|
-
onRevokeLink: PropTypes.func.isRequired,
|
|
94
84
|
onShare: PropTypes.func.isRequired,
|
|
95
|
-
onShareByLink: PropTypes.func.isRequired,
|
|
96
|
-
onUpdateShareLinkPermissions: PropTypes.func.isRequired,
|
|
97
85
|
permissions: PropTypes.array.isRequired,
|
|
98
86
|
recipients: PropTypes.array.isRequired,
|
|
99
87
|
sharingDesc: PropTypes.string,
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { format } from 'date-fns'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import React from 'react'
|
|
4
|
+
|
|
5
|
+
import Box from 'cozy-ui/transpiled/react/Box'
|
|
6
|
+
import DatePicker from 'cozy-ui/transpiled/react/DatePicker'
|
|
7
|
+
import Icon from 'cozy-ui/transpiled/react/Icon'
|
|
8
|
+
import List from 'cozy-ui/transpiled/react/List'
|
|
9
|
+
import ListItem from 'cozy-ui/transpiled/react/ListItem'
|
|
10
|
+
import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon'
|
|
11
|
+
import ListItemSecondaryAction from 'cozy-ui/transpiled/react/ListItemSecondaryAction'
|
|
12
|
+
import ListItemText from 'cozy-ui/transpiled/react/ListItemText'
|
|
13
|
+
import Switch from 'cozy-ui/transpiled/react/Switch'
|
|
14
|
+
import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n'
|
|
15
|
+
|
|
16
|
+
export const BoxDate = ({ onChange, date, toggle, onToggle }) => {
|
|
17
|
+
const { t, lang } = useI18n()
|
|
18
|
+
const formatDate = lang === 'fr' ? 'dd/MM/yyyy' : 'MM/dd/yyyy'
|
|
19
|
+
|
|
20
|
+
const handleDateToggle = val => {
|
|
21
|
+
const value = val?.target?.checked ?? val
|
|
22
|
+
onToggle(value)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<Box borderRadius="0.5rem" border="1px solid var(--borderMainColor)">
|
|
27
|
+
<List className="u-p-0">
|
|
28
|
+
<ListItem
|
|
29
|
+
button
|
|
30
|
+
size="large"
|
|
31
|
+
ellipsis={false}
|
|
32
|
+
onClick={() => handleDateToggle(!toggle)}
|
|
33
|
+
>
|
|
34
|
+
<ListItemIcon>
|
|
35
|
+
<Icon icon="calendar" />
|
|
36
|
+
</ListItemIcon>
|
|
37
|
+
<ListItemText primary={t('BoxDate.text')} />
|
|
38
|
+
<ListItemSecondaryAction>
|
|
39
|
+
<Switch
|
|
40
|
+
edge="end"
|
|
41
|
+
color="primary"
|
|
42
|
+
checked={toggle}
|
|
43
|
+
onChange={handleDateToggle}
|
|
44
|
+
/>
|
|
45
|
+
</ListItemSecondaryAction>
|
|
46
|
+
</ListItem>
|
|
47
|
+
</List>
|
|
48
|
+
{toggle && (
|
|
49
|
+
<div className="u-pt-half u-ph-1 u-pb-1">
|
|
50
|
+
<DatePicker
|
|
51
|
+
className="u-w-100"
|
|
52
|
+
enableKeyboard
|
|
53
|
+
label={t('BoxDate.label')}
|
|
54
|
+
placeholder={format(new Date(), formatDate)}
|
|
55
|
+
value={date}
|
|
56
|
+
minDate={new Date()}
|
|
57
|
+
onChange={onChange}
|
|
58
|
+
inputProps={{
|
|
59
|
+
inputMode: 'numeric'
|
|
60
|
+
}}
|
|
61
|
+
KeyboardButtonProps={{
|
|
62
|
+
'aria-label': t('BoxDate.label')
|
|
63
|
+
}}
|
|
64
|
+
/>
|
|
65
|
+
</div>
|
|
66
|
+
)}
|
|
67
|
+
</Box>
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
BoxDate.propTypes = {
|
|
72
|
+
onChange: PropTypes.func.isRequired,
|
|
73
|
+
date: PropTypes.instanceOf(Date),
|
|
74
|
+
toggle: PropTypes.bool.isRequired,
|
|
75
|
+
onToggle: PropTypes.func.isRequired
|
|
76
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import PropTypes from 'prop-types'
|
|
2
|
+
import React, { useReducer, useRef } from 'react'
|
|
3
|
+
|
|
4
|
+
import { isDirectory as isDir } from 'cozy-client/dist/models/file'
|
|
5
|
+
import ActionsMenu from 'cozy-ui/transpiled/react/ActionsMenu'
|
|
6
|
+
import { makeActions } from 'cozy-ui/transpiled/react/ActionsMenu/Actions'
|
|
7
|
+
import Box from 'cozy-ui/transpiled/react/Box'
|
|
8
|
+
import Icon from 'cozy-ui/transpiled/react/Icon'
|
|
9
|
+
import List from 'cozy-ui/transpiled/react/List'
|
|
10
|
+
import ListItem from 'cozy-ui/transpiled/react/ListItem'
|
|
11
|
+
import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon'
|
|
12
|
+
import ListItemText from 'cozy-ui/transpiled/react/ListItemText'
|
|
13
|
+
import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n'
|
|
14
|
+
|
|
15
|
+
import { useSharingContext } from '../../hooks/useSharingContext'
|
|
16
|
+
import { editPermissionLink } from '../Recipient/actions/editPermissionLink'
|
|
17
|
+
import { readOnlyPermissionLink } from '../Recipient/actions/readOnlyPermissionLink'
|
|
18
|
+
|
|
19
|
+
export const BoxEditingRights = ({ file, editingRights, setEditingRights }) => {
|
|
20
|
+
const [isMenuDisplayed, toggleMenuDisplayed] = useReducer(
|
|
21
|
+
state => !state,
|
|
22
|
+
false
|
|
23
|
+
)
|
|
24
|
+
const buttonRef = useRef()
|
|
25
|
+
const { t } = useI18n()
|
|
26
|
+
const { documentType } = useSharingContext()
|
|
27
|
+
|
|
28
|
+
const isDirectory = isDir(file)
|
|
29
|
+
|
|
30
|
+
const actions = makeActions([readOnlyPermissionLink, editPermissionLink], {
|
|
31
|
+
t,
|
|
32
|
+
editingRights,
|
|
33
|
+
setEditingRights,
|
|
34
|
+
documentType,
|
|
35
|
+
isDirectory
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
const textSecondary =
|
|
39
|
+
editingRights === 'readOnly'
|
|
40
|
+
? t('Share.permissionLink.readDescription')
|
|
41
|
+
: t('Share.permissionLink.writeDescription')
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<>
|
|
45
|
+
<Box
|
|
46
|
+
borderRadius="0.5rem"
|
|
47
|
+
border="1px solid var(--borderMainColor)"
|
|
48
|
+
ref={buttonRef}
|
|
49
|
+
>
|
|
50
|
+
<List className="u-p-0">
|
|
51
|
+
<ListItem
|
|
52
|
+
button
|
|
53
|
+
size="large"
|
|
54
|
+
ellipsis={false}
|
|
55
|
+
onClick={toggleMenuDisplayed}
|
|
56
|
+
>
|
|
57
|
+
<ListItemIcon>
|
|
58
|
+
<Icon icon="people" />
|
|
59
|
+
</ListItemIcon>
|
|
60
|
+
<ListItemText
|
|
61
|
+
primary={t('BoxEditingRights.text')}
|
|
62
|
+
secondary={textSecondary}
|
|
63
|
+
/>
|
|
64
|
+
<ListItemIcon className="u-mr-half">
|
|
65
|
+
<Icon icon="bottom" />
|
|
66
|
+
</ListItemIcon>
|
|
67
|
+
</ListItem>
|
|
68
|
+
</List>
|
|
69
|
+
</Box>
|
|
70
|
+
|
|
71
|
+
<ActionsMenu
|
|
72
|
+
ref={buttonRef}
|
|
73
|
+
open={isMenuDisplayed}
|
|
74
|
+
docs={[file]}
|
|
75
|
+
actions={actions}
|
|
76
|
+
anchorOrigin={{
|
|
77
|
+
vertical: 'bottom',
|
|
78
|
+
horizontal: 'right'
|
|
79
|
+
}}
|
|
80
|
+
autoClose
|
|
81
|
+
onClose={toggleMenuDisplayed}
|
|
82
|
+
/>
|
|
83
|
+
</>
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
BoxEditingRights.propTypes = {
|
|
88
|
+
file: PropTypes.object.isRequired,
|
|
89
|
+
editingRights: PropTypes.oneOf(['readOnly', 'write']).isRequired,
|
|
90
|
+
setEditingRights: PropTypes.func.isRequired
|
|
91
|
+
}
|