cozy-sharing 37.0.2 → 37.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.
- package/CHANGELOG.md +20 -0
- package/dist/OpenSharingLinkButton.js +1 -1
- package/dist/SharingProvider.js +315 -138
- package/dist/SharingProvider.spec.js +454 -240
- package/dist/actions/addToCozySharingLink.js +1 -1
- package/dist/actions/createCozySharingLink.js +1 -1
- package/dist/actions/shareNative.js +1 -1
- package/dist/actions/syncToCozySharingLink.js +1 -1
- package/dist/components/Avatar/AvatarList.js +1 -1
- package/dist/components/Recipient/GroupRecipient.js +0 -2
- package/dist/components/Recipient/GroupRecipientDetail.js +2 -25
- package/dist/components/Recipient/GroupRecipientDetailWithoutAccess.js +1 -1
- package/dist/components/Recipient/LinkRecipient.js +1 -1
- package/dist/components/Recipient/LinkRecipientLite.js +1 -1
- package/dist/components/Recipient/actions/revokeLink.js +1 -1
- package/dist/components/ShareAutosuggest.js +6 -6
- package/dist/components/ShareButton.js +1 -1
- package/dist/components/ShareByLink.js +1 -1
- package/dist/components/ShareLinkAccessModal/ShareLinkAccessModal.js +316 -0
- package/dist/components/ShareLinkAccessModal/ShareLinkAccessModal.spec.js +372 -0
- package/dist/components/ShareLinkAccessModal/index.js +1 -0
- package/dist/components/ShareRestrictionModal/BoxDate.js +1 -1
- package/dist/components/ShareRestrictionModal/BoxEditingRights.js +1 -1
- package/dist/components/ShareRestrictionModal/BoxPassword.js +1 -1
- package/dist/components/ShareRestrictionModal/ShareRestrictionModal.js +1 -1
- package/dist/components/ShareRestrictionModal/helpers.js +36 -18
- package/dist/components/ShareRestrictionModal/helpers.spec.js +3 -3
- package/dist/components/SharedBadge.js +1 -1
- package/dist/components/SharedDrive/SharedDriveHeader.js +1 -1
- package/dist/index.js +1 -0
- package/locales/en.json +21 -3
- package/locales/fr.json +22 -4
- package/locales/ru.json +21 -3
- package/locales/vi.json +21 -3
- package/package.json +3 -3
- package/src/OpenSharingLinkButton.jsx +1 -1
- package/src/SharingProvider.jsx +91 -27
- package/src/SharingProvider.spec.jsx +212 -60
- package/src/actions/addToCozySharingLink.js +1 -1
- package/src/actions/createCozySharingLink.js +1 -1
- package/src/actions/shareNative.js +1 -1
- package/src/actions/syncToCozySharingLink.js +1 -1
- package/src/components/Avatar/AvatarList.jsx +1 -1
- package/src/components/Recipient/GroupRecipient.jsx +1 -2
- package/src/components/Recipient/GroupRecipientDetail.jsx +3 -33
- package/src/components/Recipient/GroupRecipientDetailWithoutAccess.jsx +1 -1
- package/src/components/Recipient/LinkRecipient.jsx +1 -1
- package/src/components/Recipient/LinkRecipientLite.jsx +1 -1
- package/src/components/Recipient/actions/revokeLink.js +1 -1
- package/src/components/ShareAutosuggest.jsx +3 -4
- package/src/components/ShareButton.jsx +1 -1
- package/src/components/ShareByLink.jsx +1 -1
- package/src/components/ShareLinkAccessModal/ShareLinkAccessModal.jsx +293 -0
- package/src/components/ShareLinkAccessModal/ShareLinkAccessModal.spec.jsx +291 -0
- package/src/components/ShareLinkAccessModal/index.js +1 -0
- package/src/components/ShareRestrictionModal/BoxDate.jsx +1 -1
- package/src/components/ShareRestrictionModal/BoxEditingRights.jsx +1 -1
- package/src/components/ShareRestrictionModal/BoxPassword.jsx +1 -1
- package/src/components/ShareRestrictionModal/ShareRestrictionModal.jsx +1 -1
- package/src/components/ShareRestrictionModal/helpers.js +30 -6
- package/src/components/ShareRestrictionModal/helpers.spec.js +3 -3
- package/src/components/SharedBadge.jsx +2 -1
- package/src/components/SharedDrive/SharedDriveHeader.jsx +1 -1
- package/src/helpers/sharings.js +0 -1
- package/src/index.jsx +1 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Icon, ToTheCloud } from '@linagora/twake-icons'
|
|
2
1
|
import React, { forwardRef } from 'react'
|
|
3
2
|
|
|
3
|
+
import { Icon, ToTheCloud } from '@linagora/twake-icons'
|
|
4
4
|
import ActionsMenuItem from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem'
|
|
5
5
|
import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon'
|
|
6
6
|
import ListItemText from 'cozy-ui/transpiled/react/ListItemText'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Icon, Reply } from '@linagora/twake-icons'
|
|
2
1
|
import React, { forwardRef } from 'react'
|
|
3
2
|
|
|
3
|
+
import { Icon, Reply } from '@linagora/twake-icons'
|
|
4
4
|
import ActionsMenuItem from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem'
|
|
5
5
|
import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon'
|
|
6
6
|
import ListItemText from 'cozy-ui/transpiled/react/ListItemText'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Icon, Sync } from '@linagora/twake-icons'
|
|
2
1
|
import React, { forwardRef } from 'react'
|
|
3
2
|
|
|
3
|
+
import { Icon, Sync } from '@linagora/twake-icons'
|
|
4
4
|
import ActionsMenuItem from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem'
|
|
5
5
|
import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon'
|
|
6
6
|
import ListItemText from 'cozy-ui/transpiled/react/ListItemText'
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
import { GroupAvatar } from '../Avatar/GroupAvatar'
|
|
20
20
|
|
|
21
21
|
const GroupRecipient = props => {
|
|
22
|
-
const { name, color, members, fadeIn,
|
|
22
|
+
const { name, color, members, fadeIn, isOwner } = props
|
|
23
23
|
const { t } = useI18n()
|
|
24
24
|
const client = useClient()
|
|
25
25
|
const { isMobile } = useBreakpoints()
|
|
@@ -74,7 +74,6 @@ const GroupRecipient = props => {
|
|
|
74
74
|
{isDetailOpened ? (
|
|
75
75
|
<GroupRecipientDetail
|
|
76
76
|
isOwner={isOwner}
|
|
77
|
-
owner={owner}
|
|
78
77
|
name={name}
|
|
79
78
|
members={members}
|
|
80
79
|
onClose={closeDetail}
|
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
|
|
3
|
-
import { useClient, generateWebLink } from 'cozy-client'
|
|
4
|
-
import Buttons from 'cozy-ui/transpiled/react/Buttons'
|
|
5
3
|
import { Dialog } from 'cozy-ui/transpiled/react/CozyDialogs'
|
|
6
4
|
import Empty from 'cozy-ui/transpiled/react/Empty'
|
|
7
|
-
import Typography from 'cozy-ui/transpiled/react/Typography'
|
|
8
5
|
import { useI18n } from 'twake-i18n'
|
|
9
6
|
|
|
10
7
|
import { GroupRecipientDetailWithAccess } from './GroupRecipientDetailWithAccess'
|
|
11
8
|
import { GroupRecipientDetailWithoutAccess } from './GroupRecipientDetailWithoutAccess'
|
|
12
9
|
|
|
13
|
-
const GroupRecipientDetail = ({ name,
|
|
14
|
-
const client = useClient()
|
|
10
|
+
const GroupRecipientDetail = ({ name, members, onClose, isOwner }) => {
|
|
15
11
|
const { t } = useI18n()
|
|
16
12
|
const withAccess = members.filter(
|
|
17
13
|
member => !['revoked', 'mail-not-sent'].includes(member.status)
|
|
@@ -20,42 +16,16 @@ const GroupRecipientDetail = ({ name, owner, members, onClose, isOwner }) => {
|
|
|
20
16
|
['revoked', 'mail-not-sent'].includes(member.status)
|
|
21
17
|
)
|
|
22
18
|
|
|
23
|
-
const ownerName = owner.public_name
|
|
24
|
-
const contactsLink = generateWebLink({
|
|
25
|
-
cozyUrl: client.getStackClient().uri,
|
|
26
|
-
slug: 'contacts',
|
|
27
|
-
pathname: '/',
|
|
28
|
-
subDomainType: client.getInstanceOptions().subdomain
|
|
29
|
-
})
|
|
30
|
-
|
|
31
19
|
return (
|
|
32
20
|
<Dialog
|
|
33
21
|
open
|
|
34
22
|
size="small"
|
|
35
23
|
onClose={onClose}
|
|
36
|
-
title={
|
|
37
|
-
<>
|
|
38
|
-
{name}
|
|
39
|
-
{ownerName ? (
|
|
40
|
-
<Typography variant="caption">
|
|
41
|
-
{t('GroupRecipientDetail.subtitle', { ownerName })}
|
|
42
|
-
</Typography>
|
|
43
|
-
) : null}
|
|
44
|
-
</>
|
|
45
|
-
}
|
|
24
|
+
title={name}
|
|
46
25
|
content={
|
|
47
26
|
<div className="u-flex u-stack-xs u-flex-column">
|
|
48
27
|
{members.length === 0 ? (
|
|
49
|
-
<Empty text={t('GroupRecipientDetail.empty.content')}
|
|
50
|
-
<Buttons
|
|
51
|
-
component="a"
|
|
52
|
-
className="u-mt-1"
|
|
53
|
-
href={contactsLink}
|
|
54
|
-
target="_blank"
|
|
55
|
-
rel="noopener noreferrer"
|
|
56
|
-
label={t('GroupRecipientDetail.empty.action')}
|
|
57
|
-
/>
|
|
58
|
-
</Empty>
|
|
28
|
+
<Empty text={t('GroupRecipientDetail.empty.content')} />
|
|
59
29
|
) : null}
|
|
60
30
|
{withAccess.length > 0 ? (
|
|
61
31
|
<GroupRecipientDetailWithAccess withAccess={withAccess} />
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Icon, Forbidden } from '@linagora/twake-icons'
|
|
2
1
|
import React from 'react'
|
|
3
2
|
|
|
3
|
+
import { Icon, Forbidden } from '@linagora/twake-icons'
|
|
4
4
|
import Avatar from 'cozy-ui/transpiled/react/Avatar'
|
|
5
5
|
import List from 'cozy-ui/transpiled/react/List'
|
|
6
6
|
import ListItem from 'cozy-ui/transpiled/react/ListItem'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Icon, Gear, Link } from '@linagora/twake-icons'
|
|
2
1
|
import PropTypes from 'prop-types'
|
|
3
2
|
import React, { useState } from 'react'
|
|
4
3
|
|
|
4
|
+
import { Icon, Gear, Link } from '@linagora/twake-icons'
|
|
5
5
|
import Avatar from 'cozy-ui/transpiled/react/Avatar'
|
|
6
6
|
import Fade from 'cozy-ui/transpiled/react/Fade'
|
|
7
7
|
import IconButton from 'cozy-ui/transpiled/react/IconButton'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Icon, Link } from '@linagora/twake-icons'
|
|
2
1
|
import PropTypes from 'prop-types'
|
|
3
2
|
import React from 'react'
|
|
4
3
|
|
|
4
|
+
import { Icon, Link } from '@linagora/twake-icons'
|
|
5
5
|
import Avatar from 'cozy-ui/transpiled/react/Avatar'
|
|
6
6
|
import ListItem from 'cozy-ui/transpiled/react/ListItem'
|
|
7
7
|
import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Icon, Trash } from '@linagora/twake-icons'
|
|
2
1
|
import React, { forwardRef } from 'react'
|
|
3
2
|
|
|
3
|
+
import { Icon, Trash } from '@linagora/twake-icons'
|
|
4
4
|
import ActionsMenuItem from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem'
|
|
5
5
|
import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon'
|
|
6
6
|
import ListItemText from 'cozy-ui/transpiled/react/ListItemText'
|
|
@@ -2,15 +2,15 @@ import PropTypes from 'prop-types'
|
|
|
2
2
|
import React, { useState, useRef } from 'react'
|
|
3
3
|
import Autosuggest from 'react-autosuggest'
|
|
4
4
|
|
|
5
|
-
import Avatar from 'cozy-ui/transpiled/react/Avatar'
|
|
6
5
|
import Chip from 'cozy-ui/transpiled/react/Chips'
|
|
7
6
|
import { Spinner } from 'cozy-ui/transpiled/react/Spinner'
|
|
8
7
|
|
|
9
8
|
import { GroupAvatar } from './Avatar/GroupAvatar'
|
|
9
|
+
import { MemberAvatar } from './Avatar/MemberAvatar'
|
|
10
10
|
import ContactSuggestion from './ContactSuggestion'
|
|
11
11
|
import { isContactToBeCreated } from '../helpers/contacts'
|
|
12
12
|
import { extractEmails, validateEmail } from '../helpers/email'
|
|
13
|
-
import { getDisplayName,
|
|
13
|
+
import { getDisplayName, Contact, Group } from '../models'
|
|
14
14
|
import styles from '../styles/autosuggest.styl'
|
|
15
15
|
import { contactOrGroupMatch } from '../suggestionMatchers'
|
|
16
16
|
|
|
@@ -153,7 +153,6 @@ const ShareAutosuggest = ({
|
|
|
153
153
|
<div className={styles['recipientsContainer']}>
|
|
154
154
|
{recipients.map((recipient, idx) => {
|
|
155
155
|
const isContactGroup = recipient._type === Group.doctype
|
|
156
|
-
const avatarText = getInitials(recipient)
|
|
157
156
|
const name = getDisplayName(recipient)
|
|
158
157
|
return (
|
|
159
158
|
<Chip
|
|
@@ -163,7 +162,7 @@ const ShareAutosuggest = ({
|
|
|
163
162
|
isContactGroup ? (
|
|
164
163
|
<GroupAvatar size="xs" color={recipient.color} />
|
|
165
164
|
) : (
|
|
166
|
-
<
|
|
165
|
+
<MemberAvatar size="xs" recipient={recipient} />
|
|
167
166
|
)
|
|
168
167
|
}
|
|
169
168
|
label={name}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Icon, Share } from '@linagora/twake-icons'
|
|
2
1
|
import classNames from 'classnames'
|
|
3
2
|
import React from 'react'
|
|
4
3
|
|
|
4
|
+
import { Icon, Share } from '@linagora/twake-icons'
|
|
5
5
|
import Button from 'cozy-ui/transpiled/react/Buttons'
|
|
6
6
|
|
|
7
7
|
import styles from '../styles/button.styl'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Icon, Copy, Link } from '@linagora/twake-icons'
|
|
2
1
|
import PropTypes from 'prop-types'
|
|
3
2
|
import React, { useReducer, useState } from 'react'
|
|
4
3
|
|
|
4
|
+
import { Icon, Copy, Link } from '@linagora/twake-icons'
|
|
5
5
|
import { useClient } from 'cozy-client'
|
|
6
6
|
import Button from 'cozy-ui/transpiled/react/Buttons'
|
|
7
7
|
import { useAlert } from 'cozy-ui/transpiled/react/providers/Alert'
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import { addDays } from 'date-fns'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import React, { useState } from 'react'
|
|
4
|
+
|
|
5
|
+
import { Icon, Link as LinkIcon, Settings } from '@linagora/twake-icons'
|
|
6
|
+
import Alert from 'cozy-ui/transpiled/react/Alert'
|
|
7
|
+
import Box from 'cozy-ui/transpiled/react/Box'
|
|
8
|
+
import Button from 'cozy-ui/transpiled/react/Buttons'
|
|
9
|
+
import Chip from 'cozy-ui/transpiled/react/Chips'
|
|
10
|
+
import { ConfirmDialog } from 'cozy-ui/transpiled/react/CozyDialogs'
|
|
11
|
+
import DatePicker from 'cozy-ui/transpiled/react/DatePicker'
|
|
12
|
+
import DropdownButton from 'cozy-ui/transpiled/react/DropdownButton'
|
|
13
|
+
import FormControlLabel from 'cozy-ui/transpiled/react/FormControlLabel'
|
|
14
|
+
import Grid from 'cozy-ui/transpiled/react/Grid'
|
|
15
|
+
import IconButton from 'cozy-ui/transpiled/react/IconButton'
|
|
16
|
+
import Menu from 'cozy-ui/transpiled/react/Menu'
|
|
17
|
+
import MenuItem from 'cozy-ui/transpiled/react/MenuItem'
|
|
18
|
+
import Switch from 'cozy-ui/transpiled/react/Switch'
|
|
19
|
+
import TextField from 'cozy-ui/transpiled/react/TextField'
|
|
20
|
+
import Typography from 'cozy-ui/transpiled/react/Typography'
|
|
21
|
+
import { useI18n } from 'twake-i18n'
|
|
22
|
+
|
|
23
|
+
import withLocales from '../../hoc/withLocales'
|
|
24
|
+
import { useSharingContext } from '../../hooks/useSharingContext'
|
|
25
|
+
|
|
26
|
+
const DIALOG_CLASSES = { paper: 'u-h-auto' }
|
|
27
|
+
const DOCUMENT_ICON_SIZE = 18
|
|
28
|
+
const PASSWORD_MIN_LENGTH = 4
|
|
29
|
+
|
|
30
|
+
export const ShareLinkAccessModal = ({
|
|
31
|
+
documents,
|
|
32
|
+
onCancel,
|
|
33
|
+
onSuccess,
|
|
34
|
+
renderDocumentIcon
|
|
35
|
+
}) => {
|
|
36
|
+
const { t } = useI18n()
|
|
37
|
+
const { ensureSharingLink } = useSharingContext()
|
|
38
|
+
const [editingRights, setEditingRights] = useState('readOnly')
|
|
39
|
+
const [accessAnchorEl, setAccessAnchorEl] = useState(null)
|
|
40
|
+
const [isSettingsOpen, setIsSettingsOpen] = useState(false)
|
|
41
|
+
const [dateEnabled, setDateEnabled] = useState(false)
|
|
42
|
+
const [selectedDate, setSelectedDate] = useState(null)
|
|
43
|
+
const [passwordEnabled, setPasswordEnabled] = useState(false)
|
|
44
|
+
const [password, setPassword] = useState('')
|
|
45
|
+
const [busy, setBusy] = useState(false)
|
|
46
|
+
const [error, setError] = useState(null)
|
|
47
|
+
|
|
48
|
+
const isPasswordValid =
|
|
49
|
+
!passwordEnabled || password.trim().length >= PASSWORD_MIN_LENGTH
|
|
50
|
+
const handleAccessMenuClose = () => {
|
|
51
|
+
setAccessAnchorEl(null)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const handleDateEnabledChange = event => {
|
|
55
|
+
setDateEnabled(event.target.checked)
|
|
56
|
+
setSelectedDate(event.target.checked ? addDays(new Date(), 30) : null)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const handlePasswordEnabledChange = event => {
|
|
60
|
+
setPasswordEnabled(event.target.checked)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const handlePasswordChange = event => {
|
|
64
|
+
setPassword(event.target.value)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const handleSettingsOpen = () => {
|
|
68
|
+
setIsSettingsOpen(true)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const handleSettingsBack = () => {
|
|
72
|
+
setIsSettingsOpen(false)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const handleSubmit = async () => {
|
|
76
|
+
setBusy(true)
|
|
77
|
+
setError(null)
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
const results = await Promise.all(
|
|
81
|
+
documents.map(document =>
|
|
82
|
+
ensureSharingLink(document, {
|
|
83
|
+
editingRights,
|
|
84
|
+
dateEnabled,
|
|
85
|
+
selectedDate,
|
|
86
|
+
passwordEnabled,
|
|
87
|
+
password: password.trim()
|
|
88
|
+
})
|
|
89
|
+
)
|
|
90
|
+
)
|
|
91
|
+
onSuccess(results)
|
|
92
|
+
} catch {
|
|
93
|
+
setError(t('ShareLinkAccessModal.error.persistence'))
|
|
94
|
+
setBusy(false)
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (isSettingsOpen) {
|
|
99
|
+
return (
|
|
100
|
+
<ConfirmDialog
|
|
101
|
+
open
|
|
102
|
+
classes={DIALOG_CLASSES}
|
|
103
|
+
size="small"
|
|
104
|
+
onBack={busy ? undefined : handleSettingsBack}
|
|
105
|
+
onClose={busy ? undefined : handleSettingsBack}
|
|
106
|
+
title={t('ShareLinkAccessModal.settingsTitle')}
|
|
107
|
+
content={
|
|
108
|
+
<Box display="flex" flexDirection="column" gridGap="1rem">
|
|
109
|
+
<FormControlLabel
|
|
110
|
+
control={
|
|
111
|
+
<Switch
|
|
112
|
+
checked={dateEnabled}
|
|
113
|
+
onChange={handleDateEnabledChange}
|
|
114
|
+
disabled={busy}
|
|
115
|
+
color="primary"
|
|
116
|
+
/>
|
|
117
|
+
}
|
|
118
|
+
label={t('ShareLinkAccessModal.expiry')}
|
|
119
|
+
/>
|
|
120
|
+
{dateEnabled && (
|
|
121
|
+
<DatePicker
|
|
122
|
+
label={t('ShareLinkAccessModal.expiryDate')}
|
|
123
|
+
value={selectedDate}
|
|
124
|
+
minDate={new Date()}
|
|
125
|
+
onChange={setSelectedDate}
|
|
126
|
+
disabled={busy}
|
|
127
|
+
className="u-w-100"
|
|
128
|
+
/>
|
|
129
|
+
)}
|
|
130
|
+
<FormControlLabel
|
|
131
|
+
control={
|
|
132
|
+
<Switch
|
|
133
|
+
checked={passwordEnabled}
|
|
134
|
+
onChange={handlePasswordEnabledChange}
|
|
135
|
+
disabled={busy}
|
|
136
|
+
color="primary"
|
|
137
|
+
/>
|
|
138
|
+
}
|
|
139
|
+
label={t('ShareLinkAccessModal.password')}
|
|
140
|
+
/>
|
|
141
|
+
{passwordEnabled && (
|
|
142
|
+
<TextField
|
|
143
|
+
label={t('ShareLinkAccessModal.passwordLabel')}
|
|
144
|
+
value={password}
|
|
145
|
+
onChange={handlePasswordChange}
|
|
146
|
+
disabled={busy}
|
|
147
|
+
type="password"
|
|
148
|
+
error={!isPasswordValid}
|
|
149
|
+
helperText={
|
|
150
|
+
isPasswordValid
|
|
151
|
+
? null
|
|
152
|
+
: t('ShareLinkAccessModal.passwordTooShort', {
|
|
153
|
+
count: PASSWORD_MIN_LENGTH
|
|
154
|
+
})
|
|
155
|
+
}
|
|
156
|
+
fullWidth
|
|
157
|
+
inputProps={{ minLength: PASSWORD_MIN_LENGTH }}
|
|
158
|
+
/>
|
|
159
|
+
)}
|
|
160
|
+
</Box>
|
|
161
|
+
}
|
|
162
|
+
/>
|
|
163
|
+
)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return (
|
|
167
|
+
<ConfirmDialog
|
|
168
|
+
open
|
|
169
|
+
classes={DIALOG_CLASSES}
|
|
170
|
+
size="small"
|
|
171
|
+
onBack={busy ? undefined : onCancel}
|
|
172
|
+
onClose={busy ? undefined : onCancel}
|
|
173
|
+
title={t('ShareLinkAccessModal.title')}
|
|
174
|
+
content={
|
|
175
|
+
<Box display="flex" flexDirection="column" gridGap="1rem">
|
|
176
|
+
<Typography>{t('ShareLinkAccessModal.introText')}</Typography>
|
|
177
|
+
<Grid container spacing={1}>
|
|
178
|
+
{documents.map(document => (
|
|
179
|
+
<Grid item key={document._id || document.id} xs={12} sm={6}>
|
|
180
|
+
<Chip
|
|
181
|
+
avatar={
|
|
182
|
+
<Box component="span" className="u-flex u-ov-hidden">
|
|
183
|
+
{renderDocumentIcon(document, DOCUMENT_ICON_SIZE)}
|
|
184
|
+
</Box>
|
|
185
|
+
}
|
|
186
|
+
className="u-maw-100"
|
|
187
|
+
label={document.name}
|
|
188
|
+
size="small"
|
|
189
|
+
/>
|
|
190
|
+
</Grid>
|
|
191
|
+
))}
|
|
192
|
+
</Grid>
|
|
193
|
+
{error && <Alert severity="error">{error}</Alert>}
|
|
194
|
+
<Box
|
|
195
|
+
display="flex"
|
|
196
|
+
alignItems="center"
|
|
197
|
+
justifyContent="space-between"
|
|
198
|
+
>
|
|
199
|
+
<Box display="flex" alignItems="center" gridGap="0.5rem">
|
|
200
|
+
<Icon icon={LinkIcon} />
|
|
201
|
+
<Typography>
|
|
202
|
+
{t('ShareLinkAccessModal.anyoneWithLink')}
|
|
203
|
+
</Typography>
|
|
204
|
+
</Box>
|
|
205
|
+
<Box
|
|
206
|
+
display="flex"
|
|
207
|
+
alignItems="center"
|
|
208
|
+
gridGap="0.5rem"
|
|
209
|
+
className="u-flex-shrink-0"
|
|
210
|
+
>
|
|
211
|
+
<IconButton
|
|
212
|
+
aria-label={t('ShareLinkAccessModal.settings')}
|
|
213
|
+
disabled={busy}
|
|
214
|
+
onClick={handleSettingsOpen}
|
|
215
|
+
>
|
|
216
|
+
<Icon icon={Settings} />
|
|
217
|
+
</IconButton>
|
|
218
|
+
<DropdownButton
|
|
219
|
+
aria-label={t('ShareLinkAccessModal.accessLevel')}
|
|
220
|
+
aria-controls="share-link-access-menu"
|
|
221
|
+
aria-haspopup="true"
|
|
222
|
+
disabled={busy}
|
|
223
|
+
onClick={event => setAccessAnchorEl(event.currentTarget)}
|
|
224
|
+
spaceBetween
|
|
225
|
+
textVariant="body1"
|
|
226
|
+
>
|
|
227
|
+
{t(
|
|
228
|
+
editingRights === 'readOnly'
|
|
229
|
+
? 'ShareLinkAccessModal.viewer'
|
|
230
|
+
: 'ShareLinkAccessModal.editor'
|
|
231
|
+
)}
|
|
232
|
+
</DropdownButton>
|
|
233
|
+
<Menu
|
|
234
|
+
id="share-link-access-menu"
|
|
235
|
+
anchorEl={accessAnchorEl}
|
|
236
|
+
open={Boolean(accessAnchorEl)}
|
|
237
|
+
onClose={handleAccessMenuClose}
|
|
238
|
+
>
|
|
239
|
+
<MenuItem
|
|
240
|
+
selected={editingRights === 'readOnly'}
|
|
241
|
+
onClick={() => {
|
|
242
|
+
setEditingRights('readOnly')
|
|
243
|
+
handleAccessMenuClose()
|
|
244
|
+
}}
|
|
245
|
+
>
|
|
246
|
+
{t('ShareLinkAccessModal.viewer')}
|
|
247
|
+
</MenuItem>
|
|
248
|
+
<MenuItem
|
|
249
|
+
selected={editingRights === 'write'}
|
|
250
|
+
onClick={() => {
|
|
251
|
+
setEditingRights('write')
|
|
252
|
+
handleAccessMenuClose()
|
|
253
|
+
}}
|
|
254
|
+
>
|
|
255
|
+
{t('ShareLinkAccessModal.editor')}
|
|
256
|
+
</MenuItem>
|
|
257
|
+
</Menu>
|
|
258
|
+
</Box>
|
|
259
|
+
</Box>
|
|
260
|
+
</Box>
|
|
261
|
+
}
|
|
262
|
+
actions={
|
|
263
|
+
<>
|
|
264
|
+
<Button
|
|
265
|
+
label={t('ShareLinkAccessModal.cancel')}
|
|
266
|
+
variant="secondary"
|
|
267
|
+
onClick={onCancel}
|
|
268
|
+
disabled={busy}
|
|
269
|
+
/>
|
|
270
|
+
<Button
|
|
271
|
+
label={t('ShareLinkAccessModal.addLinks')}
|
|
272
|
+
onClick={handleSubmit}
|
|
273
|
+
disabled={busy || !isPasswordValid}
|
|
274
|
+
busy={busy}
|
|
275
|
+
/>
|
|
276
|
+
</>
|
|
277
|
+
}
|
|
278
|
+
/>
|
|
279
|
+
)
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
ShareLinkAccessModal.propTypes = {
|
|
283
|
+
documents: PropTypes.arrayOf(PropTypes.object).isRequired,
|
|
284
|
+
onCancel: PropTypes.func.isRequired,
|
|
285
|
+
onSuccess: PropTypes.func.isRequired,
|
|
286
|
+
renderDocumentIcon: PropTypes.func
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
ShareLinkAccessModal.defaultProps = {
|
|
290
|
+
renderDocumentIcon: () => null
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export default withLocales(ShareLinkAccessModal)
|