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.
Files changed (30) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/components/FederatedFolder/FederatedFolderModal.js +2 -1
  3. package/dist/components/ShareAutosuggest.js +15 -5
  4. package/dist/components/ShareAutosuggest.spec.js +26 -2
  5. package/dist/components/ShareByEmail.js +3 -0
  6. package/dist/components/ShareByEmail.spec.js +2 -1
  7. package/dist/components/ShareDialogCozyToCozy.js +2 -1
  8. package/dist/components/ShareDialogCozyToCozy.spec.js +2 -2
  9. package/dist/components/ShareRecipientsInput.js +3 -0
  10. package/dist/components/SharedDrive/EditSharedDriveModal.js +32 -55
  11. package/dist/components/SharedDrive/SharedDriveForm.js +23 -5
  12. package/dist/components/SharedDrive/useSharedDrive.js +8 -37
  13. package/dist/components/SharedDrive/useSharedDrive.spec.js +8 -81
  14. package/dist/components/WhoHasAccess.js +4 -1
  15. package/dist/helpers/contacts.js +12 -0
  16. package/package.json +4 -4
  17. package/src/components/FederatedFolder/FederatedFolderModal.jsx +1 -0
  18. package/src/components/ShareAutosuggest.jsx +17 -11
  19. package/src/components/ShareAutosuggest.spec.jsx +20 -1
  20. package/src/components/ShareByEmail.jsx +3 -0
  21. package/src/components/ShareByEmail.spec.jsx +1 -0
  22. package/src/components/ShareDialogCozyToCozy.jsx +1 -0
  23. package/src/components/ShareDialogCozyToCozy.spec.jsx +1 -0
  24. package/src/components/ShareRecipientsInput.jsx +3 -0
  25. package/src/components/SharedDrive/EditSharedDriveModal.jsx +42 -47
  26. package/src/components/SharedDrive/SharedDriveForm.jsx +18 -2
  27. package/src/components/SharedDrive/useSharedDrive.js +15 -35
  28. package/src/components/SharedDrive/useSharedDrive.spec.js +4 -39
  29. package/src/components/WhoHasAccess.jsx +3 -1
  30. 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 and onSuccess', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
91
- var onSuccess, _renderHook3, result;
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 = 6;
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 6:
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 9:
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
@@ -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": "32.3.2",
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": "^138.1.0",
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": ">=138.1.0",
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": "5fd20886ef0dfec91783b81bce0ae59d210a0cfa"
86
+ "gitHead": "546412325d385a075b531e7c735a0082d6864040"
87
87
  }
@@ -206,6 +206,7 @@ const FederatedFolderModalContent = ({
206
206
  onPendingRecipientsChange={setPendingRecipients}
207
207
  selectedOption={selectedOption}
208
208
  onSelectedOptionChange={setSelectedOption}
209
+ enableCreateContact
209
210
  />
210
211
  </div>
211
212
  <WhoHasAccess
@@ -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
- const newSuggestions =
57
- computedSuggestions.length === 0 && validateEmail(value)
58
- ? [
59
- {
60
- email: value,
61
- _type: Contact.doctype
62
- }
63
- ]
64
- : computedSuggestions
65
-
66
- setSuggestions(newSuggestions)
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 = ({ onPick, onRemove, loading = false }) => {
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
 
@@ -17,6 +17,7 @@ describe('ShareByEmail (controlled)', () => {
17
17
  onPendingRecipientsChange,
18
18
  selectedOption: 'readWrite',
19
19
  onSelectedOptionChange,
20
+ enableCreateContact: true,
20
21
  ...overrides
21
22
  }
22
23
  const utils = render(
@@ -79,6 +79,7 @@ const SharingContent = ({
79
79
  onPendingRecipientsChange={onPendingRecipientsChange}
80
80
  selectedOption={selectedOption}
81
81
  onSelectedOptionChange={onSelectedOptionChange}
82
+ enableCreateContact
82
83
  />
83
84
  )}
84
85
  </div>
@@ -21,6 +21,7 @@ jest.mock('../hooks/useSharingContext', () => ({
21
21
  }))
22
22
 
23
23
  jest.mock('../helpers/contacts', () => ({
24
+ ...jest.requireActual('../helpers/contacts'),
24
25
  getOrCreateFromArray: jest.fn((client, recipients) =>
25
26
  Promise.resolve(recipients)
26
27
  )
@@ -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 { useAlert } from 'cozy-ui/transpiled/react/providers/Alert'
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
- if (isSaving) return
37
- setIsSaving(true)
38
- try {
39
- // We add contacts
40
- const contacts = await getOrCreateFromArray(
41
- client,
42
- pendingRecipients,
43
- contact => client.create('io.cozy.contacts', contact)
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
- await share({
49
- document: document,
50
- recipients: readWriteRecipients,
51
- readOnlyRecipients,
52
- sharedDrive: true,
53
- openSharing: false
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
- onClose()
72
- } catch (_err) {
73
- showAlert({
74
- message: t('SharedDrive.editSharedDriveModal.errorNotification'),
75
- severity: 'error',
76
- variant: 'filled'
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
- disabled={isSaving}
144
- onClick={onSave}
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({ onSuccess })
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={onCreate}
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>