cozy-harvest-lib 8.1.0 → 8.2.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 (28) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/components/AccountModal.js +5 -4
  3. package/dist/components/AccountModal.spec.js +4 -1
  4. package/dist/components/AccountsListModal.js +3 -2
  5. package/dist/components/EditAccountModal.js +3 -3
  6. package/dist/components/HarvestModalRoot.js +3 -3
  7. package/dist/components/KonnectorConfiguration/ConfigurationTab/index.js +2 -2
  8. package/dist/components/MountPointContext.js +24 -10
  9. package/dist/components/MountPointContext.spec.js +17 -17
  10. package/dist/components/NewAccountModal.js +3 -3
  11. package/dist/components/NewAccountModal.spec.js +6 -6
  12. package/dist/components/RedirectToAccountFormButton.js +3 -3
  13. package/dist/components/RedirectToAccountFormButton.spec.js +4 -4
  14. package/dist/components/cards/AppLinkCard.js +2 -1
  15. package/package.json +3 -3
  16. package/src/components/AccountModal.jsx +5 -4
  17. package/src/components/AccountModal.spec.jsx +7 -2
  18. package/src/components/AccountsListModal.jsx +2 -2
  19. package/src/components/EditAccountModal.jsx +3 -3
  20. package/src/components/HarvestModalRoot.jsx +3 -3
  21. package/src/components/KonnectorConfiguration/ConfigurationTab/index.jsx +2 -2
  22. package/src/components/MountPointContext.jsx +29 -12
  23. package/src/components/MountPointContext.spec.jsx +17 -17
  24. package/src/components/NewAccountModal.jsx +3 -3
  25. package/src/components/NewAccountModal.spec.jsx +6 -6
  26. package/src/components/RedirectToAccountFormButton.jsx +3 -3
  27. package/src/components/RedirectToAccountFormButton.spec.jsx +4 -4
  28. package/src/components/cards/AppLinkCard.jsx +2 -1
