cozy-sharing 32.3.2 → 33.0.1
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 +22 -0
- package/dist/components/FederatedFolder/FederatedFolderModal.js +2 -1
- package/dist/components/ShareAutosuggest.js +15 -5
- package/dist/components/ShareAutosuggest.spec.js +26 -2
- package/dist/components/ShareByEmail.js +3 -0
- package/dist/components/ShareByEmail.spec.js +2 -1
- package/dist/components/ShareDialogCozyToCozy.js +2 -1
- package/dist/components/ShareDialogCozyToCozy.spec.js +2 -2
- package/dist/components/ShareRecipientsInput.js +3 -0
- package/dist/components/SharedDrive/EditSharedDriveModal.js +32 -55
- package/dist/components/SharedDrive/SharedDriveForm.js +23 -5
- package/dist/components/SharedDrive/useSharedDrive.js +8 -37
- package/dist/components/SharedDrive/useSharedDrive.spec.js +8 -81
- package/dist/components/WhoHasAccess.js +4 -1
- package/dist/helpers/contacts.js +12 -0
- package/package.json +4 -4
- package/src/components/FederatedFolder/FederatedFolderModal.jsx +1 -0
- package/src/components/ShareAutosuggest.jsx +17 -11
- package/src/components/ShareAutosuggest.spec.jsx +20 -1
- package/src/components/ShareByEmail.jsx +3 -0
- package/src/components/ShareByEmail.spec.jsx +1 -0
- package/src/components/ShareDialogCozyToCozy.jsx +1 -0
- package/src/components/ShareDialogCozyToCozy.spec.jsx +1 -0
- package/src/components/ShareRecipientsInput.jsx +3 -0
- package/src/components/SharedDrive/EditSharedDriveModal.jsx +42 -47
- package/src/components/SharedDrive/SharedDriveForm.jsx +18 -2
- package/src/components/SharedDrive/useSharedDrive.js +15 -35
- package/src/components/SharedDrive/useSharedDrive.spec.js +4 -39
- package/src/components/WhoHasAccess.jsx +3 -1
- package/src/helpers/contacts.js +12 -0
|
@@ -2,16 +2,12 @@ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
|
2
2
|
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
3
3
|
import { renderHook, act } from '@testing-library/react-hooks';
|
|
4
4
|
import { useSharedDrive } from './useSharedDrive';
|
|
5
|
-
var mockShowAlert = jest.fn();
|
|
6
5
|
var mockCreateSharedDrive = jest.fn();
|
|
7
6
|
var mockCollection = jest.fn(function () {
|
|
8
7
|
return {
|
|
9
8
|
createSharedDrive: mockCreateSharedDrive
|
|
10
9
|
};
|
|
11
10
|
});
|
|
12
|
-
var mockT = jest.fn(function (key) {
|
|
13
|
-
return key;
|
|
14
|
-
});
|
|
15
11
|
jest.mock('cozy-client', function () {
|
|
16
12
|
return {
|
|
17
13
|
useClient: jest.fn(function () {
|
|
@@ -22,24 +18,6 @@ jest.mock('cozy-client', function () {
|
|
|
22
18
|
})
|
|
23
19
|
};
|
|
24
20
|
});
|
|
25
|
-
jest.mock('cozy-ui/transpiled/react/providers/Alert', function () {
|
|
26
|
-
return {
|
|
27
|
-
useAlert: jest.fn(function () {
|
|
28
|
-
return {
|
|
29
|
-
showAlert: mockShowAlert
|
|
30
|
-
};
|
|
31
|
-
})
|
|
32
|
-
};
|
|
33
|
-
});
|
|
34
|
-
jest.mock('twake-i18n', function () {
|
|
35
|
-
return {
|
|
36
|
-
useI18n: jest.fn(function () {
|
|
37
|
-
return {
|
|
38
|
-
t: mockT
|
|
39
|
-
};
|
|
40
|
-
})
|
|
41
|
-
};
|
|
42
|
-
});
|
|
43
21
|
jest.mock('../../models', function () {
|
|
44
22
|
return {
|
|
45
23
|
Contact: {
|
|
@@ -60,9 +38,7 @@ describe('useSharedDrive', function () {
|
|
|
60
38
|
});
|
|
61
39
|
it('returns empty initial state', function () {
|
|
62
40
|
var _renderHook = renderHook(function () {
|
|
63
|
-
return useSharedDrive(
|
|
64
|
-
onSuccess: jest.fn()
|
|
65
|
-
});
|
|
41
|
+
return useSharedDrive();
|
|
66
42
|
}),
|
|
67
43
|
result = _renderHook.result;
|
|
68
44
|
|
|
@@ -72,9 +48,7 @@ describe('useSharedDrive', function () {
|
|
|
72
48
|
});
|
|
73
49
|
it('handleSharedDriveNameChange updates the name', function () {
|
|
74
50
|
var _renderHook2 = renderHook(function () {
|
|
75
|
-
return useSharedDrive(
|
|
76
|
-
onSuccess: jest.fn()
|
|
77
|
-
});
|
|
51
|
+
return useSharedDrive();
|
|
78
52
|
}),
|
|
79
53
|
result = _renderHook2.result;
|
|
80
54
|
|
|
@@ -87,18 +61,15 @@ describe('useSharedDrive', function () {
|
|
|
87
61
|
});
|
|
88
62
|
expect(result.current.sharedDriveName).toBe('My Drive');
|
|
89
63
|
});
|
|
90
|
-
it('onCreate calls createSharedDrive
|
|
91
|
-
var
|
|
64
|
+
it('onCreate calls createSharedDrive', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
|
|
65
|
+
var _renderHook3, result;
|
|
92
66
|
|
|
93
67
|
return _regeneratorRuntime.wrap(function _callee2$(_context2) {
|
|
94
68
|
while (1) switch (_context2.prev = _context2.next) {
|
|
95
69
|
case 0:
|
|
96
|
-
onSuccess = jest.fn();
|
|
97
70
|
mockCreateSharedDrive.mockResolvedValue({});
|
|
98
71
|
_renderHook3 = renderHook(function () {
|
|
99
|
-
return useSharedDrive(
|
|
100
|
-
onSuccess: onSuccess
|
|
101
|
-
});
|
|
72
|
+
return useSharedDrive();
|
|
102
73
|
}), result = _renderHook3.result;
|
|
103
74
|
act(function () {
|
|
104
75
|
result.current.handleSharedDriveNameChange({
|
|
@@ -110,7 +81,7 @@ describe('useSharedDrive', function () {
|
|
|
110
81
|
email: 'a@b.c'
|
|
111
82
|
}]);
|
|
112
83
|
});
|
|
113
|
-
_context2.next =
|
|
84
|
+
_context2.next = 5;
|
|
114
85
|
return act( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
115
86
|
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
116
87
|
while (1) switch (_context.prev = _context.next) {
|
|
@@ -125,7 +96,7 @@ describe('useSharedDrive', function () {
|
|
|
125
96
|
}, _callee);
|
|
126
97
|
})));
|
|
127
98
|
|
|
128
|
-
case
|
|
99
|
+
case 5:
|
|
129
100
|
expect(mockCreateSharedDrive).toHaveBeenCalledWith({
|
|
130
101
|
name: 'My Drive',
|
|
131
102
|
description: 'My Drive',
|
|
@@ -134,55 +105,11 @@ describe('useSharedDrive', function () {
|
|
|
134
105
|
}],
|
|
135
106
|
readOnlyRecipients: []
|
|
136
107
|
});
|
|
137
|
-
expect(mockShowAlert).toHaveBeenCalledWith(expect.objectContaining({
|
|
138
|
-
severity: 'success'
|
|
139
|
-
}));
|
|
140
|
-
expect(onSuccess).toHaveBeenCalledTimes(1);
|
|
141
108
|
|
|
142
|
-
case
|
|
109
|
+
case 6:
|
|
143
110
|
case "end":
|
|
144
111
|
return _context2.stop();
|
|
145
112
|
}
|
|
146
113
|
}, _callee2);
|
|
147
114
|
})));
|
|
148
|
-
it('onCreate shows error alert and does not call onSuccess on failure', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4() {
|
|
149
|
-
var onSuccess, _renderHook4, result;
|
|
150
|
-
|
|
151
|
-
return _regeneratorRuntime.wrap(function _callee4$(_context4) {
|
|
152
|
-
while (1) switch (_context4.prev = _context4.next) {
|
|
153
|
-
case 0:
|
|
154
|
-
onSuccess = jest.fn();
|
|
155
|
-
mockCreateSharedDrive.mockRejectedValue(new Error('network error'));
|
|
156
|
-
_renderHook4 = renderHook(function () {
|
|
157
|
-
return useSharedDrive({
|
|
158
|
-
onSuccess: onSuccess
|
|
159
|
-
});
|
|
160
|
-
}), result = _renderHook4.result;
|
|
161
|
-
_context4.next = 5;
|
|
162
|
-
return act( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
|
|
163
|
-
return _regeneratorRuntime.wrap(function _callee3$(_context3) {
|
|
164
|
-
while (1) switch (_context3.prev = _context3.next) {
|
|
165
|
-
case 0:
|
|
166
|
-
_context3.next = 2;
|
|
167
|
-
return result.current.onCreate();
|
|
168
|
-
|
|
169
|
-
case 2:
|
|
170
|
-
case "end":
|
|
171
|
-
return _context3.stop();
|
|
172
|
-
}
|
|
173
|
-
}, _callee3);
|
|
174
|
-
})));
|
|
175
|
-
|
|
176
|
-
case 5:
|
|
177
|
-
expect(mockShowAlert).toHaveBeenCalledWith(expect.objectContaining({
|
|
178
|
-
severity: 'error'
|
|
179
|
-
}));
|
|
180
|
-
expect(onSuccess).not.toHaveBeenCalled();
|
|
181
|
-
|
|
182
|
-
case 7:
|
|
183
|
-
case "end":
|
|
184
|
-
return _context4.stop();
|
|
185
|
-
}
|
|
186
|
-
}, _callee4);
|
|
187
|
-
})));
|
|
188
115
|
});
|
|
@@ -32,6 +32,8 @@ var WhoHasAccess = function WhoHasAccess(_ref2) {
|
|
|
32
32
|
isOwner = _ref2$isOwner === void 0 ? false : _ref2$isOwner,
|
|
33
33
|
_ref2$isSharedDrive = _ref2.isSharedDrive,
|
|
34
34
|
isSharedDrive = _ref2$isSharedDrive === void 0 ? false : _ref2$isSharedDrive,
|
|
35
|
+
_ref2$showOwner = _ref2.showOwner,
|
|
36
|
+
showOwner = _ref2$showOwner === void 0 ? true : _ref2$showOwner,
|
|
35
37
|
recipients = _ref2.recipients,
|
|
36
38
|
_ref2$recipientsToBeC = _ref2.recipientsToBeConfirmed,
|
|
37
39
|
recipientsToBeConfirmed = _ref2$recipientsToBeC === void 0 ? [] : _ref2$recipientsToBeC,
|
|
@@ -57,7 +59,7 @@ var WhoHasAccess = function WhoHasAccess(_ref2) {
|
|
|
57
59
|
onRevokeSelf: onRevokeSelf,
|
|
58
60
|
permissions: permissions,
|
|
59
61
|
fadeIn: linkHasBeenJustCreated
|
|
60
|
-
}), /*#__PURE__*/React.createElement(OwnerRecipient, {
|
|
62
|
+
}), showOwner && /*#__PURE__*/React.createElement(OwnerRecipient, {
|
|
61
63
|
recipients: recipients
|
|
62
64
|
}), /*#__PURE__*/React.createElement(RecipientList, {
|
|
63
65
|
recipients: recipients,
|
|
@@ -75,6 +77,7 @@ var WhoHasAccess = function WhoHasAccess(_ref2) {
|
|
|
75
77
|
|
|
76
78
|
WhoHasAccess.propTypes = {
|
|
77
79
|
isOwner: PropTypes.bool,
|
|
80
|
+
showOwner: PropTypes.bool,
|
|
78
81
|
recipients: PropTypes.array.isRequired,
|
|
79
82
|
recipientsToBeConfirmed: PropTypes.arrayOf(PropTypes.shape({
|
|
80
83
|
email: PropTypes.string.isRequired
|
package/dist/helpers/contacts.js
CHANGED
|
@@ -102,4 +102,16 @@ export var getContactsFromGroupId = function getContactsFromGroupId() {
|
|
|
102
102
|
return group._id === groupId;
|
|
103
103
|
});
|
|
104
104
|
});
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Returns true when a contact does not exist. A contact without
|
|
108
|
+
* an `_id` is always a placeholder that must be created before sharing.
|
|
109
|
+
*
|
|
110
|
+
* Used to decide whether the autosuggest input should allow creating
|
|
111
|
+
* a new contact on the fly or should block the pick (depending on the
|
|
112
|
+
* `enableCreateContact` flag).
|
|
113
|
+
*/
|
|
114
|
+
|
|
115
|
+
export var isContactToBeCreated = function isContactToBeCreated(contact) {
|
|
116
|
+
return !contact._id;
|
|
105
117
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cozy-sharing",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "33.0.1",
|
|
4
4
|
"description": "Provides sharing login for React applications.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"author": "Cozy",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"cozy-device-helper": "^4.0.0",
|
|
58
58
|
"cozy-intent": "^2.31.1",
|
|
59
59
|
"cozy-minilog": "^3.10.1",
|
|
60
|
-
"cozy-ui": "^
|
|
60
|
+
"cozy-ui": "^139.0.2",
|
|
61
61
|
"cozy-ui-plus": "^8.0.1",
|
|
62
62
|
"jest": "30.3.0",
|
|
63
63
|
"jest-environment-jsdom": "30.3.0",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"cozy-flags": ">=4.8.1",
|
|
74
74
|
"cozy-intent": ">=2.29.1",
|
|
75
75
|
"cozy-minilog": ">=3.9.1",
|
|
76
|
-
"cozy-ui": ">=
|
|
76
|
+
"cozy-ui": ">=139.0.2",
|
|
77
77
|
"cozy-ui-plus": ">=6.0.0",
|
|
78
78
|
"prop-types": ">=15.7.2",
|
|
79
79
|
"react": ">=16.12.0",
|
|
@@ -83,5 +83,5 @@
|
|
|
83
83
|
"sideEffects": [
|
|
84
84
|
"*.css"
|
|
85
85
|
],
|
|
86
|
-
"gitHead": "
|
|
86
|
+
"gitHead": "546412325d385a075b531e7c735a0082d6864040"
|
|
87
87
|
}
|
|
@@ -8,6 +8,7 @@ import { Spinner } from 'cozy-ui/transpiled/react/Spinner'
|
|
|
8
8
|
|
|
9
9
|
import { GroupAvatar } from './Avatar/GroupAvatar'
|
|
10
10
|
import ContactSuggestion from './ContactSuggestion'
|
|
11
|
+
import { isContactToBeCreated } from '../helpers/contacts'
|
|
11
12
|
import { extractEmails, validateEmail } from '../helpers/email'
|
|
12
13
|
import { getDisplayName, getInitials, Contact, Group } from '../models'
|
|
13
14
|
import styles from '../styles/autosuggest.styl'
|
|
@@ -25,6 +26,7 @@ const ShareAutocomplete = ({
|
|
|
25
26
|
recipients,
|
|
26
27
|
onPick,
|
|
27
28
|
onRemove,
|
|
29
|
+
enableCreateContact,
|
|
28
30
|
placeholder,
|
|
29
31
|
endAdornment
|
|
30
32
|
}) => {
|
|
@@ -53,17 +55,18 @@ const ShareAutocomplete = ({
|
|
|
53
55
|
const onSuggestionsFetchRequested = ({ value }) => {
|
|
54
56
|
const computedSuggestions = computeSuggestions(value)
|
|
55
57
|
|
|
56
|
-
|
|
57
|
-
computedSuggestions
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
58
|
+
if (computedSuggestions.length > 0) {
|
|
59
|
+
setSuggestions(computedSuggestions)
|
|
60
|
+
} else if (enableCreateContact && validateEmail(value)) {
|
|
61
|
+
setSuggestions([
|
|
62
|
+
{
|
|
63
|
+
email: value,
|
|
64
|
+
_type: Contact.doctype
|
|
65
|
+
}
|
|
66
|
+
])
|
|
67
|
+
} else {
|
|
68
|
+
setSuggestions([])
|
|
69
|
+
}
|
|
67
70
|
}
|
|
68
71
|
|
|
69
72
|
const onSuggestionsClearRequested = () => {
|
|
@@ -130,6 +133,8 @@ const ShareAutocomplete = ({
|
|
|
130
133
|
}
|
|
131
134
|
|
|
132
135
|
const onAutosuggestPick = value => {
|
|
136
|
+
if (isContactToBeCreated(value) && !enableCreateContact) return
|
|
137
|
+
|
|
133
138
|
onPick(value)
|
|
134
139
|
setInputValue('')
|
|
135
140
|
autosuggestRef?.current?.input?.focus()
|
|
@@ -228,6 +233,7 @@ ShareAutocomplete.propTypes = {
|
|
|
228
233
|
recipients: PropTypes.array.isRequired,
|
|
229
234
|
onPick: PropTypes.func.isRequired,
|
|
230
235
|
onRemove: PropTypes.func.isRequired,
|
|
236
|
+
enableCreateContact: PropTypes.bool,
|
|
231
237
|
placeholder: PropTypes.string,
|
|
232
238
|
endAdornment: PropTypes.node
|
|
233
239
|
}
|
|
@@ -9,7 +9,12 @@ jest.mock('cozy-ui/transpiled/react/Spinner', () => ({
|
|
|
9
9
|
}))
|
|
10
10
|
|
|
11
11
|
describe('ShareAutosuggest', () => {
|
|
12
|
-
const setup = ({
|
|
12
|
+
const setup = ({
|
|
13
|
+
onPick,
|
|
14
|
+
onRemove,
|
|
15
|
+
loading = false,
|
|
16
|
+
enableCreateContact = true
|
|
17
|
+
}) => {
|
|
13
18
|
render(
|
|
14
19
|
<AppLike>
|
|
15
20
|
<ShareAutosuggest
|
|
@@ -19,6 +24,7 @@ describe('ShareAutosuggest', () => {
|
|
|
19
24
|
onPick={onPick}
|
|
20
25
|
recipients={[]}
|
|
21
26
|
onRemove={onRemove}
|
|
27
|
+
enableCreateContact={enableCreateContact}
|
|
22
28
|
/>
|
|
23
29
|
</AppLike>
|
|
24
30
|
)
|
|
@@ -51,6 +57,19 @@ describe('ShareAutosuggest', () => {
|
|
|
51
57
|
})
|
|
52
58
|
})
|
|
53
59
|
|
|
60
|
+
it('should not call onPick for new contacts when enableCreateContact is false', () => {
|
|
61
|
+
const onPick = jest.fn()
|
|
62
|
+
const onRemove = jest.fn()
|
|
63
|
+
|
|
64
|
+
setup({ onPick, onRemove, enableCreateContact: false })
|
|
65
|
+
|
|
66
|
+
const inputNode = screen.getByPlaceholderText('myPlaceHolder')
|
|
67
|
+
|
|
68
|
+
fireEvent.change(inputNode, { target: { value: 'new@cozycloud.cc' } })
|
|
69
|
+
fireEvent.keyPress(inputNode, { key: 'Enter', keyCode: 13, charCode: 13 })
|
|
70
|
+
expect(onPick).not.toHaveBeenCalled()
|
|
71
|
+
})
|
|
72
|
+
|
|
54
73
|
it('should show loading indicator when loading prop is true (autoFocus triggers onFocus on mount)', () => {
|
|
55
74
|
const onPick = jest.fn()
|
|
56
75
|
const onRemove = jest.fn()
|
|
@@ -21,6 +21,7 @@ export const ShareByEmail = ({
|
|
|
21
21
|
onPendingRecipientsChange,
|
|
22
22
|
selectedOption,
|
|
23
23
|
onSelectedOptionChange,
|
|
24
|
+
enableCreateContact,
|
|
24
25
|
sharing
|
|
25
26
|
}) => {
|
|
26
27
|
const { t } = useI18n()
|
|
@@ -66,6 +67,7 @@ export const ShareByEmail = ({
|
|
|
66
67
|
}
|
|
67
68
|
onPick={onRecipientPick}
|
|
68
69
|
onRemove={onRecipientRemove}
|
|
70
|
+
enableCreateContact={enableCreateContact}
|
|
69
71
|
currentRecipients={currentRecipients}
|
|
70
72
|
recipients={pendingRecipients}
|
|
71
73
|
endAdornment={
|
|
@@ -89,6 +91,7 @@ ShareByEmail.propTypes = {
|
|
|
89
91
|
onPendingRecipientsChange: PropTypes.func.isRequired,
|
|
90
92
|
selectedOption: PropTypes.oneOf(['readWrite', 'readOnly']).isRequired,
|
|
91
93
|
onSelectedOptionChange: PropTypes.func.isRequired,
|
|
94
|
+
enableCreateContact: PropTypes.bool,
|
|
92
95
|
sharing: PropTypes.object
|
|
93
96
|
}
|
|
94
97
|
|
|
@@ -25,6 +25,7 @@ const ShareRecipientsInput = ({
|
|
|
25
25
|
placeholder,
|
|
26
26
|
onPick,
|
|
27
27
|
onRemove,
|
|
28
|
+
enableCreateContact,
|
|
28
29
|
disabled,
|
|
29
30
|
endAdornment
|
|
30
31
|
}) => {
|
|
@@ -114,6 +115,7 @@ const ShareRecipientsInput = ({
|
|
|
114
115
|
recipients={recipients}
|
|
115
116
|
onPick={onPick}
|
|
116
117
|
onRemove={onRemove}
|
|
118
|
+
enableCreateContact={enableCreateContact}
|
|
117
119
|
placeholder={placeholder}
|
|
118
120
|
endAdornment={endAdornment}
|
|
119
121
|
/>
|
|
@@ -126,6 +128,7 @@ ShareRecipientsInput.propTypes = {
|
|
|
126
128
|
placeholder: PropTypes.string,
|
|
127
129
|
onPick: PropTypes.func.isRequired,
|
|
128
130
|
onRemove: PropTypes.func.isRequired,
|
|
131
|
+
enableCreateContact: PropTypes.bool,
|
|
129
132
|
disabled: PropTypes.bool,
|
|
130
133
|
endAdornment: PropTypes.node
|
|
131
134
|
}
|
|
@@ -6,7 +6,7 @@ import Button from 'cozy-ui/transpiled/react/Buttons'
|
|
|
6
6
|
import { FixedDialog } from 'cozy-ui/transpiled/react/CozyDialogs'
|
|
7
7
|
import TextField from 'cozy-ui/transpiled/react/TextField'
|
|
8
8
|
import Typography from 'cozy-ui/transpiled/react/Typography'
|
|
9
|
-
import {
|
|
9
|
+
import { useSubmitWithLoader } from 'cozy-ui/transpiled/react/hooks/useSubmitWithLoader'
|
|
10
10
|
import { useI18n } from 'twake-i18n'
|
|
11
11
|
|
|
12
12
|
import SharedDriveHeader from './SharedDriveHeader'
|
|
@@ -21,62 +21,41 @@ export const EditSharedDriveModal = withLocales(({ onClose, document }) => {
|
|
|
21
21
|
const client = useClient()
|
|
22
22
|
const { t } = useI18n()
|
|
23
23
|
const { share, getRecipients, revoke } = useSharingContext()
|
|
24
|
-
const { showAlert } = useAlert()
|
|
25
24
|
const {
|
|
26
25
|
pendingRecipients,
|
|
27
26
|
setPendingRecipients,
|
|
28
27
|
selectedOption,
|
|
29
28
|
setSelectedOption
|
|
30
29
|
} = usePendingRecipients()
|
|
30
|
+
const { onSubmit, isLoading } = useSubmitWithLoader()
|
|
31
31
|
|
|
32
32
|
const [driveName, setDriveName] = useState(document.name)
|
|
33
|
-
const [isSaving, setIsSaving] = useState(false)
|
|
34
33
|
|
|
35
34
|
const onSave = async () => {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
)
|
|
45
|
-
const readWriteRecipients = selectedOption === 'readOnly' ? [] : contacts
|
|
46
|
-
const readOnlyRecipients = selectedOption === 'readOnly' ? contacts : []
|
|
35
|
+
// We add contacts
|
|
36
|
+
const contacts = await getOrCreateFromArray(
|
|
37
|
+
client,
|
|
38
|
+
pendingRecipients,
|
|
39
|
+
contact => client.create('io.cozy.contacts', contact)
|
|
40
|
+
)
|
|
41
|
+
const readWriteRecipients = selectedOption === 'readOnly' ? [] : contacts
|
|
42
|
+
const readOnlyRecipients = selectedOption === 'readOnly' ? contacts : []
|
|
47
43
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
// We rename the shared drive
|
|
57
|
-
if (document?.name !== driveName) {
|
|
58
|
-
await client.collection('io.cozy.files').update({
|
|
59
|
-
...document,
|
|
60
|
-
name: driveName,
|
|
61
|
-
_rev: document._rev || document.meta.rev
|
|
62
|
-
})
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
showAlert({
|
|
66
|
-
message: t('SharedDrive.editSharedDriveModal.successNotification'),
|
|
67
|
-
severity: 'success',
|
|
68
|
-
variant: 'filled'
|
|
69
|
-
})
|
|
44
|
+
await share({
|
|
45
|
+
document: document,
|
|
46
|
+
recipients: readWriteRecipients,
|
|
47
|
+
readOnlyRecipients,
|
|
48
|
+
sharedDrive: true,
|
|
49
|
+
openSharing: false
|
|
50
|
+
})
|
|
70
51
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
52
|
+
// We rename the shared drive
|
|
53
|
+
if (document?.name !== driveName) {
|
|
54
|
+
await client.collection('io.cozy.files').update({
|
|
55
|
+
...document,
|
|
56
|
+
name: driveName,
|
|
57
|
+
_rev: document._rev || document.meta.rev
|
|
77
58
|
})
|
|
78
|
-
} finally {
|
|
79
|
-
setIsSaving(false)
|
|
80
59
|
}
|
|
81
60
|
}
|
|
82
61
|
|
|
@@ -110,8 +89,8 @@ export const EditSharedDriveModal = withLocales(({ onClose, document }) => {
|
|
|
110
89
|
{t('Share.contacts.addUsers')}
|
|
111
90
|
</Typography>
|
|
112
91
|
<DumbShareByEmail
|
|
113
|
-
currentRecipients={[]}
|
|
114
92
|
documentType="Files"
|
|
93
|
+
currentRecipients={existingRecipients}
|
|
115
94
|
pendingRecipients={pendingRecipients}
|
|
116
95
|
onPendingRecipientsChange={setPendingRecipients}
|
|
117
96
|
selectedOption={selectedOption}
|
|
@@ -121,6 +100,7 @@ export const EditSharedDriveModal = withLocales(({ onClose, document }) => {
|
|
|
121
100
|
<WhoHasAccess
|
|
122
101
|
isOwner
|
|
123
102
|
isSharedDrive
|
|
103
|
+
showOwner={false}
|
|
124
104
|
recipients={existingRecipients}
|
|
125
105
|
document={document}
|
|
126
106
|
documentType="Files"
|
|
@@ -134,14 +114,29 @@ export const EditSharedDriveModal = withLocales(({ onClose, document }) => {
|
|
|
134
114
|
className="u-w-100 u-m-1"
|
|
135
115
|
size="large"
|
|
136
116
|
onClick={onClose}
|
|
117
|
+
disabled={isLoading}
|
|
137
118
|
/>
|
|
138
119
|
<Button
|
|
139
120
|
variant="primary"
|
|
140
121
|
label={t('SharedDrive.sharedDriveModal.save')}
|
|
141
122
|
className="u-w-100 u-m-1"
|
|
142
123
|
size="large"
|
|
143
|
-
|
|
144
|
-
|
|
124
|
+
onClick={() =>
|
|
125
|
+
onSubmit({
|
|
126
|
+
submit: onSave,
|
|
127
|
+
success: {
|
|
128
|
+
action: onClose,
|
|
129
|
+
message: t(
|
|
130
|
+
'SharedDrive.editSharedDriveModal.successNotification'
|
|
131
|
+
)
|
|
132
|
+
},
|
|
133
|
+
error: {
|
|
134
|
+
message: () =>
|
|
135
|
+
t('SharedDrive.editSharedDriveModal.errorNotification')
|
|
136
|
+
}
|
|
137
|
+
})
|
|
138
|
+
}
|
|
139
|
+
busy={isLoading}
|
|
145
140
|
/>
|
|
146
141
|
</div>
|
|
147
142
|
</div>
|
|
@@ -4,6 +4,7 @@ import React from 'react'
|
|
|
4
4
|
import Button from 'cozy-ui/transpiled/react/Buttons'
|
|
5
5
|
import TextField from 'cozy-ui/transpiled/react/TextField'
|
|
6
6
|
import Typography from 'cozy-ui/transpiled/react/Typography'
|
|
7
|
+
import { useSubmitWithLoader } from 'cozy-ui/transpiled/react/hooks/useSubmitWithLoader'
|
|
7
8
|
import { useI18n } from 'twake-i18n'
|
|
8
9
|
|
|
9
10
|
import withLocales from '../../hoc/withLocales'
|
|
@@ -21,7 +22,8 @@ export const SharedDriveForm = withLocales(({ onSuccess, onCancel }) => {
|
|
|
21
22
|
selectedOption,
|
|
22
23
|
setSelectedOption,
|
|
23
24
|
onCreate
|
|
24
|
-
} = useSharedDrive(
|
|
25
|
+
} = useSharedDrive()
|
|
26
|
+
const { onSubmit, isLoading } = useSubmitWithLoader()
|
|
25
27
|
|
|
26
28
|
return (
|
|
27
29
|
<div>
|
|
@@ -55,13 +57,27 @@ export const SharedDriveForm = withLocales(({ onSuccess, onCancel }) => {
|
|
|
55
57
|
className="u-w-100 u-m-1"
|
|
56
58
|
size="large"
|
|
57
59
|
onClick={onCancel}
|
|
60
|
+
disabled={isLoading}
|
|
58
61
|
/>
|
|
59
62
|
<Button
|
|
60
63
|
variant="primary"
|
|
61
64
|
label={t('SharedDrive.sharedDriveModal.create')}
|
|
62
65
|
className="u-w-100 u-m-1"
|
|
63
66
|
size="large"
|
|
64
|
-
onClick={
|
|
67
|
+
onClick={() =>
|
|
68
|
+
onSubmit({
|
|
69
|
+
submit: onCreate,
|
|
70
|
+
success: {
|
|
71
|
+
action: onSuccess,
|
|
72
|
+
message: t('SharedDrive.sharedDriveModal.successNotification')
|
|
73
|
+
},
|
|
74
|
+
error: {
|
|
75
|
+
message: () =>
|
|
76
|
+
t('SharedDrive.sharedDriveModal.errorNotification')
|
|
77
|
+
}
|
|
78
|
+
})
|
|
79
|
+
}
|
|
80
|
+
busy={isLoading}
|
|
65
81
|
/>
|
|
66
82
|
</div>
|
|
67
83
|
</div>
|