cozy-sharing 37.2.0 → 37.2.2
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 +8 -0
- package/dist/components/ShareLinkAccessModal/ShareLinkAccessModal.js +35 -65
- package/dist/components/ShareLinkAccessModal/ShareLinkAccessModal.spec.js +20 -7
- package/dist/components/ShareRestrictionModal/BoxDate.js +3 -0
- package/dist/components/ShareRestrictionModal/BoxPassword.js +6 -9
- package/dist/components/ShareRestrictionModal/ShareLinkSettings.js +80 -0
- package/dist/components/ShareRestrictionModal/ShareRestrictionContentModal.js +15 -55
- package/dist/components/ShareRestrictionModal/ShareRestrictionModal.js +1 -6
- package/locales/en.json +0 -5
- package/locales/fr.json +0 -5
- package/locales/ru.json +0 -5
- package/locales/vi.json +0 -5
- package/package.json +3 -3
- package/src/components/ShareLinkAccessModal/ShareLinkAccessModal.jsx +23 -73
- package/src/components/ShareLinkAccessModal/ShareLinkAccessModal.spec.jsx +15 -7
- package/src/components/ShareRestrictionModal/BoxDate.jsx +1 -0
- package/src/components/ShareRestrictionModal/BoxPassword.jsx +3 -7
- package/src/components/ShareRestrictionModal/ShareLinkSettings.jsx +93 -0
- package/src/components/ShareRestrictionModal/ShareRestrictionContentModal.jsx +15 -55
- package/src/components/ShareRestrictionModal/ShareRestrictionModal.jsx +1 -9
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [37.2.2](https://github.com/cozy/cozy-libs/compare/cozy-sharing@37.2.1...cozy-sharing@37.2.2) (2026-07-22)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package cozy-sharing
|
|
9
|
+
|
|
10
|
+
## [37.2.1](https://github.com/cozy/cozy-libs/compare/cozy-sharing@37.2.0...cozy-sharing@37.2.1) (2026-07-22)
|
|
11
|
+
|
|
12
|
+
**Note:** Version bump only for package cozy-sharing
|
|
13
|
+
|
|
6
14
|
# [37.2.0](https://github.com/cozy/cozy-libs/compare/cozy-sharing@37.1.0...cozy-sharing@37.2.0) (2026-07-21)
|
|
7
15
|
|
|
8
16
|
### Bug Fixes
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
2
|
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
3
3
|
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
4
|
-
import { addDays } from 'date-fns';
|
|
5
4
|
import PropTypes from 'prop-types';
|
|
6
5
|
import React, { useState } from 'react';
|
|
7
6
|
import { Icon, Link as LinkIcon, Settings } from '@linagora/twake-icons';
|
|
@@ -10,24 +9,20 @@ import Box from 'cozy-ui/transpiled/react/Box';
|
|
|
10
9
|
import Button from 'cozy-ui/transpiled/react/Buttons';
|
|
11
10
|
import Chip from 'cozy-ui/transpiled/react/Chips';
|
|
12
11
|
import { ConfirmDialog } from 'cozy-ui/transpiled/react/CozyDialogs';
|
|
13
|
-
import DatePicker from 'cozy-ui/transpiled/react/DatePicker';
|
|
14
12
|
import DropdownButton from 'cozy-ui/transpiled/react/DropdownButton';
|
|
15
|
-
import FormControlLabel from 'cozy-ui/transpiled/react/FormControlLabel';
|
|
16
13
|
import Grid from 'cozy-ui/transpiled/react/Grid';
|
|
17
14
|
import IconButton from 'cozy-ui/transpiled/react/IconButton';
|
|
18
15
|
import Menu from 'cozy-ui/transpiled/react/Menu';
|
|
19
16
|
import MenuItem from 'cozy-ui/transpiled/react/MenuItem';
|
|
20
|
-
import Switch from 'cozy-ui/transpiled/react/Switch';
|
|
21
|
-
import TextField from 'cozy-ui/transpiled/react/TextField';
|
|
22
17
|
import Typography from 'cozy-ui/transpiled/react/Typography';
|
|
23
18
|
import { useI18n } from 'twake-i18n';
|
|
24
19
|
import withLocales from '../../hoc/withLocales';
|
|
25
20
|
import { useSharingContext } from '../../hooks/useSharingContext';
|
|
21
|
+
import { ShareLinkSettings } from '../ShareRestrictionModal/ShareLinkSettings';
|
|
26
22
|
var DIALOG_CLASSES = {
|
|
27
23
|
paper: 'u-h-auto'
|
|
28
24
|
};
|
|
29
25
|
var DOCUMENT_ICON_SIZE = 18;
|
|
30
|
-
var PASSWORD_MIN_LENGTH = 4;
|
|
31
26
|
export var ShareLinkAccessModal = function ShareLinkAccessModal(_ref) {
|
|
32
27
|
var documents = _ref.documents,
|
|
33
28
|
onCancel = _ref.onCancel,
|
|
@@ -75,35 +70,30 @@ export var ShareLinkAccessModal = function ShareLinkAccessModal(_ref) {
|
|
|
75
70
|
password = _useState14[0],
|
|
76
71
|
setPassword = _useState14[1];
|
|
77
72
|
|
|
78
|
-
var _useState15 = useState(
|
|
73
|
+
var _useState15 = useState(true),
|
|
79
74
|
_useState16 = _slicedToArray(_useState15, 2),
|
|
80
|
-
|
|
81
|
-
|
|
75
|
+
isDateValid = _useState16[0],
|
|
76
|
+
setIsDateValid = _useState16[1];
|
|
82
77
|
|
|
83
|
-
var _useState17 = useState(
|
|
78
|
+
var _useState17 = useState(true),
|
|
84
79
|
_useState18 = _slicedToArray(_useState17, 2),
|
|
85
|
-
|
|
86
|
-
|
|
80
|
+
isPasswordValid = _useState18[0],
|
|
81
|
+
setIsPasswordValid = _useState18[1];
|
|
87
82
|
|
|
88
|
-
var
|
|
83
|
+
var _useState19 = useState(false),
|
|
84
|
+
_useState20 = _slicedToArray(_useState19, 2),
|
|
85
|
+
busy = _useState20[0],
|
|
86
|
+
setBusy = _useState20[1];
|
|
87
|
+
|
|
88
|
+
var _useState21 = useState(null),
|
|
89
|
+
_useState22 = _slicedToArray(_useState21, 2),
|
|
90
|
+
error = _useState22[0],
|
|
91
|
+
setError = _useState22[1];
|
|
89
92
|
|
|
90
93
|
var handleAccessMenuClose = function handleAccessMenuClose() {
|
|
91
94
|
setAccessAnchorEl(null);
|
|
92
95
|
};
|
|
93
96
|
|
|
94
|
-
var handleDateEnabledChange = function handleDateEnabledChange(event) {
|
|
95
|
-
setDateEnabled(event.target.checked);
|
|
96
|
-
setSelectedDate(event.target.checked ? addDays(new Date(), 30) : null);
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
var handlePasswordEnabledChange = function handlePasswordEnabledChange(event) {
|
|
100
|
-
setPasswordEnabled(event.target.checked);
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
var handlePasswordChange = function handlePasswordChange(event) {
|
|
104
|
-
setPassword(event.target.value);
|
|
105
|
-
};
|
|
106
|
-
|
|
107
97
|
var handleSettingsOpen = function handleSettingsOpen() {
|
|
108
98
|
setIsSettingsOpen(true);
|
|
109
99
|
};
|
|
@@ -168,44 +158,24 @@ export var ShareLinkAccessModal = function ShareLinkAccessModal(_ref) {
|
|
|
168
158
|
display: "flex",
|
|
169
159
|
flexDirection: "column",
|
|
170
160
|
gridGap: "1rem"
|
|
171
|
-
}, /*#__PURE__*/React.createElement(
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
onChange: handlePasswordEnabledChange,
|
|
190
|
-
disabled: busy,
|
|
191
|
-
color: "primary"
|
|
192
|
-
}),
|
|
193
|
-
label: t('ShareLinkAccessModal.password')
|
|
194
|
-
}), passwordEnabled && /*#__PURE__*/React.createElement(TextField, {
|
|
195
|
-
label: t('ShareLinkAccessModal.passwordLabel'),
|
|
196
|
-
value: password,
|
|
197
|
-
onChange: handlePasswordChange,
|
|
198
|
-
disabled: busy,
|
|
199
|
-
type: "password",
|
|
200
|
-
error: !isPasswordValid,
|
|
201
|
-
helperText: isPasswordValid ? null : t('ShareLinkAccessModal.passwordTooShort', {
|
|
202
|
-
count: PASSWORD_MIN_LENGTH
|
|
203
|
-
}),
|
|
204
|
-
fullWidth: true,
|
|
205
|
-
inputProps: {
|
|
206
|
-
minLength: PASSWORD_MIN_LENGTH
|
|
207
|
-
}
|
|
208
|
-
}))
|
|
161
|
+
}, /*#__PURE__*/React.createElement(ShareLinkSettings, {
|
|
162
|
+
dateEnabled: dateEnabled,
|
|
163
|
+
isPasswordValid: isPasswordValid,
|
|
164
|
+
password: password,
|
|
165
|
+
passwordEnabled: passwordEnabled,
|
|
166
|
+
selectedDate: selectedDate,
|
|
167
|
+
setDateEnabled: setDateEnabled,
|
|
168
|
+
setIsDateValid: setIsDateValid,
|
|
169
|
+
setIsPasswordValid: setIsPasswordValid,
|
|
170
|
+
setPassword: setPassword,
|
|
171
|
+
setPasswordEnabled: setPasswordEnabled,
|
|
172
|
+
setSelectedDate: setSelectedDate
|
|
173
|
+
})),
|
|
174
|
+
actions: /*#__PURE__*/React.createElement(Button, {
|
|
175
|
+
label: t('ShareRestrictionModal.action.confirm'),
|
|
176
|
+
onClick: handleSettingsBack,
|
|
177
|
+
disabled: !isDateValid || !isPasswordValid
|
|
178
|
+
})
|
|
209
179
|
});
|
|
210
180
|
}
|
|
211
181
|
|
|
@@ -297,7 +267,7 @@ export var ShareLinkAccessModal = function ShareLinkAccessModal(_ref) {
|
|
|
297
267
|
}), /*#__PURE__*/React.createElement(Button, {
|
|
298
268
|
label: t('ShareLinkAccessModal.addLinks'),
|
|
299
269
|
onClick: handleSubmit,
|
|
300
|
-
disabled: busy || !isPasswordValid,
|
|
270
|
+
disabled: busy || !isDateValid || !isPasswordValid,
|
|
301
271
|
busy: busy
|
|
302
272
|
}))
|
|
303
273
|
});
|
|
@@ -17,6 +17,15 @@ jest.mock('../../hoc/withLocales', function () {
|
|
|
17
17
|
};
|
|
18
18
|
};
|
|
19
19
|
});
|
|
20
|
+
jest.mock('cozy-ui/transpiled/react/providers/Alert', function () {
|
|
21
|
+
return {
|
|
22
|
+
useAlert: function useAlert() {
|
|
23
|
+
return {
|
|
24
|
+
showAlert: jest.fn()
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
});
|
|
20
29
|
jest.mock('cozy-ui/transpiled/react/CozyDialogs', function () {
|
|
21
30
|
return {
|
|
22
31
|
ConfirmDialog: function ConfirmDialog(_ref) {
|
|
@@ -133,11 +142,12 @@ jest.mock('twake-i18n', function () {
|
|
|
133
142
|
'ShareLinkAccessModal.cancel': 'Cancel',
|
|
134
143
|
'ShareLinkAccessModal.addLinks': 'Add links',
|
|
135
144
|
'ShareLinkAccessModal.settingsTitle': 'Sharing settings',
|
|
136
|
-
'
|
|
137
|
-
'
|
|
138
|
-
'
|
|
139
|
-
'
|
|
140
|
-
'
|
|
145
|
+
'ShareRestrictionModal.action.confirm': 'Confirm',
|
|
146
|
+
'ShareRestrictionModal.invalidPasswordMessage': 'Password must contain at least 4 characters.',
|
|
147
|
+
'BoxDate.text': 'Set an expiration date',
|
|
148
|
+
'BoxDate.label': 'Expiration date',
|
|
149
|
+
'BoxPassword.text': 'Require a password',
|
|
150
|
+
'BoxPassword.label': 'Password',
|
|
141
151
|
'ShareLinkAccessModal.error.persistence': 'Could not save link permissions. Please try again.'
|
|
142
152
|
}[key] || key;
|
|
143
153
|
}
|
|
@@ -200,7 +210,7 @@ describe('ShareLinkAccessModal', function () {
|
|
|
200
210
|
}));
|
|
201
211
|
expect(onCancel).toHaveBeenCalledTimes(1);
|
|
202
212
|
});
|
|
203
|
-
it('
|
|
213
|
+
it('validates the settings by returning to the access screen', function () {
|
|
204
214
|
renderModal();
|
|
205
215
|
fireEvent.click(screen.getByLabelText('Access level'));
|
|
206
216
|
fireEvent.click(screen.getByRole('button', {
|
|
@@ -217,7 +227,7 @@ describe('ShareLinkAccessModal', function () {
|
|
|
217
227
|
}
|
|
218
228
|
});
|
|
219
229
|
fireEvent.click(screen.getByRole('button', {
|
|
220
|
-
name: '
|
|
230
|
+
name: 'Confirm'
|
|
221
231
|
}));
|
|
222
232
|
expect(screen.getByLabelText('Access level')).toHaveTextContent('Editor');
|
|
223
233
|
fireEvent.click(screen.getByRole('button', {
|
|
@@ -238,6 +248,9 @@ describe('ShareLinkAccessModal', function () {
|
|
|
238
248
|
value: 'abc'
|
|
239
249
|
}
|
|
240
250
|
});
|
|
251
|
+
expect(screen.getByRole('button', {
|
|
252
|
+
name: 'Confirm'
|
|
253
|
+
})).toBeDisabled();
|
|
241
254
|
fireEvent.click(screen.getByRole('button', {
|
|
242
255
|
name: 'Back'
|
|
243
256
|
}));
|
|
@@ -50,6 +50,9 @@ export var BoxDate = function BoxDate(_ref) {
|
|
|
50
50
|
edge: "start",
|
|
51
51
|
color: "primary",
|
|
52
52
|
checked: toggle,
|
|
53
|
+
inputProps: {
|
|
54
|
+
'aria-label': t('BoxDate.text')
|
|
55
|
+
},
|
|
53
56
|
onChange: handleDateToggle
|
|
54
57
|
})))), toggle && /*#__PURE__*/React.createElement("div", {
|
|
55
58
|
className: "u-pt-half u-ph-1 u-pb-1"
|
|
@@ -17,10 +17,9 @@ import TextField from 'cozy-ui/transpiled/react/TextField';
|
|
|
17
17
|
import { useAlert } from 'cozy-ui/transpiled/react/providers/Alert';
|
|
18
18
|
import { useI18n } from 'twake-i18n';
|
|
19
19
|
import { copyToClipboard } from './helpers';
|
|
20
|
-
import { checkIsPermissionHasPassword } from '../../helpers/permissions';
|
|
21
|
-
import { useSharingContext } from '../../hooks/useSharingContext';
|
|
22
20
|
export var BoxPassword = function BoxPassword(_ref) {
|
|
23
|
-
var
|
|
21
|
+
var _ref$hasPassword = _ref.hasPassword,
|
|
22
|
+
hasPassword = _ref$hasPassword === void 0 ? false : _ref$hasPassword,
|
|
24
23
|
onChange = _ref.onChange,
|
|
25
24
|
password = _ref.password,
|
|
26
25
|
onToggle = _ref.onToggle,
|
|
@@ -41,12 +40,6 @@ export var BoxPassword = function BoxPassword(_ref) {
|
|
|
41
40
|
|
|
42
41
|
var inputRef = React.useRef();
|
|
43
42
|
|
|
44
|
-
var _useSharingContext = useSharingContext(),
|
|
45
|
-
getDocumentPermissions = _useSharingContext.getDocumentPermissions;
|
|
46
|
-
|
|
47
|
-
var permissions = getDocumentPermissions(file._id);
|
|
48
|
-
var hasPassword = checkIsPermissionHasPassword(permissions);
|
|
49
|
-
|
|
50
43
|
var handlePasswordToggle = function handlePasswordToggle(val) {
|
|
51
44
|
var _val$target$checked, _val$target;
|
|
52
45
|
|
|
@@ -113,6 +106,9 @@ export var BoxPassword = function BoxPassword(_ref) {
|
|
|
113
106
|
edge: "start",
|
|
114
107
|
color: "primary",
|
|
115
108
|
checked: toggle,
|
|
109
|
+
inputProps: {
|
|
110
|
+
'aria-label': t('BoxPassword.text')
|
|
111
|
+
},
|
|
116
112
|
onChange: handlePasswordToggle
|
|
117
113
|
})))), toggle && /*#__PURE__*/React.createElement("div", {
|
|
118
114
|
className: "u-pt-half u-ph-1 u-pb-1"
|
|
@@ -146,6 +142,7 @@ export var BoxPassword = function BoxPassword(_ref) {
|
|
|
146
142
|
}))));
|
|
147
143
|
};
|
|
148
144
|
BoxPassword.propTypes = {
|
|
145
|
+
hasPassword: PropTypes.bool,
|
|
149
146
|
onChange: PropTypes.func.isRequired,
|
|
150
147
|
password: PropTypes.string,
|
|
151
148
|
onToggle: PropTypes.func.isRequired,
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { addDays, isValid } from 'date-fns';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { useI18n } from 'twake-i18n';
|
|
5
|
+
import { BoxDate } from './BoxDate';
|
|
6
|
+
import { BoxPassword } from './BoxPassword';
|
|
7
|
+
export var PASSWORD_MIN_LENGTH = 4;
|
|
8
|
+
export var ShareLinkSettings = function ShareLinkSettings(_ref) {
|
|
9
|
+
var dateEnabled = _ref.dateEnabled,
|
|
10
|
+
_ref$hasPassword = _ref.hasPassword,
|
|
11
|
+
hasPassword = _ref$hasPassword === void 0 ? false : _ref$hasPassword,
|
|
12
|
+
isPasswordValid = _ref.isPasswordValid,
|
|
13
|
+
password = _ref.password,
|
|
14
|
+
passwordEnabled = _ref.passwordEnabled,
|
|
15
|
+
selectedDate = _ref.selectedDate,
|
|
16
|
+
setDateEnabled = _ref.setDateEnabled,
|
|
17
|
+
setIsDateValid = _ref.setIsDateValid,
|
|
18
|
+
setIsPasswordValid = _ref.setIsPasswordValid,
|
|
19
|
+
setPassword = _ref.setPassword,
|
|
20
|
+
setPasswordEnabled = _ref.setPasswordEnabled,
|
|
21
|
+
setSelectedDate = _ref.setSelectedDate;
|
|
22
|
+
|
|
23
|
+
var _useI18n = useI18n(),
|
|
24
|
+
t = _useI18n.t;
|
|
25
|
+
|
|
26
|
+
var handlePasswordChange = function handlePasswordChange(value) {
|
|
27
|
+
setPassword(value);
|
|
28
|
+
setIsPasswordValid(hasPassword && value.trim().length === 0 || value.trim().length >= PASSWORD_MIN_LENGTH);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
var handlePasswordToggle = function handlePasswordToggle(enabled) {
|
|
32
|
+
setPasswordEnabled(enabled);
|
|
33
|
+
setPassword('');
|
|
34
|
+
setIsPasswordValid(!enabled || hasPassword);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
var handleDateChange = function handleDateChange(date) {
|
|
38
|
+
setSelectedDate(date);
|
|
39
|
+
setIsDateValid(isValid(date));
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
var handleDateToggle = function handleDateToggle(enabled) {
|
|
43
|
+
setDateEnabled(enabled);
|
|
44
|
+
setSelectedDate(enabled ? addDays(new Date(), 30) : null);
|
|
45
|
+
setIsDateValid(true);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(BoxDate, {
|
|
49
|
+
onChange: handleDateChange,
|
|
50
|
+
date: selectedDate,
|
|
51
|
+
onToggle: handleDateToggle,
|
|
52
|
+
toggle: dateEnabled
|
|
53
|
+
}), /*#__PURE__*/React.createElement(BoxPassword, {
|
|
54
|
+
hasPassword: hasPassword,
|
|
55
|
+
helperText: isPasswordValid ? null : t('ShareRestrictionModal.invalidPasswordMessage', {
|
|
56
|
+
smart_count: PASSWORD_MIN_LENGTH - password.length
|
|
57
|
+
}),
|
|
58
|
+
onChange: handlePasswordChange,
|
|
59
|
+
password: password,
|
|
60
|
+
onToggle: handlePasswordToggle,
|
|
61
|
+
toggle: passwordEnabled,
|
|
62
|
+
inputProps: {
|
|
63
|
+
minLength: PASSWORD_MIN_LENGTH
|
|
64
|
+
}
|
|
65
|
+
}));
|
|
66
|
+
};
|
|
67
|
+
ShareLinkSettings.propTypes = {
|
|
68
|
+
dateEnabled: PropTypes.bool.isRequired,
|
|
69
|
+
hasPassword: PropTypes.bool,
|
|
70
|
+
isPasswordValid: PropTypes.bool.isRequired,
|
|
71
|
+
password: PropTypes.string,
|
|
72
|
+
passwordEnabled: PropTypes.bool.isRequired,
|
|
73
|
+
selectedDate: PropTypes.instanceOf(Date),
|
|
74
|
+
setDateEnabled: PropTypes.func.isRequired,
|
|
75
|
+
setIsDateValid: PropTypes.func.isRequired,
|
|
76
|
+
setIsPasswordValid: PropTypes.func.isRequired,
|
|
77
|
+
setPassword: PropTypes.func.isRequired,
|
|
78
|
+
setPasswordEnabled: PropTypes.func.isRequired,
|
|
79
|
+
setSelectedDate: PropTypes.func.isRequired
|
|
80
|
+
};
|
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
import { addDays, isValid } from 'date-fns';
|
|
2
1
|
import PropTypes from 'prop-types';
|
|
3
2
|
import React from 'react';
|
|
4
3
|
import Box from 'cozy-ui/transpiled/react/Box';
|
|
5
4
|
import Typography from 'cozy-ui/transpiled/react/Typography';
|
|
6
5
|
import { useI18n } from 'twake-i18n';
|
|
7
|
-
import { BoxDate } from './BoxDate';
|
|
8
6
|
import { BoxEditingRights } from './BoxEditingRights';
|
|
9
|
-
import {
|
|
7
|
+
import { ShareLinkSettings } from './ShareLinkSettings';
|
|
10
8
|
import { checkIsPermissionHasPassword } from '../../helpers/permissions';
|
|
11
9
|
import { useSharingContext } from '../../hooks/useSharingContext';
|
|
12
|
-
var PASSWORD_MIN_LENGTH = 4;
|
|
13
10
|
export var ShareRestrictionContentModal = function ShareRestrictionContentModal(_ref) {
|
|
14
11
|
var file = _ref.file,
|
|
15
12
|
selectedDate = _ref.selectedDate,
|
|
@@ -17,7 +14,7 @@ export var ShareRestrictionContentModal = function ShareRestrictionContentModal(
|
|
|
17
14
|
dateToggle = _ref.dateToggle,
|
|
18
15
|
setDateToggle = _ref.setDateToggle,
|
|
19
16
|
setIsValidDate = _ref.setIsValidDate,
|
|
20
|
-
|
|
17
|
+
isPasswordValid = _ref.isPasswordValid,
|
|
21
18
|
password = _ref.password,
|
|
22
19
|
setPassword = _ref.setPassword,
|
|
23
20
|
passwordToggle = _ref.passwordToggle,
|
|
@@ -34,41 +31,6 @@ export var ShareRestrictionContentModal = function ShareRestrictionContentModal(
|
|
|
34
31
|
|
|
35
32
|
var permissions = getDocumentPermissions(file._id);
|
|
36
33
|
var hasPassword = checkIsPermissionHasPassword(permissions);
|
|
37
|
-
|
|
38
|
-
var handlePassword = function handlePassword(value) {
|
|
39
|
-
setPassword(value);
|
|
40
|
-
setIsValidPassword(hasPassword && value.trim().length === 0 || value.trim().length >= PASSWORD_MIN_LENGTH);
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
var handlePasswordToggle = function handlePasswordToggle(val) {
|
|
44
|
-
setPasswordToggle(val);
|
|
45
|
-
setPassword('');
|
|
46
|
-
|
|
47
|
-
if (val && !password) {
|
|
48
|
-
setIsValidPassword(hasPassword);
|
|
49
|
-
} else {
|
|
50
|
-
setIsValidPassword(true);
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
var handleDate = function handleDate(date) {
|
|
55
|
-
setSelectedDate(date);
|
|
56
|
-
setIsValidDate(isValid(date));
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
var handleDateToggle = function handleDateToggle(val) {
|
|
60
|
-
setDateToggle(val);
|
|
61
|
-
|
|
62
|
-
if (!val) {
|
|
63
|
-
setSelectedDate(null);
|
|
64
|
-
setIsValidDate(true);
|
|
65
|
-
} else {
|
|
66
|
-
var defaultValue = val ? addDays(new Date(), 30) : null;
|
|
67
|
-
setSelectedDate(defaultValue);
|
|
68
|
-
setIsValidDate(true);
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
|
|
72
34
|
return /*#__PURE__*/React.createElement(Box, {
|
|
73
35
|
display: "flex",
|
|
74
36
|
flexDirection: "column",
|
|
@@ -80,21 +42,19 @@ export var ShareRestrictionContentModal = function ShareRestrictionContentModal(
|
|
|
80
42
|
file: file,
|
|
81
43
|
editingRights: editingRights,
|
|
82
44
|
setEditingRights: setEditingRights
|
|
83
|
-
}), /*#__PURE__*/React.createElement(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
toggle: dateToggle
|
|
88
|
-
}), /*#__PURE__*/React.createElement(BoxPassword, {
|
|
89
|
-
file: file,
|
|
90
|
-
onChange: handlePassword,
|
|
45
|
+
}), /*#__PURE__*/React.createElement(ShareLinkSettings, {
|
|
46
|
+
dateEnabled: dateToggle,
|
|
47
|
+
hasPassword: hasPassword,
|
|
48
|
+
isPasswordValid: isPasswordValid,
|
|
91
49
|
password: password,
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
50
|
+
passwordEnabled: passwordToggle,
|
|
51
|
+
selectedDate: selectedDate,
|
|
52
|
+
setDateEnabled: setDateToggle,
|
|
53
|
+
setIsDateValid: setIsValidDate,
|
|
54
|
+
setIsPasswordValid: setIsValidPassword,
|
|
55
|
+
setPassword: setPassword,
|
|
56
|
+
setPasswordEnabled: setPasswordToggle,
|
|
57
|
+
setSelectedDate: setSelectedDate
|
|
98
58
|
}));
|
|
99
59
|
};
|
|
100
60
|
ShareRestrictionContentModal.propTypes = {
|
|
@@ -106,7 +66,7 @@ ShareRestrictionContentModal.propTypes = {
|
|
|
106
66
|
setDateToggle: PropTypes.func.isRequired,
|
|
107
67
|
setIsValidDate: PropTypes.func.isRequired,
|
|
108
68
|
// Password
|
|
109
|
-
|
|
69
|
+
isPasswordValid: PropTypes.bool.isRequired,
|
|
110
70
|
password: PropTypes.string,
|
|
111
71
|
setPassword: PropTypes.func.isRequired,
|
|
112
72
|
passwordToggle: PropTypes.bool.isRequired,
|
|
@@ -16,7 +16,6 @@ import { copyToClipboard, updatePermissions, makeTTL, revokePermissions, createP
|
|
|
16
16
|
import { getAppSlugFromDocumentType } from '../../helpers/link';
|
|
17
17
|
import { checkIsPermissionHasExpiresDate, checkIsPermissionHasPassword, checkIsReadOnlyPermissions, getPermissionExpiresDate } from '../../helpers/permissions';
|
|
18
18
|
import { useSharingContext } from '../../hooks/useSharingContext';
|
|
19
|
-
var PASSWORD_MIN_LENGTH = 4;
|
|
20
19
|
export var ShareRestrictionModal = function ShareRestrictionModal(_ref) {
|
|
21
20
|
var file = _ref.file,
|
|
22
21
|
onClose = _ref.onClose;
|
|
@@ -84,10 +83,6 @@ export var ShareRestrictionModal = function ShareRestrictionModal(_ref) {
|
|
|
84
83
|
editingRights = _useState16[0],
|
|
85
84
|
setEditingRights = _useState16[1];
|
|
86
85
|
|
|
87
|
-
var helperTextPassword = !isValidPassword ? t('ShareRestrictionModal.invalidPasswordMessage', {
|
|
88
|
-
smart_count: PASSWORD_MIN_LENGTH - password.length
|
|
89
|
-
}) : null;
|
|
90
|
-
|
|
91
86
|
var handleClick = /*#__PURE__*/function () {
|
|
92
87
|
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
93
88
|
var permsPromise, urlPromise;
|
|
@@ -216,7 +211,7 @@ export var ShareRestrictionModal = function ShareRestrictionModal(_ref) {
|
|
|
216
211
|
selectedDate: selectedDate,
|
|
217
212
|
setIsValidDate: setIsValidDate // Password
|
|
218
213
|
,
|
|
219
|
-
|
|
214
|
+
isPasswordValid: isValidPassword,
|
|
220
215
|
passwordToggle: passwordToggle,
|
|
221
216
|
setPasswordToggle: setPasswordToggle,
|
|
222
217
|
password: password,
|
package/locales/en.json
CHANGED
|
@@ -470,11 +470,6 @@
|
|
|
470
470
|
"viewer": "Viewer",
|
|
471
471
|
"editor": "Editor",
|
|
472
472
|
"settingsTitle": "Sharing settings",
|
|
473
|
-
"expiry": "Set an expiration date",
|
|
474
|
-
"expiryDate": "Expiration date",
|
|
475
|
-
"password": "Require a password",
|
|
476
|
-
"passwordLabel": "Password",
|
|
477
|
-
"passwordTooShort": "Password must contain at least %{count} characters.",
|
|
478
473
|
"cancel": "Cancel",
|
|
479
474
|
"addLinks": "Add links",
|
|
480
475
|
"error": {
|
package/locales/fr.json
CHANGED
|
@@ -468,11 +468,6 @@
|
|
|
468
468
|
"viewer": "Lecteur",
|
|
469
469
|
"editor": "Éditeur",
|
|
470
470
|
"settingsTitle": "Paramètres de partage",
|
|
471
|
-
"expiry": "Définir une date d'expiration",
|
|
472
|
-
"expiryDate": "Date d'expiration",
|
|
473
|
-
"password": "Exiger un mot de passe",
|
|
474
|
-
"passwordLabel": "Mot de passe",
|
|
475
|
-
"passwordTooShort": "Le mot de passe doit contenir au moins %{count} caractères.",
|
|
476
471
|
"cancel": "Annuler",
|
|
477
472
|
"addLinks": "Ajouter les liens",
|
|
478
473
|
"error": {
|
package/locales/ru.json
CHANGED
|
@@ -470,11 +470,6 @@
|
|
|
470
470
|
"viewer": "Просмотр",
|
|
471
471
|
"editor": "Редактирование",
|
|
472
472
|
"settingsTitle": "Настройки доступа",
|
|
473
|
-
"expiry": "Установить срок действия",
|
|
474
|
-
"expiryDate": "Дата истечения",
|
|
475
|
-
"password": "Требовать пароль",
|
|
476
|
-
"passwordLabel": "Пароль",
|
|
477
|
-
"passwordTooShort": "Пароль должен содержать не менее %{count} символов.",
|
|
478
473
|
"cancel": "Отмена",
|
|
479
474
|
"addLinks": "Добавить ссылки",
|
|
480
475
|
"error": {
|
package/locales/vi.json
CHANGED
|
@@ -470,11 +470,6 @@
|
|
|
470
470
|
"viewer": "Người xem",
|
|
471
471
|
"editor": "Người chỉnh sửa",
|
|
472
472
|
"settingsTitle": "Cài đặt chia sẻ",
|
|
473
|
-
"expiry": "Đặt ngày hết hạn",
|
|
474
|
-
"expiryDate": "Ngày hết hạn",
|
|
475
|
-
"password": "Yêu cầu mật khẩu",
|
|
476
|
-
"passwordLabel": "Mật khẩu",
|
|
477
|
-
"passwordTooShort": "Mật khẩu phải có ít nhất %{count} ký tự.",
|
|
478
473
|
"cancel": "Hủy",
|
|
479
474
|
"addLinks": "Thêm liên kết",
|
|
480
475
|
"error": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cozy-sharing",
|
|
3
|
-
"version": "37.2.
|
|
3
|
+
"version": "37.2.2",
|
|
4
4
|
"description": "Provides sharing login for React applications.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"author": "Cozy",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"cozy-intent": "^2.31.1",
|
|
60
60
|
"cozy-minilog": "^3.10.1",
|
|
61
61
|
"cozy-ui": "^140.5.0",
|
|
62
|
-
"cozy-ui-plus": "^12.1.
|
|
62
|
+
"cozy-ui-plus": "^12.1.4",
|
|
63
63
|
"jest": "30.3.0",
|
|
64
64
|
"jest-environment-jsdom": "30.3.0",
|
|
65
65
|
"react": "16.12.0",
|
|
@@ -85,5 +85,5 @@
|
|
|
85
85
|
"sideEffects": [
|
|
86
86
|
"*.css"
|
|
87
87
|
],
|
|
88
|
-
"gitHead": "
|
|
88
|
+
"gitHead": "ba501af781312be5d4f530b8dac3c6b9604da60e"
|
|
89
89
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { addDays } from 'date-fns'
|
|
2
1
|
import PropTypes from 'prop-types'
|
|
3
2
|
import React, { useState } from 'react'
|
|
4
3
|
|
|
@@ -8,25 +7,20 @@ import Box from 'cozy-ui/transpiled/react/Box'
|
|
|
8
7
|
import Button from 'cozy-ui/transpiled/react/Buttons'
|
|
9
8
|
import Chip from 'cozy-ui/transpiled/react/Chips'
|
|
10
9
|
import { ConfirmDialog } from 'cozy-ui/transpiled/react/CozyDialogs'
|
|
11
|
-
import DatePicker from 'cozy-ui/transpiled/react/DatePicker'
|
|
12
10
|
import DropdownButton from 'cozy-ui/transpiled/react/DropdownButton'
|
|
13
|
-
import FormControlLabel from 'cozy-ui/transpiled/react/FormControlLabel'
|
|
14
11
|
import Grid from 'cozy-ui/transpiled/react/Grid'
|
|
15
12
|
import IconButton from 'cozy-ui/transpiled/react/IconButton'
|
|
16
13
|
import Menu from 'cozy-ui/transpiled/react/Menu'
|
|
17
14
|
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
15
|
import Typography from 'cozy-ui/transpiled/react/Typography'
|
|
21
16
|
import { useI18n } from 'twake-i18n'
|
|
22
17
|
|
|
23
18
|
import withLocales from '../../hoc/withLocales'
|
|
24
19
|
import { useSharingContext } from '../../hooks/useSharingContext'
|
|
20
|
+
import { ShareLinkSettings } from '../ShareRestrictionModal/ShareLinkSettings'
|
|
25
21
|
|
|
26
22
|
const DIALOG_CLASSES = { paper: 'u-h-auto' }
|
|
27
23
|
const DOCUMENT_ICON_SIZE = 18
|
|
28
|
-
const PASSWORD_MIN_LENGTH = 4
|
|
29
|
-
|
|
30
24
|
export const ShareLinkAccessModal = ({
|
|
31
25
|
documents,
|
|
32
26
|
onCancel,
|
|
@@ -42,28 +36,15 @@ export const ShareLinkAccessModal = ({
|
|
|
42
36
|
const [selectedDate, setSelectedDate] = useState(null)
|
|
43
37
|
const [passwordEnabled, setPasswordEnabled] = useState(false)
|
|
44
38
|
const [password, setPassword] = useState('')
|
|
39
|
+
const [isDateValid, setIsDateValid] = useState(true)
|
|
40
|
+
const [isPasswordValid, setIsPasswordValid] = useState(true)
|
|
45
41
|
const [busy, setBusy] = useState(false)
|
|
46
42
|
const [error, setError] = useState(null)
|
|
47
43
|
|
|
48
|
-
const isPasswordValid =
|
|
49
|
-
!passwordEnabled || password.trim().length >= PASSWORD_MIN_LENGTH
|
|
50
44
|
const handleAccessMenuClose = () => {
|
|
51
45
|
setAccessAnchorEl(null)
|
|
52
46
|
}
|
|
53
47
|
|
|
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
48
|
const handleSettingsOpen = () => {
|
|
68
49
|
setIsSettingsOpen(true)
|
|
69
50
|
}
|
|
@@ -106,59 +87,28 @@ export const ShareLinkAccessModal = ({
|
|
|
106
87
|
title={t('ShareLinkAccessModal.settingsTitle')}
|
|
107
88
|
content={
|
|
108
89
|
<Box display="flex" flexDirection="column" gridGap="1rem">
|
|
109
|
-
<
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
|
|
90
|
+
<ShareLinkSettings
|
|
91
|
+
dateEnabled={dateEnabled}
|
|
92
|
+
isPasswordValid={isPasswordValid}
|
|
93
|
+
password={password}
|
|
94
|
+
passwordEnabled={passwordEnabled}
|
|
95
|
+
selectedDate={selectedDate}
|
|
96
|
+
setDateEnabled={setDateEnabled}
|
|
97
|
+
setIsDateValid={setIsDateValid}
|
|
98
|
+
setIsPasswordValid={setIsPasswordValid}
|
|
99
|
+
setPassword={setPassword}
|
|
100
|
+
setPasswordEnabled={setPasswordEnabled}
|
|
101
|
+
setSelectedDate={setSelectedDate}
|
|
119
102
|
/>
|
|
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
103
|
</Box>
|
|
161
104
|
}
|
|
105
|
+
actions={
|
|
106
|
+
<Button
|
|
107
|
+
label={t('ShareRestrictionModal.action.confirm')}
|
|
108
|
+
onClick={handleSettingsBack}
|
|
109
|
+
disabled={!isDateValid || !isPasswordValid}
|
|
110
|
+
/>
|
|
111
|
+
}
|
|
162
112
|
/>
|
|
163
113
|
)
|
|
164
114
|
}
|
|
@@ -270,7 +220,7 @@ export const ShareLinkAccessModal = ({
|
|
|
270
220
|
<Button
|
|
271
221
|
label={t('ShareLinkAccessModal.addLinks')}
|
|
272
222
|
onClick={handleSubmit}
|
|
273
|
-
disabled={busy || !isPasswordValid}
|
|
223
|
+
disabled={busy || !isDateValid || !isPasswordValid}
|
|
274
224
|
busy={busy}
|
|
275
225
|
/>
|
|
276
226
|
</>
|
|
@@ -12,6 +12,10 @@ jest.mock('../../hoc/withLocales', () => Component => props => (
|
|
|
12
12
|
<Component {...props} />
|
|
13
13
|
))
|
|
14
14
|
|
|
15
|
+
jest.mock('cozy-ui/transpiled/react/providers/Alert', () => ({
|
|
16
|
+
useAlert: () => ({ showAlert: jest.fn() })
|
|
17
|
+
}))
|
|
18
|
+
|
|
15
19
|
jest.mock('cozy-ui/transpiled/react/CozyDialogs', () => ({
|
|
16
20
|
ConfirmDialog: ({ title, content, actions, onBack, onClose, size }) => (
|
|
17
21
|
<div role="dialog" data-size={size}>
|
|
@@ -98,12 +102,13 @@ jest.mock('twake-i18n', () => ({
|
|
|
98
102
|
'ShareLinkAccessModal.cancel': 'Cancel',
|
|
99
103
|
'ShareLinkAccessModal.addLinks': 'Add links',
|
|
100
104
|
'ShareLinkAccessModal.settingsTitle': 'Sharing settings',
|
|
101
|
-
'
|
|
102
|
-
'
|
|
103
|
-
'ShareLinkAccessModal.password': 'Require a password',
|
|
104
|
-
'ShareLinkAccessModal.passwordLabel': 'Password',
|
|
105
|
-
'ShareLinkAccessModal.passwordTooShort':
|
|
105
|
+
'ShareRestrictionModal.action.confirm': 'Confirm',
|
|
106
|
+
'ShareRestrictionModal.invalidPasswordMessage':
|
|
106
107
|
'Password must contain at least 4 characters.',
|
|
108
|
+
'BoxDate.text': 'Set an expiration date',
|
|
109
|
+
'BoxDate.label': 'Expiration date',
|
|
110
|
+
'BoxPassword.text': 'Require a password',
|
|
111
|
+
'BoxPassword.label': 'Password',
|
|
107
112
|
'ShareLinkAccessModal.error.persistence':
|
|
108
113
|
'Could not save link permissions. Please try again.'
|
|
109
114
|
})[key] || key
|
|
@@ -169,7 +174,7 @@ describe('ShareLinkAccessModal', () => {
|
|
|
169
174
|
expect(onCancel).toHaveBeenCalledTimes(1)
|
|
170
175
|
})
|
|
171
176
|
|
|
172
|
-
it('
|
|
177
|
+
it('validates the settings by returning to the access screen', () => {
|
|
173
178
|
renderModal()
|
|
174
179
|
|
|
175
180
|
fireEvent.click(screen.getByLabelText('Access level'))
|
|
@@ -180,7 +185,7 @@ describe('ShareLinkAccessModal', () => {
|
|
|
180
185
|
fireEvent.change(screen.getByLabelText('Password'), {
|
|
181
186
|
target: { value: 'secret' }
|
|
182
187
|
})
|
|
183
|
-
fireEvent.click(screen.getByRole('button', { name: '
|
|
188
|
+
fireEvent.click(screen.getByRole('button', { name: 'Confirm' }))
|
|
184
189
|
|
|
185
190
|
expect(screen.getByLabelText('Access level')).toHaveTextContent('Editor')
|
|
186
191
|
|
|
@@ -199,6 +204,9 @@ describe('ShareLinkAccessModal', () => {
|
|
|
199
204
|
fireEvent.change(screen.getByLabelText('Password'), {
|
|
200
205
|
target: { value: 'abc' }
|
|
201
206
|
})
|
|
207
|
+
|
|
208
|
+
expect(screen.getByRole('button', { name: 'Confirm' })).toBeDisabled()
|
|
209
|
+
|
|
202
210
|
fireEvent.click(screen.getByRole('button', { name: 'Back' }))
|
|
203
211
|
|
|
204
212
|
expect(screen.getByRole('button', { name: 'Add links' })).toBeDisabled()
|
|
@@ -15,11 +15,9 @@ import { useAlert } from 'cozy-ui/transpiled/react/providers/Alert'
|
|
|
15
15
|
import { useI18n } from 'twake-i18n'
|
|
16
16
|
|
|
17
17
|
import { copyToClipboard } from './helpers'
|
|
18
|
-
import { checkIsPermissionHasPassword } from '../../helpers/permissions'
|
|
19
|
-
import { useSharingContext } from '../../hooks/useSharingContext'
|
|
20
18
|
|
|
21
19
|
export const BoxPassword = ({
|
|
22
|
-
|
|
20
|
+
hasPassword = false,
|
|
23
21
|
onChange,
|
|
24
22
|
password,
|
|
25
23
|
onToggle,
|
|
@@ -31,10 +29,6 @@ export const BoxPassword = ({
|
|
|
31
29
|
const { showAlert } = useAlert()
|
|
32
30
|
const [displayHelper, setDisplayHelper] = useState(false)
|
|
33
31
|
const inputRef = React.useRef()
|
|
34
|
-
const { getDocumentPermissions } = useSharingContext()
|
|
35
|
-
|
|
36
|
-
const permissions = getDocumentPermissions(file._id)
|
|
37
|
-
const hasPassword = checkIsPermissionHasPassword(permissions)
|
|
38
32
|
|
|
39
33
|
const handlePasswordToggle = val => {
|
|
40
34
|
const value = val?.target?.checked ?? val
|
|
@@ -75,6 +69,7 @@ export const BoxPassword = ({
|
|
|
75
69
|
edge="start"
|
|
76
70
|
color="primary"
|
|
77
71
|
checked={toggle}
|
|
72
|
+
inputProps={{ 'aria-label': t('BoxPassword.text') }}
|
|
78
73
|
onChange={handlePasswordToggle}
|
|
79
74
|
/>
|
|
80
75
|
</ListItemSecondaryAction>
|
|
@@ -117,6 +112,7 @@ export const BoxPassword = ({
|
|
|
117
112
|
}
|
|
118
113
|
|
|
119
114
|
BoxPassword.propTypes = {
|
|
115
|
+
hasPassword: PropTypes.bool,
|
|
120
116
|
onChange: PropTypes.func.isRequired,
|
|
121
117
|
password: PropTypes.string,
|
|
122
118
|
onToggle: PropTypes.func.isRequired,
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { addDays, isValid } from 'date-fns'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import React from 'react'
|
|
4
|
+
|
|
5
|
+
import { useI18n } from 'twake-i18n'
|
|
6
|
+
|
|
7
|
+
import { BoxDate } from './BoxDate'
|
|
8
|
+
import { BoxPassword } from './BoxPassword'
|
|
9
|
+
|
|
10
|
+
export const PASSWORD_MIN_LENGTH = 4
|
|
11
|
+
|
|
12
|
+
export const ShareLinkSettings = ({
|
|
13
|
+
dateEnabled,
|
|
14
|
+
hasPassword = false,
|
|
15
|
+
isPasswordValid,
|
|
16
|
+
password,
|
|
17
|
+
passwordEnabled,
|
|
18
|
+
selectedDate,
|
|
19
|
+
setDateEnabled,
|
|
20
|
+
setIsDateValid,
|
|
21
|
+
setIsPasswordValid,
|
|
22
|
+
setPassword,
|
|
23
|
+
setPasswordEnabled,
|
|
24
|
+
setSelectedDate
|
|
25
|
+
}) => {
|
|
26
|
+
const { t } = useI18n()
|
|
27
|
+
|
|
28
|
+
const handlePasswordChange = value => {
|
|
29
|
+
setPassword(value)
|
|
30
|
+
setIsPasswordValid(
|
|
31
|
+
(hasPassword && value.trim().length === 0) ||
|
|
32
|
+
value.trim().length >= PASSWORD_MIN_LENGTH
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const handlePasswordToggle = enabled => {
|
|
37
|
+
setPasswordEnabled(enabled)
|
|
38
|
+
setPassword('')
|
|
39
|
+
setIsPasswordValid(!enabled || hasPassword)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const handleDateChange = date => {
|
|
43
|
+
setSelectedDate(date)
|
|
44
|
+
setIsDateValid(isValid(date))
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const handleDateToggle = enabled => {
|
|
48
|
+
setDateEnabled(enabled)
|
|
49
|
+
setSelectedDate(enabled ? addDays(new Date(), 30) : null)
|
|
50
|
+
setIsDateValid(true)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<>
|
|
55
|
+
<BoxDate
|
|
56
|
+
onChange={handleDateChange}
|
|
57
|
+
date={selectedDate}
|
|
58
|
+
onToggle={handleDateToggle}
|
|
59
|
+
toggle={dateEnabled}
|
|
60
|
+
/>
|
|
61
|
+
<BoxPassword
|
|
62
|
+
hasPassword={hasPassword}
|
|
63
|
+
helperText={
|
|
64
|
+
isPasswordValid
|
|
65
|
+
? null
|
|
66
|
+
: t('ShareRestrictionModal.invalidPasswordMessage', {
|
|
67
|
+
smart_count: PASSWORD_MIN_LENGTH - password.length
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
onChange={handlePasswordChange}
|
|
71
|
+
password={password}
|
|
72
|
+
onToggle={handlePasswordToggle}
|
|
73
|
+
toggle={passwordEnabled}
|
|
74
|
+
inputProps={{ minLength: PASSWORD_MIN_LENGTH }}
|
|
75
|
+
/>
|
|
76
|
+
</>
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
ShareLinkSettings.propTypes = {
|
|
81
|
+
dateEnabled: PropTypes.bool.isRequired,
|
|
82
|
+
hasPassword: PropTypes.bool,
|
|
83
|
+
isPasswordValid: PropTypes.bool.isRequired,
|
|
84
|
+
password: PropTypes.string,
|
|
85
|
+
passwordEnabled: PropTypes.bool.isRequired,
|
|
86
|
+
selectedDate: PropTypes.instanceOf(Date),
|
|
87
|
+
setDateEnabled: PropTypes.func.isRequired,
|
|
88
|
+
setIsDateValid: PropTypes.func.isRequired,
|
|
89
|
+
setIsPasswordValid: PropTypes.func.isRequired,
|
|
90
|
+
setPassword: PropTypes.func.isRequired,
|
|
91
|
+
setPasswordEnabled: PropTypes.func.isRequired,
|
|
92
|
+
setSelectedDate: PropTypes.func.isRequired
|
|
93
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { addDays, isValid } from 'date-fns'
|
|
2
1
|
import PropTypes from 'prop-types'
|
|
3
2
|
import React from 'react'
|
|
4
3
|
|
|
@@ -6,14 +5,11 @@ import Box from 'cozy-ui/transpiled/react/Box'
|
|
|
6
5
|
import Typography from 'cozy-ui/transpiled/react/Typography'
|
|
7
6
|
import { useI18n } from 'twake-i18n'
|
|
8
7
|
|
|
9
|
-
import { BoxDate } from './BoxDate'
|
|
10
8
|
import { BoxEditingRights } from './BoxEditingRights'
|
|
11
|
-
import {
|
|
9
|
+
import { ShareLinkSettings } from './ShareLinkSettings'
|
|
12
10
|
import { checkIsPermissionHasPassword } from '../../helpers/permissions'
|
|
13
11
|
import { useSharingContext } from '../../hooks/useSharingContext'
|
|
14
12
|
|
|
15
|
-
const PASSWORD_MIN_LENGTH = 4
|
|
16
|
-
|
|
17
13
|
export const ShareRestrictionContentModal = ({
|
|
18
14
|
file,
|
|
19
15
|
// Date
|
|
@@ -23,7 +19,7 @@ export const ShareRestrictionContentModal = ({
|
|
|
23
19
|
setDateToggle,
|
|
24
20
|
setIsValidDate,
|
|
25
21
|
// Password
|
|
26
|
-
|
|
22
|
+
isPasswordValid,
|
|
27
23
|
password,
|
|
28
24
|
setPassword,
|
|
29
25
|
passwordToggle,
|
|
@@ -38,41 +34,6 @@ export const ShareRestrictionContentModal = ({
|
|
|
38
34
|
const permissions = getDocumentPermissions(file._id)
|
|
39
35
|
const hasPassword = checkIsPermissionHasPassword(permissions)
|
|
40
36
|
|
|
41
|
-
const handlePassword = value => {
|
|
42
|
-
setPassword(value)
|
|
43
|
-
setIsValidPassword(
|
|
44
|
-
(hasPassword && value.trim().length === 0) ||
|
|
45
|
-
value.trim().length >= PASSWORD_MIN_LENGTH
|
|
46
|
-
)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const handlePasswordToggle = val => {
|
|
50
|
-
setPasswordToggle(val)
|
|
51
|
-
setPassword('')
|
|
52
|
-
if (val && !password) {
|
|
53
|
-
setIsValidPassword(hasPassword)
|
|
54
|
-
} else {
|
|
55
|
-
setIsValidPassword(true)
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const handleDate = date => {
|
|
60
|
-
setSelectedDate(date)
|
|
61
|
-
setIsValidDate(isValid(date))
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const handleDateToggle = val => {
|
|
65
|
-
setDateToggle(val)
|
|
66
|
-
if (!val) {
|
|
67
|
-
setSelectedDate(null)
|
|
68
|
-
setIsValidDate(true)
|
|
69
|
-
} else {
|
|
70
|
-
const defaultValue = val ? addDays(new Date(), 30) : null
|
|
71
|
-
setSelectedDate(defaultValue)
|
|
72
|
-
setIsValidDate(true)
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
37
|
return (
|
|
77
38
|
<Box display="flex" flexDirection="column" gridGap="1rem">
|
|
78
39
|
<Typography variant="h4" className="u-mb-half u-ml-half">
|
|
@@ -84,20 +45,19 @@ export const ShareRestrictionContentModal = ({
|
|
|
84
45
|
editingRights={editingRights}
|
|
85
46
|
setEditingRights={setEditingRights}
|
|
86
47
|
/>
|
|
87
|
-
<
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
toggle={dateToggle}
|
|
92
|
-
/>
|
|
93
|
-
<BoxPassword
|
|
94
|
-
file={file}
|
|
95
|
-
onChange={handlePassword}
|
|
48
|
+
<ShareLinkSettings
|
|
49
|
+
dateEnabled={dateToggle}
|
|
50
|
+
hasPassword={hasPassword}
|
|
51
|
+
isPasswordValid={isPasswordValid}
|
|
96
52
|
password={password}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
53
|
+
passwordEnabled={passwordToggle}
|
|
54
|
+
selectedDate={selectedDate}
|
|
55
|
+
setDateEnabled={setDateToggle}
|
|
56
|
+
setIsDateValid={setIsValidDate}
|
|
57
|
+
setIsPasswordValid={setIsValidPassword}
|
|
58
|
+
setPassword={setPassword}
|
|
59
|
+
setPasswordEnabled={setPasswordToggle}
|
|
60
|
+
setSelectedDate={setSelectedDate}
|
|
101
61
|
/>
|
|
102
62
|
</Box>
|
|
103
63
|
)
|
|
@@ -112,7 +72,7 @@ ShareRestrictionContentModal.propTypes = {
|
|
|
112
72
|
setDateToggle: PropTypes.func.isRequired,
|
|
113
73
|
setIsValidDate: PropTypes.func.isRequired,
|
|
114
74
|
// Password
|
|
115
|
-
|
|
75
|
+
isPasswordValid: PropTypes.bool.isRequired,
|
|
116
76
|
password: PropTypes.string,
|
|
117
77
|
setPassword: PropTypes.func.isRequired,
|
|
118
78
|
passwordToggle: PropTypes.bool.isRequired,
|
|
@@ -27,8 +27,6 @@ import {
|
|
|
27
27
|
} from '../../helpers/permissions'
|
|
28
28
|
import { useSharingContext } from '../../hooks/useSharingContext'
|
|
29
29
|
|
|
30
|
-
const PASSWORD_MIN_LENGTH = 4
|
|
31
|
-
|
|
32
30
|
export const ShareRestrictionModal = ({ file, onClose }) => {
|
|
33
31
|
const client = useClient()
|
|
34
32
|
const { t } = useI18n()
|
|
@@ -68,12 +66,6 @@ export const ShareRestrictionModal = ({ file, onClose }) => {
|
|
|
68
66
|
isReadOnlyPermissions || permissions.length === 0 ? 'readOnly' : 'write'
|
|
69
67
|
)
|
|
70
68
|
|
|
71
|
-
const helperTextPassword = !isValidPassword
|
|
72
|
-
? t('ShareRestrictionModal.invalidPasswordMessage', {
|
|
73
|
-
smart_count: PASSWORD_MIN_LENGTH - password.length
|
|
74
|
-
})
|
|
75
|
-
: null
|
|
76
|
-
|
|
77
69
|
const handleClick = async () => {
|
|
78
70
|
setLoading(true)
|
|
79
71
|
// The clipboard write must be initiated synchronously within the click
|
|
@@ -153,7 +145,7 @@ export const ShareRestrictionModal = ({ file, onClose }) => {
|
|
|
153
145
|
selectedDate={selectedDate}
|
|
154
146
|
setIsValidDate={setIsValidDate}
|
|
155
147
|
// Password
|
|
156
|
-
|
|
148
|
+
isPasswordValid={isValidPassword}
|
|
157
149
|
passwordToggle={passwordToggle}
|
|
158
150
|
setPasswordToggle={setPasswordToggle}
|
|
159
151
|
password={password}
|