package/CHANGELOG.md CHANGED
@@ -3,6 +3,40 @@
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
+ ## [8.2.1](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@8.2.0...cozy-harvest-lib@8.2.1) (2022-04-13)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * Get correct bi mapping for bnp_es and cic_es ([f304f89](https://github.com/cozy/cozy-libs/commit/f304f8978f1857f3f1d1e74c0c19385ab96dde24))
12
+
13
+
14
+
15
+
16
+
17
+ # [8.2.0](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@8.1.1...cozy-harvest-lib@8.2.0) (2022-04-13)
18
+
19
+
20
+ ### Features
21
+
22
+ * Fix back navigation ([89283ab](https://github.com/cozy/cozy-libs/commit/89283ab1beb06fa15625a7f108abbddf37216397))
23
+
24
+
25
+
26
+
27
+
28
+ ## [8.1.1](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@8.1.0...cozy-harvest-lib@8.1.1) (2022-04-11)
29
+
30
+
31
+ ### Bug Fixes
32
+
33
+ * **cozy-harvest-lib:** Correctly handle onClick on AppLinkCard ([c9068c5](https://github.com/cozy/cozy-libs/commit/c9068c53a1ec2e1f6b9b7636f6b25aadec69900f))
34
+ * **cozy-harvest-lib:** Disable AppLink button until fallback is resolved ([bedc90d](https://github.com/cozy/cozy-libs/commit/bedc90d80c899bb93a2be70d6963d62742fb600b))
35
+
36
+
37
+
38
+
39
+
6
40
  # [8.1.0](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@8.0.0...cozy-harvest-lib@8.1.0) (2022-04-08)
7
41
 
8
42
 
@@ -26,7 +26,7 @@ import * as triggersModel from '../helpers/triggers';
26
26
  import KonnectorAccountTabs from './KonnectorConfiguration/KonnectorAccountTabs';
27
27
  import AccountSelectBox from './AccountSelectBox/AccountSelectBox';
28
28
  import KonnectorModalHeader from './KonnectorModalHeader';
29
- import { withMountPointPushHistory } from './MountPointContext';
29
+ import { withMountPointHistory } from './MountPointContext';
30
30
  import withLocales from './hoc/withLocales';
31
31
  import DialogContent from '@material-ui/core/DialogContent';
32
32
  /**
@@ -247,6 +247,7 @@ export var AccountModal = /*#__PURE__*/function (_Component) {
247
247
  accountsAndTriggers = _this$props2.accountsAndTriggers,
248
248
  t = _this$props2.t,
249
249
  pushHistory = _this$props2.pushHistory,
250
+ replaceHistory = _this$props2.replaceHistory,
250
251
  initialActiveTab = _this$props2.initialActiveTab,
251
252
  isMobile = _this$props2.breakpoints.isMobile,
252
253
  showAccountSelection = _this$props2.showAccountSelection,
@@ -293,7 +294,7 @@ export var AccountModal = /*#__PURE__*/function (_Component) {
293
294
  account: account,
294
295
  onAccountDeleted: onDismiss,
295
296
  addAccount: function addAccount() {
296
- return pushHistory('/new');
297
+ return replaceHistory('/new');
297
298
  },
298
299
  showNewAccountButton: showNewAccountButton
299
300
  })));
@@ -324,7 +325,7 @@ AccountModal.propTypes = {
324
325
  trigger: PropTypes.object.isRequired
325
326
  })).isRequired,
326
327
  t: PropTypes.func.isRequired,
327
- pushHistory: PropTypes.func.isRequired,
328
+ replaceHistory: PropTypes.func.isRequired,
328
329
  accountId: PropTypes.string.isRequired,
329
330
 
330
331
  /** @type {string} Can be set to force the initial active tab */
@@ -336,4 +337,4 @@ AccountModal.propTypes = {
336
337
  /** @type {Boolean} Whether to show the button to add a new account */
337
338
  showNewAccountButton: PropTypes.bool
338
339
  };
339
- export default flow(withClient, withLocales, withMountPointPushHistory, withBreakpoints())(AccountModal);
340
+ export default flow(withClient, withLocales, withMountPointHistory, withBreakpoints())(AccountModal);
@@ -38,6 +38,7 @@ var accountIdMock = '123';
38
38
  describe('AccountModal', function () {
39
39
  var setup = function setup() {
40
40
  var mockHistoryPush = jest.fn();
41
+ var mockHistoryReplace = jest.fn();
41
42
  var component = shallow( /*#__PURE__*/React.createElement(AccountModal, {
42
43
  konnector: {},
43
44
  t: function t(x) {
@@ -46,6 +47,7 @@ describe('AccountModal', function () {
46
47
  accountId: accountIdMock,
47
48
  accountsAndTriggers: accountsAndTriggersMock,
48
49
  pushHistory: mockHistoryPush,
50
+ replaceHistory: mockHistoryReplace,
49
51
  breakpoints: {
50
52
  isMobile: true
51
53
  },
@@ -53,7 +55,8 @@ describe('AccountModal', function () {
53
55
  }));
54
56
  return {
55
57
  component: component,
56
- mockHistoryPush: mockHistoryPush
58
+ mockHistoryPush: mockHistoryPush,
59
+ mockHistoryReplace: mockHistoryReplace
57
60
  };
58
61
  };
59
62
 
@@ -13,7 +13,8 @@ var AccountsListModal = function AccountsListModal(_ref) {
13
13
  t = _ref.t;
14
14
 
15
15
  var _useContext = useContext(MountPointContext),
16
- pushHistory = _useContext.pushHistory;
16
+ pushHistory = _useContext.pushHistory,
17
+ replaceHistory = _useContext.replaceHistory;
17
18
 
18
19
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(DialogContent, null, /*#__PURE__*/React.createElement(Stack, {
19
20
  className: "u-mb-3"
@@ -29,7 +30,7 @@ var AccountsListModal = function AccountsListModal(_ref) {
29
30
  accounts: accounts,
30
31
  konnector: konnector,
31
32
  onPick: function onPick(option) {
32
- return pushHistory("/accounts/".concat(option.account._id));
33
+ return replaceHistory("/accounts/".concat(option.account._id));
33
34
  },
34
35
  addAccount: function addAccount() {
35
36
  return pushHistory('/new');
@@ -27,7 +27,7 @@ import { DialogCloseButton, useCozyDialog } from 'cozy-ui/transpiled/react/CozyD
27
27
  import { fetchAccount as _fetchAccount } from '../connections/accounts';
28
28
  import * as triggersModel from '../helpers/triggers';
29
29
  import TriggerManager from './TriggerManager';
30
- import { withMountPointPushHistory } from './MountPointContext';
30
+ import { withMountPointHistory } from './MountPointContext';
31
31
  import logger from '../logger';
32
32
  import { withTracker } from './hoc/tracking';
33
33
  import useTimeout from './hooks/useTimeout';
@@ -213,7 +213,7 @@ export var EditAccountModal = /*#__PURE__*/function (_Component) {
213
213
  var account = this.state.account;
214
214
 
215
215
  if (account) {
216
- this.props.pushHistory("/accounts/".concat(account._id));
216
+ this.props.replaceHistory("/accounts/".concat(account._id));
217
217
  } else {
218
218
  this.props.pushHistory("/accounts");
219
219
  }
@@ -255,4 +255,4 @@ EditAccountModal.propTypes = {
255
255
  accounts: PropTypes.array.isRequired,
256
256
  reconnect: PropTypes.bool
257
257
  };
258
- export default flow(withClient, withMountPointPushHistory, withTracker)(EditAccountModal);
258
+ export default flow(withClient, withMountPointHistory, withTracker)(EditAccountModal);
@@ -8,13 +8,13 @@ var HarvestModalRoot = function HarvestModalRoot(_ref) {
8
8
  konnector = _ref.konnector;
9
9
 
10
10
  var _useContext = useContext(MountPointContext),
11
- pushHistory = _useContext.pushHistory;
11
+ replaceHistory = _useContext.replaceHistory;
12
12
 
13
13
  if (accounts.length === 0) {
14
- pushHistory('/new');
14
+ replaceHistory('/new');
15
15
  return null;
16
16
  } else if (accounts.length === 1) {
17
- pushHistory("/accounts/".concat(accounts[0].account._id));
17
+ replaceHistory("/accounts/".concat(accounts[0].account._id));
18
18
  return null;
19
19
  } else {
20
20
  return /*#__PURE__*/React.createElement(AccountsListModal, {
@@ -76,7 +76,7 @@ var ConfigurationTab = function ConfigurationTab(_ref2) {
76
76
  isMobile = _useBreakpoints.isMobile;
77
77
 
78
78
  var _useContext = useContext(MountPointContext),
79
- pushHistory = _useContext.pushHistory;
79
+ replaceHistory = _useContext.replaceHistory;
80
80
 
81
81
  var client = useClient();
82
82
  var vaultClient = useVaultClient();
@@ -238,7 +238,7 @@ var ConfigurationTab = function ConfigurationTab(_ref2) {
238
238
  button: true,
239
239
  divider: true,
240
240
  onClick: function onClick() {
241
- return pushHistory("/accounts/".concat(account._id, "/edit"));
241
+ return replaceHistory("/accounts/".concat(account._id, "/edit"));
242
242
  }
243
243
  }, /*#__PURE__*/React.createElement(ListItemIcon, null, /*#__PURE__*/React.createElement(Icon, {
244
244
  icon: KeyIcon,
@@ -26,20 +26,32 @@ export var RawMountPointProvider = /*#__PURE__*/function (_React$Component) {
26
26
 
27
27
  _this = _super.call(this, props);
28
28
  _this.pushHistory = _this.pushHistory.bind(_assertThisInitialized(_this));
29
+ _this.replaceHistory = _this.replaceHistory.bind(_assertThisInitialized(_this));
29
30
  _this.state = {
30
31
  baseRoute: props.baseRoute || '/',
31
- pushHistory: _this.pushHistory
32
+ pushHistory: _this.pushHistory,
33
+ replaceHistory: _this.replaceHistory
32
34
  };
33
35
  return _this;
34
36
  }
35
37
 
36
38
  _createClass(RawMountPointProvider, [{
37
- key: "pushHistory",
38
- value: function pushHistory(route) {
39
+ key: "historyAction",
40
+ value: function historyAction(route, method) {
39
41
  var history = this.props.history;
40
42
  var baseRoute = this.state.baseRoute;
41
- var segments = baseRoute.split('/').concat(route.split('/')).filter(Boolean);
42
- history.push("/".concat(segments.join('/')));
43
+ var segments = '/'.concat(baseRoute.split('/').concat(route.split('/')).filter(Boolean).join('/'));
44
+ history[method](segments);
45
+ }
46
+ }, {
47
+ key: "pushHistory",
48
+ value: function pushHistory(route) {
49
+ this.historyAction(route, 'push');
50
+ }
51
+ }, {
52
+ key: "replaceHistory",
53
+ value: function replaceHistory(route) {
54
+ this.historyAction(route, 'replace');
43
55
  }
44
56
  }, {
45
57
  key: "render",
@@ -57,19 +69,21 @@ RawMountPointProvider.propTypes = {
57
69
  history: PropTypes.object
58
70
  };
59
71
 
60
- var withMountPointPushHistory = function withMountPointPushHistory(BaseComponent) {
72
+ var withMountPointHistory = function withMountPointHistory(BaseComponent) {
61
73
  var Component = function Component(props) {
62
74
  var _useContext = useContext(MountPointContext),
63
- pushHistory = _useContext.pushHistory;
75
+ pushHistory = _useContext.pushHistory,
76
+ replaceHistory = _useContext.replaceHistory;
64
77
 
65
78
  return /*#__PURE__*/React.createElement(BaseComponent, _extends({
66
- pushHistory: pushHistory
79
+ pushHistory: pushHistory,
80
+ replaceHistory: replaceHistory
67
81
  }, props));
68
82
  };
69
83
 
70
- Component.displayName = "withMountPointPushHistory(".concat(BaseComponent.displayName || BaseComponent.name, ")");
84
+ Component.displayName = "withMountPointHistory(".concat(BaseComponent.displayName || BaseComponent.name, ")");
71
85
  return Component;
72
86
  };
73
87
 
74
88
  var MountPointProvider = withRouter(RawMountPointProvider);
75
- export { MountPointContext, MountPointProvider, withMountPointPushHistory };
89
+ export { MountPointContext, MountPointProvider, withMountPointHistory };
@@ -3,7 +3,7 @@ import { shallow } from 'enzyme';
3
3
  import { RawMountPointProvider } from 'components/MountPointContext';
4
4
  describe('MountPointProvider', function () {
5
5
  var historyMock = {
6
- push: jest.fn()
6
+ replace: jest.fn()
7
7
  };
8
8
  beforeEach(function () {
9
9
  jest.resetAllMocks();
@@ -13,33 +13,33 @@ describe('MountPointProvider', function () {
13
13
  baseRoute: "/root",
14
14
  history: historyMock
15
15
  }));
16
- component.instance().pushHistory('/one');
17
- expect(historyMock.push).toHaveBeenCalledWith('/root/one');
18
- component.instance().pushHistory('/one/two');
19
- expect(historyMock.push).toHaveBeenCalledWith('/root/one/two');
20
- component.instance().pushHistory('no/slash');
21
- expect(historyMock.push).toHaveBeenCalledWith('/root/no/slash');
22
- component.instance().pushHistory('too/many///slashes');
23
- expect(historyMock.push).toHaveBeenCalledWith('/root/too/many/slashes');
16
+ component.instance().replaceHistory('/one');
17
+ expect(historyMock.replace).toHaveBeenCalledWith('/root/one');
18
+ component.instance().replaceHistory('/one/two');
19
+ expect(historyMock.replace).toHaveBeenCalledWith('/root/one/two');
20
+ component.instance().replaceHistory('no/slash');
21
+ expect(historyMock.replace).toHaveBeenCalledWith('/root/no/slash');
22
+ component.instance().replaceHistory('too/many///slashes');
23
+ expect(historyMock.replace).toHaveBeenCalledWith('/root/too/many/slashes');
24
24
  });
25
25
  it('should handle a trailing slash in the base route', function () {
26
26
  var component = shallow( /*#__PURE__*/React.createElement(RawMountPointProvider, {
27
27
  baseRoute: "/root/",
28
28
  history: historyMock
29
29
  }));
30
- component.instance().pushHistory('/one');
31
- expect(historyMock.push).toHaveBeenCalledWith('/root/one');
32
- component.instance().pushHistory('no/slash');
33
- expect(historyMock.push).toHaveBeenCalledWith('/root/no/slash');
30
+ component.instance().replaceHistory('/one');
31
+ expect(historyMock.replace).toHaveBeenCalledWith('/root/one');
32
+ component.instance().replaceHistory('no/slash');
33
+ expect(historyMock.replace).toHaveBeenCalledWith('/root/no/slash');
34
34
  });
35
35
  it('should handle a base route with multiple segments', function () {
36
36
  var component = shallow( /*#__PURE__*/React.createElement(RawMountPointProvider, {
37
37
  baseRoute: "/base/route/",
38
38
  history: historyMock
39
39
  }));
40
- component.instance().pushHistory('/one');
41
- expect(historyMock.push).toHaveBeenCalledWith('/base/route/one');
42
- component.instance().pushHistory('/one/two');
43
- expect(historyMock.push).toHaveBeenCalledWith('/base/route/one/two');
40
+ component.instance().replaceHistory('/one');
41
+ expect(historyMock.replace).toHaveBeenCalledWith('/base/route/one');
42
+ component.instance().replaceHistory('/one/two');
43
+ expect(historyMock.replace).toHaveBeenCalledWith('/base/route/one/two');
44
44
  });
45
45
  });
@@ -32,7 +32,7 @@ var NewAccountModal = function NewAccountModal(_ref) {
32
32
  var client = useClient();
33
33
 
34
34
  var _useContext = useContext(MountPointContext),
35
- pushHistory = _useContext.pushHistory;
35
+ replaceHistory = _useContext.replaceHistory;
36
36
 
37
37
  var _useMaintenanceStatus = useMaintenanceStatus(client, konnector),
38
38
  fetchStatus = _useMaintenanceStatus.fetchStatus,
@@ -78,7 +78,7 @@ var NewAccountModal = function NewAccountModal(_ref) {
78
78
  path += '/success';
79
79
  }
80
80
 
81
- pushHistory(path);
81
+ replaceHistory(path);
82
82
  },
83
83
  onSuccess: function onSuccess(trigger) {
84
84
  var accountId = triggersModel.getAccountId(trigger);
@@ -88,7 +88,7 @@ var NewAccountModal = function NewAccountModal(_ref) {
88
88
  path += '/success';
89
89
  }
90
90
 
91
- pushHistory(path);
91
+ replaceHistory(path);
92
92
  },
93
93
  onVaultDismiss: onDismiss,
94
94
  fieldOptions: fieldOptions
@@ -27,9 +27,9 @@ jest.mock('./DialogContext', function () {
27
27
  };
28
28
  });
29
29
  describe('NewAccountModal', function () {
30
- var pushHistory = jest.fn();
30
+ var replaceHistory = jest.fn();
31
31
  var mountPointContextValue = {
32
- pushHistory: pushHistory
32
+ replaceHistory: replaceHistory
33
33
  };
34
34
  var konnectorTrigger = {
35
35
  worker: 'konnector',
@@ -58,7 +58,7 @@ describe('NewAccountModal', function () {
58
58
  }
59
59
  }))));
60
60
  onLoginSuccessFn(konnectorTrigger);
61
- expect(pushHistory).toHaveBeenCalledWith('/accounts/accountNumber/success');
61
+ expect(replaceHistory).toHaveBeenCalledWith('/accounts/accountNumber/success');
62
62
  });
63
63
  it('should redirect to route without success on login success for client triggers', function () {
64
64
  render( /*#__PURE__*/React.createElement(AppLike, {
@@ -72,7 +72,7 @@ describe('NewAccountModal', function () {
72
72
  }
73
73
  }))));
74
74
  onLoginSuccessFn(clientTrigger);
75
- expect(pushHistory).toHaveBeenCalledWith('/accounts/accountNumberClient');
75
+ expect(replaceHistory).toHaveBeenCalledWith('/accounts/accountNumberClient');
76
76
  });
77
77
  it('should redirect to success route on success for non client triggers', function () {
78
78
  render( /*#__PURE__*/React.createElement(AppLike, {
@@ -86,7 +86,7 @@ describe('NewAccountModal', function () {
86
86
  }
87
87
  }))));
88
88
  onSuccessFn(konnectorTrigger);
89
- expect(pushHistory).toHaveBeenCalledWith('/accounts/accountNumber/success');
89
+ expect(replaceHistory).toHaveBeenCalledWith('/accounts/accountNumber/success');
90
90
  });
91
91
  it('should redirect to route without success on success for client triggers', function () {
92
92
  render( /*#__PURE__*/React.createElement(AppLike, {
@@ -100,6 +100,6 @@ describe('NewAccountModal', function () {
100
100
  }
101
101
  }))));
102
102
  onSuccessFn(clientTrigger);
103
- expect(pushHistory).toHaveBeenCalledWith('/accounts/accountNumberClient');
103
+ expect(replaceHistory).toHaveBeenCalledWith('/accounts/accountNumberClient');
104
104
  });
105
105
  });
@@ -13,11 +13,11 @@ var RedirectToAccountFormButton = function RedirectToAccountFormButton(_ref) {
13
13
  var accountId = getAccountId(trigger);
14
14
 
15
15
  var _useContext = useContext(MountPointContext),
16
- pushHistory = _useContext.pushHistory;
16
+ replaceHistory = _useContext.replaceHistory;
17
17
 
18
18
  var handleClick = useCallback(function () {
19
- pushHistory("/accounts/".concat(accountId, "/edit?reconnect"));
20
- }, [accountId, pushHistory]);
19
+ replaceHistory("/accounts/".concat(accountId, "/edit?reconnect"));
20
+ }, [accountId, replaceHistory]);
21
21
  return /*#__PURE__*/React.createElement(Button, {
22
22
  className: "u-ml-0",
23
23
  theme: "secondary",
@@ -4,10 +4,10 @@ import { MountPointContext } from './MountPointContext';
4
4
  import RedirectToAccountFormButton from './RedirectToAccountFormButton';
5
5
  import AppLike from '../../test/AppLike';
6
6
  describe('redirect to account form button', function () {
7
- it('should use pushHistory to navigate', function () {
8
- var pushHistory = jest.fn();
7
+ it('should use replaceHistory to navigate', function () {
8
+ var replaceHistory = jest.fn();
9
9
  var mountPointContextValue = {
10
- pushHistory: pushHistory
10
+ replaceHistory: replaceHistory
11
11
  };
12
12
  var trigger = {
13
13
  message: {
@@ -20,6 +20,6 @@ describe('redirect to account form button', function () {
20
20
  trigger: trigger
21
21
  }))));
22
22
  fireEvent.click(root.getByText('Reconnect'));
23
- expect(pushHistory).toHaveBeenCalledWith('/accounts/account-id-1337/edit?reconnect');
23
+ expect(replaceHistory).toHaveBeenCalledWith('/accounts/account-id-1337/edit?reconnect');
24
24
  });
25
25
  });
@@ -41,7 +41,8 @@ export var AppLinkButton = function AppLinkButton(_ref) {
41
41
  var onClick = _ref2.onClick,
42
42
  href = _ref2.href;
43
43
  return /*#__PURE__*/React.createElement(ButtonLink, {
44
- onClick: fetchStatus !== 'loaded' ? onClick : null,
44
+ disabled: fetchStatus !== 'loaded',
45
+ onClick: fetchStatus === 'loaded' ? onClick : null,
45
46
  href: href,
46
47
  icon: isInstalled ? /*#__PURE__*/React.createElement(AppIcon, {
47
48
  app: slug,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-harvest-lib",
3
- "version": "8.1.0",
3
+ "version": "8.2.1",
4
4
  "description": "Provides logic, modules and components for Cozy's harvest applications.",
5
5
  "main": "dist/index.js",
6
6
  "author": "Cozy",
@@ -28,7 +28,7 @@
28
28
  "dependencies": {
29
29
  "@cozy/minilog": "^1.0.0",
30
30
  "@sentry/browser": "^6.0.1",
31
- "cozy-bi-auth": "0.0.24",
31
+ "cozy-bi-auth": "0.0.25",
32
32
  "cozy-doctypes": "^1.83.7",
33
33
  "cozy-logger": "^1.9.0",
34
34
  "date-fns": "^1.30.1",
@@ -85,5 +85,5 @@
85
85
  "react-router-dom": "^5.0.1"
86
86
  },
87
87
  "sideEffects": false,
88
- "gitHead": "7d830a3634199b430803344cad471783baac1bd5"
88
+ "gitHead": "34e61fe01b642f5a6640a52d70383ead998fdb70"
89
89
  }
@@ -14,7 +14,7 @@ import * as triggersModel from '../helpers/triggers'
14
14
  import KonnectorAccountTabs from './KonnectorConfiguration/KonnectorAccountTabs'
15
15
  import AccountSelectBox from './AccountSelectBox/AccountSelectBox'
16
16
  import KonnectorModalHeader from './KonnectorModalHeader'
17
- import { withMountPointPushHistory } from './MountPointContext'
17
+ import { withMountPointHistory } from './MountPointContext'
18
18
  import withLocales from './hoc/withLocales'
19
19
  import DialogContent from '@material-ui/core/DialogContent'
20
20
 
@@ -109,6 +109,7 @@ export class AccountModal extends Component {
109
109
  accountsAndTriggers,
110
110
  t,
111
111
  pushHistory,
112
+ replaceHistory,
112
113
  initialActiveTab,
113
114
  breakpoints: { isMobile },
114
115
  showAccountSelection,
@@ -164,7 +165,7 @@ export class AccountModal extends Component {
164
165
  initialTrigger={trigger}
165
166
  account={account}
166
167
  onAccountDeleted={onDismiss}
167
- addAccount={() => pushHistory('/new')}
168
+ addAccount={() => replaceHistory('/new')}
168
169
  showNewAccountButton={showNewAccountButton}
169
170
  />
170
171
  </DialogContent>
@@ -197,7 +198,7 @@ AccountModal.propTypes = {
197
198
  })
198
199
  ).isRequired,
199
200
  t: PropTypes.func.isRequired,
200
- pushHistory: PropTypes.func.isRequired,
201
+ replaceHistory: PropTypes.func.isRequired,
201
202
  accountId: PropTypes.string.isRequired,
202
203
 
203
204
  /** @type {string} Can be set to force the initial active tab */
@@ -213,6 +214,6 @@ AccountModal.propTypes = {
213
214
  export default flow(
214
215
  withClient,
215
216
  withLocales,
216
- withMountPointPushHistory,
217
+ withMountPointHistory,
217
218
  withBreakpoints()
218
219
  )(AccountModal)
@@ -37,6 +37,8 @@ const accountIdMock = '123'
37
37
  describe('AccountModal', () => {
38
38
  const setup = () => {
39
39
  const mockHistoryPush = jest.fn()
40
+ const mockHistoryReplace = jest.fn()
41
+
40
42
  const component = shallow(
41
43
  <AccountModal
42
44
  konnector={{}}
@@ -44,11 +46,12 @@ describe('AccountModal', () => {
44
46
  accountId={accountIdMock}
45
47
  accountsAndTriggers={accountsAndTriggersMock}
46
48
  pushHistory={mockHistoryPush}
49
+ replaceHistory={mockHistoryReplace}
47
50
  breakpoints={{ isMobile: true }}
48
51
  onDismiss={jest.fn()}
49
52
  />
50
53
  )
51
- return { component, mockHistoryPush }
54
+ return { component, mockHistoryPush, mockHistoryReplace }
52
55
  }
53
56
 
54
57
  it('should display the fetching state by default', () => {
@@ -62,7 +65,9 @@ describe('AccountModal', () => {
62
65
  name: 'account 1'
63
66
  })
64
67
 
65
- const { component, mockHistoryPush } = setup({ fetchAccount })
68
+ const { component, mockHistoryPush } = setup({
69
+ fetchAccount
70
+ })
66
71
 
67
72
  it('should display the AccountSelect & Content if an account is there and we can change the selectedAccount', async () => {
68
73
  await component.instance().componentDidMount()
@@ -8,7 +8,7 @@ import { MountPointContext } from './MountPointContext'
8
8
  import DialogContent from '@material-ui/core/DialogContent'
9
9
 
10
10
  const AccountsListModal = ({ konnector, accounts, t }) => {
11
- const { pushHistory } = useContext(MountPointContext)
11
+ const { pushHistory, replaceHistory } = useContext(MountPointContext)
12
12
  return (
13
13
  <>
14
14
  <DialogContent>
@@ -23,7 +23,7 @@ const AccountsListModal = ({ konnector, accounts, t }) => {
23
23
  <AccountsList
24
24
  accounts={accounts}
25
25
  konnector={konnector}
26
- onPick={option => pushHistory(`/accounts/${option.account._id}`)}
26
+ onPick={option => replaceHistory(`/accounts/${option.account._id}`)}
27
27
  addAccount={() => pushHistory('/new')}
28
28
  />
29
29
  </DialogContent>
@@ -19,7 +19,7 @@ import {
19
19
  import { fetchAccount } from '../connections/accounts'
20
20
  import * as triggersModel from '../helpers/triggers'
21
21
  import TriggerManager from './TriggerManager'
22
- import { withMountPointPushHistory } from './MountPointContext'
22
+ import { withMountPointHistory } from './MountPointContext'
23
23
  import logger from '../logger'
24
24
  import { withTracker } from './hoc/tracking'
25
25
  import useTimeout from './hooks/useTimeout'
@@ -164,7 +164,7 @@ export class EditAccountModal extends Component {
164
164
  redirectToAccount() {
165
165
  const { account } = this.state
166
166
  if (account) {
167
- this.props.pushHistory(`/accounts/${account._id}`)
167
+ this.props.replaceHistory(`/accounts/${account._id}`)
168
168
  } else {
169
169
  this.props.pushHistory(`/accounts`)
170
170
  }
@@ -203,6 +203,6 @@ EditAccountModal.propTypes = {
203
203
 
204
204
  export default flow(
205
205
  withClient,
206
- withMountPointPushHistory,
206
+ withMountPointHistory,
207
207
  withTracker
208
208
  )(EditAccountModal)
@@ -4,12 +4,12 @@ import AccountsListModal from './AccountsListModal'
4
4
  import { MountPointContext } from './MountPointContext'
5
5
 
6
6
  const HarvestModalRoot = ({ accounts, konnector }) => {
7
- const { pushHistory } = useContext(MountPointContext)
7
+ const { replaceHistory } = useContext(MountPointContext)
8
8
  if (accounts.length === 0) {
9
- pushHistory('/new')
9
+ replaceHistory('/new')
10
10
  return null
11
11
  } else if (accounts.length === 1) {
12
- pushHistory(`/accounts/${accounts[0].account._id}`)
12
+ replaceHistory(`/accounts/${accounts[0].account._id}`)
13
13
  return null
14
14
  } else {
15
15
  return <AccountsListModal konnector={konnector} accounts={accounts} />
@@ -78,7 +78,7 @@ const ConfigurationTab = ({
78
78
  }) => {
79
79
  const { t } = useI18n()
80
80
  const { isMobile } = useBreakpoints()
81
- const { pushHistory } = useContext(MountPointContext)
81
+ const { replaceHistory } = useContext(MountPointContext)
82
82
  const client = useClient()
83
83
  const vaultClient = useVaultClient()
84
84
  const [deleting, setDeleting] = useSafeState(false)
@@ -169,7 +169,7 @@ const ConfigurationTab = ({
169
169
  <ListItem
170
170
  button
171
171
  divider
172
- onClick={() => pushHistory(`/accounts/${account._id}/edit`)}
172
+ onClick={() => replaceHistory(`/accounts/${account._id}/edit`)}
173
173
  >
174
174
  <ListItemIcon>
175
175
  <Icon icon={KeyIcon} color={palette['slateGrey']} />
@@ -9,21 +9,31 @@ export class RawMountPointProvider extends React.Component {
9
9
  super(props)
10
10
 
11
11
  this.pushHistory = this.pushHistory.bind(this)
12
+ this.replaceHistory = this.replaceHistory.bind(this)
12
13
 
13
14
  this.state = {
14
15
  baseRoute: props.baseRoute || '/',
15
- pushHistory: this.pushHistory
16
+ pushHistory: this.pushHistory,
17
+ replaceHistory: this.replaceHistory
16
18
  }
17
19
  }
18
20
 
19
- pushHistory(route) {
21
+ historyAction(route, method) {
20
22
  const { history } = this.props
21
23
  const { baseRoute } = this.state
22
- const segments = baseRoute
23
- .split('/')
24
- .concat(route.split('/'))
25
- .filter(Boolean)
26
- history.push(`/${segments.join('/')}`)
24
+ const segments = '/'.concat(
25
+ baseRoute.split('/').concat(route.split('/')).filter(Boolean).join('/')
26
+ )
27
+
28
+ history[method](segments)
29
+ }
30
+
31
+ pushHistory(route) {
32
+ this.historyAction(route, 'push')
33
+ }
34
+
35
+ replaceHistory(route) {
36
+ this.historyAction(route, 'replace')
27
37
  }
28
38
 
29
39
  render() {
@@ -40,13 +50,20 @@ RawMountPointProvider.propTypes = {
40
50
  history: PropTypes.object
41
51
  }
42
52
 
43
- const withMountPointPushHistory = BaseComponent => {
53
+ const withMountPointHistory = BaseComponent => {
44
54
  const Component = props => {
45
- const { pushHistory } = useContext(MountPointContext)
46
- return <BaseComponent pushHistory={pushHistory} {...props} />
55
+ const { pushHistory, replaceHistory } = useContext(MountPointContext)
56
+
57
+ return (
58
+ <BaseComponent
59
+ pushHistory={pushHistory}
60
+ replaceHistory={replaceHistory}
61
+ {...props}
62
+ />
63
+ )
47
64
  }
48
65
 
49
- Component.displayName = `withMountPointPushHistory(${
66
+ Component.displayName = `withMountPointHistory(${
50
67
  BaseComponent.displayName || BaseComponent.name
51
68
  })`
52
69
 
@@ -54,4 +71,4 @@ const withMountPointPushHistory = BaseComponent => {
54
71
  }
55
72
 
56
73
  const MountPointProvider = withRouter(RawMountPointProvider)
57
- export { MountPointContext, MountPointProvider, withMountPointPushHistory }
74
+ export { MountPointContext, MountPointProvider, withMountPointHistory }
@@ -3,7 +3,7 @@ import { shallow } from 'enzyme'
3
3
  import { RawMountPointProvider } from 'components/MountPointContext'
4
4
 
5
5
  describe('MountPointProvider', () => {
6
- const historyMock = { push: jest.fn() }
6
+ const historyMock = { replace: jest.fn() }
7
7
 
8
8
  beforeEach(() => {
9
9
  jest.resetAllMocks()
@@ -14,17 +14,17 @@ describe('MountPointProvider', () => {
14
14
  <RawMountPointProvider baseRoute="/root" history={historyMock} />
15
15
  )
16
16
 
17
- component.instance().pushHistory('/one')
18
- expect(historyMock.push).toHaveBeenCalledWith('/root/one')
17
+ component.instance().replaceHistory('/one')
18
+ expect(historyMock.replace).toHaveBeenCalledWith('/root/one')
19
19
 
20
- component.instance().pushHistory('/one/two')
21
- expect(historyMock.push).toHaveBeenCalledWith('/root/one/two')
20
+ component.instance().replaceHistory('/one/two')
21
+ expect(historyMock.replace).toHaveBeenCalledWith('/root/one/two')
22
22
 
23
- component.instance().pushHistory('no/slash')
24
- expect(historyMock.push).toHaveBeenCalledWith('/root/no/slash')
23
+ component.instance().replaceHistory('no/slash')
24
+ expect(historyMock.replace).toHaveBeenCalledWith('/root/no/slash')
25
25
 
26
- component.instance().pushHistory('too/many///slashes')
27
- expect(historyMock.push).toHaveBeenCalledWith('/root/too/many/slashes')
26
+ component.instance().replaceHistory('too/many///slashes')
27
+ expect(historyMock.replace).toHaveBeenCalledWith('/root/too/many/slashes')
28
28
  })
29
29
 
30
30
  it('should handle a trailing slash in the base route', () => {
@@ -32,11 +32,11 @@ describe('MountPointProvider', () => {
32
32
  <RawMountPointProvider baseRoute="/root/" history={historyMock} />
33
33
  )
34
34
 
35
- component.instance().pushHistory('/one')
36
- expect(historyMock.push).toHaveBeenCalledWith('/root/one')
35
+ component.instance().replaceHistory('/one')
36
+ expect(historyMock.replace).toHaveBeenCalledWith('/root/one')
37
37
 
38
- component.instance().pushHistory('no/slash')
39
- expect(historyMock.push).toHaveBeenCalledWith('/root/no/slash')
38
+ component.instance().replaceHistory('no/slash')
39
+ expect(historyMock.replace).toHaveBeenCalledWith('/root/no/slash')
40
40
  })
41
41
 
42
42
  it('should handle a base route with multiple segments', () => {
@@ -44,10 +44,10 @@ describe('MountPointProvider', () => {
44
44
  <RawMountPointProvider baseRoute="/base/route/" history={historyMock} />
45
45
  )
46
46
 
47
- component.instance().pushHistory('/one')
48
- expect(historyMock.push).toHaveBeenCalledWith('/base/route/one')
47
+ component.instance().replaceHistory('/one')
48
+ expect(historyMock.replace).toHaveBeenCalledWith('/base/route/one')
49
49
 
50
- component.instance().pushHistory('/one/two')
51
- expect(historyMock.push).toHaveBeenCalledWith('/base/route/one/two')
50
+ component.instance().replaceHistory('/one/two')
51
+ expect(historyMock.replace).toHaveBeenCalledWith('/base/route/one/two')
52
52
  })
53
53
  })
@@ -26,7 +26,7 @@ import { useDialogContext } from './DialogContext'
26
26
  const NewAccountModal = ({ konnector, onDismiss }) => {
27
27
  const { t } = useI18n()
28
28
  const client = useClient()
29
- const { pushHistory } = useContext(MountPointContext)
29
+ const { replaceHistory } = useContext(MountPointContext)
30
30
  const {
31
31
  fetchStatus,
32
32
  data: { isInMaintenance, messages: maintenanceMessages }
@@ -74,7 +74,7 @@ const NewAccountModal = ({ konnector, onDismiss }) => {
74
74
  if (trigger.worker !== 'client') {
75
75
  path += '/success'
76
76
  }
77
- pushHistory(path)
77
+ replaceHistory(path)
78
78
  }}
79
79
  onSuccess={trigger => {
80
80
  const accountId = triggersModel.getAccountId(trigger)
@@ -82,7 +82,7 @@ const NewAccountModal = ({ konnector, onDismiss }) => {
82
82
  if (trigger.worker !== 'client') {
83
83
  path += '/success'
84
84
  }
85
- pushHistory(path)
85
+ replaceHistory(path)
86
86
  }}
87
87
  onVaultDismiss={onDismiss}
88
88
  fieldOptions={fieldOptions}
@@ -26,9 +26,9 @@ jest.mock('./DialogContext', () => {
26
26
  })
27
27
 
28
28
  describe('NewAccountModal', () => {
29
- const pushHistory = jest.fn()
29
+ const replaceHistory = jest.fn()
30
30
  const mountPointContextValue = {
31
- pushHistory
31
+ replaceHistory
32
32
  }
33
33
  const konnectorTrigger = {
34
34
  worker: 'konnector',
@@ -58,7 +58,7 @@ describe('NewAccountModal', () => {
58
58
  </AppLike>
59
59
  )
60
60
  onLoginSuccessFn(konnectorTrigger)
61
- expect(pushHistory).toHaveBeenCalledWith('/accounts/accountNumber/success')
61
+ expect(replaceHistory).toHaveBeenCalledWith('/accounts/accountNumber/success')
62
62
  })
63
63
  it('should redirect to route without success on login success for client triggers', () => {
64
64
  render(
@@ -71,7 +71,7 @@ describe('NewAccountModal', () => {
71
71
  </AppLike>
72
72
  )
73
73
  onLoginSuccessFn(clientTrigger)
74
- expect(pushHistory).toHaveBeenCalledWith('/accounts/accountNumberClient')
74
+ expect(replaceHistory).toHaveBeenCalledWith('/accounts/accountNumberClient')
75
75
  })
76
76
 
77
77
  it('should redirect to success route on success for non client triggers', () => {
@@ -85,7 +85,7 @@ describe('NewAccountModal', () => {
85
85
  </AppLike>
86
86
  )
87
87
  onSuccessFn(konnectorTrigger)
88
- expect(pushHistory).toHaveBeenCalledWith('/accounts/accountNumber/success')
88
+ expect(replaceHistory).toHaveBeenCalledWith('/accounts/accountNumber/success')
89
89
  })
90
90
  it('should redirect to route without success on success for client triggers', () => {
91
91
  render(
@@ -98,6 +98,6 @@ describe('NewAccountModal', () => {
98
98
  </AppLike>
99
99
  )
100
100
  onSuccessFn(clientTrigger)
101
- expect(pushHistory).toHaveBeenCalledWith('/accounts/accountNumberClient')
101
+ expect(replaceHistory).toHaveBeenCalledWith('/accounts/accountNumberClient')
102
102
  })
103
103
  })
@@ -7,10 +7,10 @@ import { MountPointContext } from './MountPointContext'
7
7
  const RedirectToAccountFormButton = ({ trigger }) => {
8
8
  const { t } = useI18n()
9
9
  const accountId = getAccountId(trigger)
10
- const { pushHistory } = useContext(MountPointContext)
10
+ const { replaceHistory } = useContext(MountPointContext)
11
11
  const handleClick = useCallback(() => {
12
- pushHistory(`/accounts/${accountId}/edit?reconnect`)
13
- }, [accountId, pushHistory])
12
+ replaceHistory(`/accounts/${accountId}/edit?reconnect`)
13
+ }, [accountId, replaceHistory])
14
14
  return (
15
15
  <Button
16
16
  className="u-ml-0"
@@ -5,10 +5,10 @@ import RedirectToAccountFormButton from './RedirectToAccountFormButton'
5
5
  import AppLike from '../../test/AppLike'
6
6
 
7
7
  describe('redirect to account form button', () => {
8
- it('should use pushHistory to navigate', () => {
9
- const pushHistory = jest.fn()
8
+ it('should use replaceHistory to navigate', () => {
9
+ const replaceHistory = jest.fn()
10
10
  const mountPointContextValue = {
11
- pushHistory
11
+ replaceHistory
12
12
  }
13
13
  const trigger = {
14
14
  message: {
@@ -23,7 +23,7 @@ describe('redirect to account form button', () => {
23
23
  </AppLike>
24
24
  )
25
25
  fireEvent.click(root.getByText('Reconnect'))
26
- expect(pushHistory).toHaveBeenCalledWith(
26
+ expect(replaceHistory).toHaveBeenCalledWith(
27
27
  '/accounts/account-id-1337/edit?reconnect'
28
28
  )
29
29
  })
@@ -28,7 +28,8 @@ export const AppLinkButton = ({ slug, path }) => {
28
28
  <AppLinker app={{ slug }} nativePath={path} href={url || '#'}>
29
29
  {({ onClick, href }) => (
30
30
  <ButtonLink
31
- onClick={fetchStatus !== 'loaded' ? onClick : null}
31
+ disabled={fetchStatus !== 'loaded'}
32
+ onClick={fetchStatus === 'loaded' ? onClick : null}
32
33
  href={href}
33
34
  icon={
34
35
  isInstalled ? (