matlab-proxy 0.11.0__tar.gz → 0.12.0__tar.gz

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.

Potentially problematic release.


This version of matlab-proxy might be problematic. Click here for more details.

Files changed (131) hide show
  1. {matlab-proxy-0.11.0/matlab_proxy.egg-info → matlab-proxy-0.12.0}/PKG-INFO +1 -1
  2. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/actionCreators/actionCreators.spec.js +7 -7
  3. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/actionCreators/index.js +78 -6
  4. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/actions/index.js +7 -1
  5. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/index.js +58 -9
  6. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/Confirmation/index.js +6 -5
  7. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/reducers/index.js +64 -3
  8. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/selectors/index.js +25 -4
  9. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/selectors/selectors.spec.js +17 -2
  10. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/test/utils/state.js +8 -1
  11. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy/app.py +46 -19
  12. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy/app_state.py +5 -1
  13. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy/constants.py +4 -1
  14. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0/matlab_proxy.egg-info}/PKG-INFO +1 -1
  15. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/setup.py +1 -1
  16. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/LICENSE.md +0 -0
  17. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/MANIFEST.in +0 -0
  18. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/README.md +0 -0
  19. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/.gitignore +0 -0
  20. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/README.md +0 -0
  21. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/package-lock.json +0 -0
  22. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/package.json +0 -0
  23. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/public/favicon.ico +0 -0
  24. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/public/index.html +0 -0
  25. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/public/manifest.json +0 -0
  26. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/public/robots.txt +0 -0
  27. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/3p/css/bootstrap.min.css +0 -0
  28. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/3p/css/site7.min.css +0 -0
  29. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/3p/fonts/glyphicons-halflings-regular.eot +0 -0
  30. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/3p/fonts/glyphicons-halflings-regular.svg +0 -0
  31. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/3p/fonts/glyphicons-halflings-regular.ttf +0 -0
  32. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/3p/fonts/glyphicons-halflings-regular.woff +0 -0
  33. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/3p/fonts/glyphicons-halflings-regular.woff2 +0 -0
  34. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/3p/fonts/mathworks-eps.svg +0 -0
  35. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/3p/fonts/mathworks-eps.ttf +0 -0
  36. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/3p/fonts/mathworks-eps.woff +0 -0
  37. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/3p/fonts/mathworks-pictograms.svg +0 -0
  38. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/3p/fonts/mathworks-pictograms.ttf +0 -0
  39. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/3p/fonts/mathworks-pictograms.woff +0 -0
  40. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/3p/fonts/mathworks.svg +0 -0
  41. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/3p/fonts/mathworks.ttf +0 -0
  42. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/3p/fonts/mathworks.woff +0 -0
  43. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/3p/images/bug_reports/workaround.gif +0 -0
  44. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/3p/images/responsive/global/ico-header-account-hover.svg +0 -0
  45. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/3p/images/responsive/global/ico-header-account.svg +0 -0
  46. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/3p/images/responsive/global/ico-header-contact-hover.svg +0 -0
  47. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/3p/images/responsive/global/ico-header-contact.svg +0 -0
  48. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/3p/images/responsive/global/ico-sprite.png +0 -0
  49. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/App.css +0 -0
  50. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/App.spec.js +0 -0
  51. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/App/MATLAB-env-blur.png +0 -0
  52. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/Confirmation/Confirmation.spec.js +0 -0
  53. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/Controls/Controls.css +0 -0
  54. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/Controls/Controls.spec.js +0 -0
  55. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/Controls/feedback.svg +0 -0
  56. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/Controls/help.svg +0 -0
  57. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/Controls/index.js +0 -0
  58. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/Controls/restart.svg +0 -0
  59. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/Controls/sign-out.svg +0 -0
  60. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/Controls/start.svg +0 -0
  61. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/Controls/stop.svg +0 -0
  62. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/Controls/terminate.svg +0 -0
  63. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/EntitlementSelector/EntitlementSelector.spec.js +0 -0
  64. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/EntitlementSelector/index.js +0 -0
  65. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/Error/Error.css +0 -0
  66. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/Error/Error.spec.js +0 -0
  67. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/Error/index.js +0 -0
  68. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/Help/Help.css +0 -0
  69. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/Help/Help.spec.js +0 -0
  70. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/Help/index.js +0 -0
  71. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/Information/Information.css +0 -0
  72. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/Information/Information.spec.js +0 -0
  73. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/Information/index.js +0 -0
  74. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/LicensingGatherer/ExistingLicense.css +0 -0
  75. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/LicensingGatherer/ExistingLicense.js +0 -0
  76. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/LicensingGatherer/LicenseGatherer.spec.js +0 -0
  77. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/LicensingGatherer/LicensingGatherer.css +0 -0
  78. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/LicensingGatherer/MHLM.js +0 -0
  79. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/LicensingGatherer/NLM.js +0 -0
  80. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/LicensingGatherer/index.js +0 -0
  81. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/MatlabJsd/MatlabJsd.css +0 -0
  82. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/MatlabJsd/MatlabJsd.spec.js +0 -0
  83. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/MatlabJsd/index.js +0 -0
  84. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/Overlay/Overlay.css +0 -0
  85. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/Overlay/Overlay.spec.js +0 -0
  86. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/Overlay/index.js +0 -0
  87. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/OverlayTrigger/OverlayTrigger.css +0 -0
  88. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/OverlayTrigger/OverlayTrigger.spec.js +0 -0
  89. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/OverlayTrigger/ResizeOverlayTrigger.spec.js +0 -0
  90. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/OverlayTrigger/arrow.svg +0 -0
  91. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/OverlayTrigger/gripper.svg +0 -0
  92. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/OverlayTrigger/index.js +0 -0
  93. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/OverlayTrigger/trigger-error.svg +0 -0
  94. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/components/OverlayTrigger/trigger-ok.svg +0 -0
  95. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/index.css +0 -0
  96. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/index.js +0 -0
  97. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/jest.config.json +0 -0
  98. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/logo.svg +0 -0
  99. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/reducers/reducers.spec.js +0 -0
  100. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/serviceWorker.js +0 -0
  101. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/setupTests.js +0 -0
  102. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/gui/src/test/utils/react-test.js +0 -0
  103. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy/__init__.py +0 -0
  104. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy/default_configuration.py +0 -0
  105. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy/devel.py +0 -0
  106. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy/icons/matlab.svg +0 -0
  107. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy/matlab/startup.m +0 -0
  108. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy/settings.py +0 -0
  109. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy/util/__init__.py +0 -0
  110. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy/util/event_loop.py +0 -0
  111. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy/util/list_servers.py +0 -0
  112. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy/util/mw.py +0 -0
  113. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy/util/mwi/__init__.py +0 -0
  114. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy/util/mwi/custom_http_headers.py +0 -0
  115. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy/util/mwi/embedded_connector/__init__.py +0 -0
  116. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy/util/mwi/embedded_connector/helpers.py +0 -0
  117. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy/util/mwi/embedded_connector/request.py +0 -0
  118. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy/util/mwi/environment_variables.py +0 -0
  119. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy/util/mwi/exceptions.py +0 -0
  120. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy/util/mwi/logger.py +0 -0
  121. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy/util/mwi/token_auth.py +0 -0
  122. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy/util/mwi/validators.py +0 -0
  123. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy/util/system.py +0 -0
  124. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy/util/windows.py +0 -0
  125. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy.egg-info/SOURCES.txt +0 -0
  126. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy.egg-info/dependency_links.txt +0 -0
  127. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy.egg-info/entry_points.txt +0 -0
  128. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy.egg-info/not-zip-safe +0 -0
  129. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy.egg-info/requires.txt +0 -0
  130. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/matlab_proxy.egg-info/top_level.txt +0 -0
  131. {matlab-proxy-0.11.0 → matlab-proxy-0.12.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: matlab-proxy
3
- Version: 0.11.0
3
+ Version: 0.12.0
4
4
  Summary: Python® package enables you to launch MATLAB® and access it from a web browser.
5
5
  Home-page: https://github.com/mathworks/matlab-proxy/
6
6
  Author: The MathWorks, Inc.
@@ -1,4 +1,4 @@
1
- // Copyright 2020-2023 The MathWorks, Inc.
1
+ // Copyright 2020-2024 The MathWorks, Inc.
2
2
 
3
3
  import configureMockStore from 'redux-mock-store';
4
4
  import thunk from 'redux-thunk';
@@ -94,7 +94,7 @@ describe('Test fetchWithTimeout method', () => {
94
94
  });
95
95
 
96
96
  it('should fetch requested data without raising an exception or dispatching any action', async () => {
97
- fetchMock.getOnce('/get_status', {
97
+ fetchMock.getOnce('/get_status?IS_DESKTOP=TRUE', {
98
98
  body: {
99
99
  matlab: {
100
100
  status: 'down',
@@ -104,7 +104,7 @@ describe('Test fetchWithTimeout method', () => {
104
104
  headers: { 'content-type': 'application/json' },
105
105
  });
106
106
 
107
- const response = await actionCreators.fetchWithTimeout(store.dispatch, '/get_status', {}, 10000);
107
+ const response = await actionCreators.fetchWithTimeout(store.dispatch, '/get_status?IS_DESKTOP=TRUE', {}, 10000);
108
108
  const body = await response.json()
109
109
 
110
110
  expect(body).not.toBeNull();
@@ -116,7 +116,7 @@ describe('Test fetchWithTimeout method', () => {
116
116
  ];
117
117
 
118
118
  try {
119
- const response = await actionCreators.fetchWithTimeout(store.dispatch, '/get_status', {}, 100);
119
+ const response = await actionCreators.fetchWithTimeout(store.dispatch, '/get_status?IS_DESKTOP=TRUE', {}, 100);
120
120
  } catch (error) {
121
121
  expect(error).toBeInstanceOf(TypeError)
122
122
  const received = store.getActions();
@@ -130,14 +130,14 @@ describe('Test fetchWithTimeout method', () => {
130
130
 
131
131
  // Send a delayed response, well after the timeout for the request has expired.
132
132
  // This should trigger the abort() method of the AbortController()
133
- fetchMock.getOnce('/get_status', new Promise(resolve => setTimeout(() => resolve({ body: 'ok' }), 1000 + timeout)));
133
+ fetchMock.getOnce('/get_status?IS_DESKTOP=TRUE', new Promise(resolve => setTimeout(() => resolve({ body: 'ok' }), 1000 + timeout)));
134
134
 
135
135
  const abortSpy = jest.spyOn(global.AbortController.prototype, 'abort');
136
136
  const expectedActions = [
137
137
  actions.RECEIVE_ERROR,
138
138
  ];
139
139
 
140
- await actionCreators.fetchWithTimeout(store.dispatch, '/get_status', {}, timeout);
140
+ await actionCreators.fetchWithTimeout(store.dispatch, '/get_status?IS_DESKTOP=TRUE', {}, timeout);
141
141
 
142
142
  expect(abortSpy).toBeCalledTimes(1);
143
143
  const received = store.getActions();
@@ -194,7 +194,7 @@ describe('Test Async actionCreators', () => {
194
194
  });
195
195
 
196
196
  it('dispatches REQUEST_SERVER_STATUS, RECEIVE_SERVER_STATUS when fetching status', () => {
197
- fetchMock.getOnce('/get_status', {
197
+ fetchMock.getOnce('/get_status?IS_DESKTOP=TRUE', {
198
198
  body: {
199
199
  matlab: {
200
200
  status: 'down',
@@ -1,4 +1,4 @@
1
- // Copyright 2020-2023 The MathWorks, Inc.
1
+ // Copyright 2020-2024 The MathWorks, Inc.
2
2
 
3
3
  import {
4
4
  SET_TRIGGER_POSITION,
@@ -19,10 +19,19 @@ import {
19
19
  RECEIVE_START_MATLAB,
20
20
  RECEIVE_ERROR,
21
21
  RECEIVE_ENV_CONFIG,
22
+ RECEIVE_CONCURRENCY_CHECK,
22
23
  SET_AUTH_STATUS,
23
- SET_AUTH_TOKEN
24
+ SET_AUTH_TOKEN,
25
+ RECEIVE_SESSION_STATUS,
26
+ WAS_EVER_ACTIVE,
27
+ REQUEST_SESSION_STATUS,
28
+ SET_CLIENT_ID,
24
29
  } from '../actions';
25
- import { selectMatlabPending } from '../selectors';
30
+ import {
31
+ selectMatlabPending,
32
+ selectIsConcurrencyEnabled,
33
+ selectClientId,
34
+ } from '../selectors';
26
35
  import sha256 from 'crypto-js/sha256';
27
36
 
28
37
  export function setAuthStatus(authInfo) {
@@ -61,12 +70,25 @@ export function setOverlayVisibility(visibility) {
61
70
  };
62
71
  }
63
72
 
73
+ export function setClientId(client_id) {
74
+ return {
75
+ type: SET_CLIENT_ID,
76
+ client_id
77
+ };
78
+ }
79
+
64
80
  export function requestServerStatus() {
65
81
  return {
66
82
  type: REQUEST_SERVER_STATUS,
67
83
  };
68
84
  }
69
85
 
86
+ export function wasEverActive() {
87
+ return {
88
+ type: WAS_EVER_ACTIVE,
89
+ }
90
+ }
91
+
70
92
  export function receiveServerStatus(status) {
71
93
  return function (dispatch, getState) {
72
94
  return dispatch({
@@ -76,6 +98,20 @@ export function receiveServerStatus(status) {
76
98
  });
77
99
  }
78
100
  }
101
+ export function requestSessionStatus() {
102
+ return {
103
+ type: REQUEST_SESSION_STATUS,
104
+ };
105
+ }
106
+
107
+ export function receiveSessionStatus(status) {
108
+ return function (dispatch, getState) {
109
+ return dispatch({
110
+ type: RECEIVE_SESSION_STATUS,
111
+ status,
112
+ })
113
+ }
114
+ }
79
115
 
80
116
  export function requestEnvConfig() {
81
117
  return {
@@ -90,6 +126,13 @@ export function receiveEnvConfig(config) {
90
126
  };
91
127
  }
92
128
 
129
+ export function receiveConcurrencyCheck(config) {
130
+ return {
131
+ type: RECEIVE_CONCURRENCY_CHECK,
132
+ config,
133
+ }
134
+ }
135
+
93
136
  export function requestSetLicensing() {
94
137
  return {
95
138
  type: REQUEST_SET_LICENSING,
@@ -193,14 +236,43 @@ export async function fetchWithTimeout(dispatch, resource, options = {}, timeout
193
236
  }
194
237
  }
195
238
 
196
- export function fetchServerStatus() {
239
+ export function fetchServerStatus(requestTransferSession = false) {
197
240
  return async function (dispatch, getState) {
241
+ const isConcurrencyEnabled = selectIsConcurrencyEnabled(getState());
242
+ const clientIdInState = selectClientId(getState());
243
+ const clientId = clientIdInState ? clientIdInState : sessionStorage.getItem("MWI_CLIENT_ID");
198
244
 
199
245
  dispatch(requestServerStatus());
200
- const response = await fetchWithTimeout(dispatch, './get_status', {}, 10000);
201
- const data = await response.json();
246
+
247
+ let url = './get_status?IS_DESKTOP=TRUE'
248
+
249
+ if (isConcurrencyEnabled && clientId) {
250
+ let params = new URLSearchParams();
251
+ params.append("MWI_CLIENT_ID",encodeURIComponent(clientId))
252
+
253
+ if (requestTransferSession){
254
+ params.append("TRANSFER_SESSION",encodeURIComponent(requestTransferSession))
255
+ }
256
+
257
+ url = url + '&' + params.toString();
258
+
259
+ }
260
+
261
+ const response = await fetchWithTimeout(dispatch, url, {}, 10000);
262
+
263
+ const data = await response.json();
202
264
  dispatch(receiveServerStatus(data));
203
265
 
266
+ if (clientId == null && data["clientId"]) {
267
+ sessionStorage.setItem("MWI_CLIENT_ID", data["clientId"]);
268
+ dispatch(setClientId(data["clientId"]));
269
+ }
270
+ if ("isActiveClient" in data) {
271
+ dispatch(receiveSessionStatus(data))
272
+ if (data["isActiveClient"] === true) {
273
+ dispatch(wasEverActive())
274
+ }
275
+ }
204
276
  }
205
277
  }
206
278
 
@@ -1,8 +1,9 @@
1
- // Copyright (c) 2020-2023 The MathWorks, Inc.
1
+ // Copyright 2020-2024 The MathWorks, Inc.
2
2
 
3
3
  export const SET_TRIGGER_POSITION = 'SET_TRIGGER_POSITION';
4
4
  export const SET_TUTORIAL_HIDDEN = 'SET_TUTORIAL_HIDDEN';
5
5
  export const SET_OVERLAY_VISIBILITY = 'SET_OVERLAY_VISIBILITY';
6
+ export const SET_CLIENT_ID = 'SET_CLIENT_ID';
6
7
  export const REQUEST_SERVER_STATUS = 'REQUEST_SERVER_STATUS';
7
8
  export const RECEIVE_SERVER_STATUS = 'RECEIVE_SERVER_STATUS';
8
9
  export const REQUEST_SET_LICENSING = 'REQUEST_SET_LICENSING';
@@ -18,5 +19,10 @@ export const RECEIVE_START_MATLAB = 'RECEIVE_START_MATLAB';
18
19
  export const RECEIVE_ERROR = 'RECEIVE_ERROR';
19
20
  export const REQUEST_ENV_CONFIG = 'REQUEST_ENV_CONFIG';
20
21
  export const RECEIVE_ENV_CONFIG = 'RECEIVE_ENV_CONFIG';
22
+ export const RECEIVE_CONCURRENCY_CHECK = 'RECEIVE_CONCURRENCY_CHECK';
21
23
  export const SET_AUTH_STATUS = 'SET_AUTH_STATUS';
22
24
  export const SET_AUTH_TOKEN = 'SET_AUTH_TOKEN';
25
+ export const REQUEST_SERVER_INITIALIZATION = 'REQUEST_SERVER_INITIALIZATION';
26
+ export const RECEIVE_SESSION_STATUS = 'RECEIVE_SESSION_STATUS';
27
+ export const WAS_EVER_ACTIVE = 'WAS_EVER_ACTIVE';
28
+ export const REQUEST_SESSION_STATUS = 'REQUEST_SESSION_STATUS';
@@ -1,4 +1,4 @@
1
- // Copyright 2020-2023 The MathWorks, Inc.
1
+ // Copyright 2020-2024 The MathWorks, Inc.
2
2
 
3
3
  import React, { useState, useCallback, useEffect, useMemo } from 'react';
4
4
  import { useSelector, useDispatch } from 'react-redux';
@@ -30,6 +30,9 @@ import {
30
30
  selectLicensingInfo,
31
31
  selectUseMOS,
32
32
  selectUseMRE,
33
+ selectIsConcurrent,
34
+ selectWasEverActive,
35
+ selectIsConcurrencyEnabled,
33
36
  } from "../../selectors";
34
37
 
35
38
  import {
@@ -55,11 +58,14 @@ function App() {
55
58
  const error = useSelector(selectError);
56
59
  const loadUrl = useSelector(selectLoadUrl);
57
60
  const isConnectionError = useSelector(selectIsConnectionError);
58
- const isAuthenticated = useSelector(selectIsAuthenticated)
61
+ const isAuthenticated = useSelector(selectIsAuthenticated);
59
62
  const authEnabled = useSelector(selectAuthEnabled);
60
63
  const licensingInfo = useSelector(selectLicensingInfo);
61
64
  const useMOS = useSelector(selectUseMOS);
62
65
  const useMRE = useSelector(selectUseMRE);
66
+ const isSessionConcurrent = useSelector(selectIsConcurrent);
67
+ const isConcurrencyEnabled = useSelector(selectIsConcurrencyEnabled);
68
+ const wasEverActive = useSelector(selectWasEverActive);
63
69
 
64
70
  const baseUrl = useMemo(() => {
65
71
  const url = document.URL
@@ -92,7 +98,10 @@ function App() {
92
98
  );
93
99
 
94
100
  const [dialogModel, setDialogModel] = useState(null);
101
+ const [isTerminated, setIsTerminated] = useState(false);
95
102
 
103
+ // sessionDialog stores the state of concurrent session based on which either matlab gets rendered or the concurrent session dialog gets rendered
104
+ let sessionDialog = null;
96
105
  let dialog;
97
106
  if (dialogModel) {
98
107
  const closeHandler = () => setDialogModel(null);
@@ -135,6 +144,35 @@ function App() {
135
144
  );
136
145
  } else if (error && error.type === "MatlabInstallError") {
137
146
  dialog = <Error message={error.message} />;
147
+ }
148
+ // check the user authentication before giving them the option to transfer the session.
149
+ else if ((!authEnabled || isAuthenticated) && isSessionConcurrent && isConcurrencyEnabled) {
150
+ // Transfer the session to this tab
151
+ // setting the query parameter of requestTransferSession to true
152
+ const transferSessionOnClick= () => {
153
+ dispatch(fetchServerStatus(true));
154
+ sessionDialog=null;
155
+ }
156
+ const endSession = () => {
157
+ setIsTerminated(true);
158
+ }
159
+ if(isTerminated) {
160
+ sessionDialog = <Error message="Your session has been terminated. Refresh the page to restart the session." />;
161
+ }
162
+ else {
163
+ sessionDialog = (
164
+ <Confirmation
165
+ confirm={transferSessionOnClick}
166
+ cancel={endSession}
167
+ title='MATLAB is currently open in another window'
168
+ cancelButton={wasEverActive?('Cancel'):('Continue in existing window')}
169
+ confirmButton = {wasEverActive?('Confirm'):('Continue in this window')}>
170
+ {wasEverActive
171
+ ? 'You have been disconnected because MATLAB is open in another window. Click on Confirm to continue using MATLAB here.'
172
+ : <div>MATLAB is open in another window and cannot be opened in a second window or tab at the same time.<br></br>Would you like to continue in this window?</div> }
173
+ </Confirmation>
174
+ );
175
+ }
138
176
  }
139
177
 
140
178
  useEffect(() => {
@@ -147,11 +185,11 @@ function App() {
147
185
 
148
186
  useEffect(() => {
149
187
  // Initial fetch server status
150
- if (!hasFetchedServerStatus) {
188
+ if (hasFetchedEnvConfig && !hasFetchedServerStatus) {
151
189
  dispatch(fetchServerStatus());
152
190
  }
153
191
 
154
- }, [dispatch, hasFetchedServerStatus]);
192
+ }, [dispatch, hasFetchedServerStatus, hasFetchedEnvConfig]);
155
193
 
156
194
  // Periodic fetch server status
157
195
  useInterval(() => {
@@ -233,11 +271,22 @@ function App() {
233
271
  const overlayTrigger = overlayVisible ? null : <OverlayTrigger />;
234
272
 
235
273
  return (
236
- <div data-testid="app" className="main">
237
- {overlayTrigger}
238
- {matlabJsd}
239
- {overlay}
240
- </div>
274
+ // If we use div instead of React.Fragment then the editor screen becomes white / doesn't fully render.
275
+ // Have noticed this behavior both in windows and Linux.
276
+ // If session dialog is not 'null' then render the transfer dialog or error dialog otherwise render the normal MATLAB.
277
+ <React.Fragment>
278
+ {sessionDialog?(
279
+ <Overlay>
280
+ {sessionDialog}
281
+ </Overlay>
282
+ ):(
283
+ <div data-testid="app" className="main">
284
+ {overlayTrigger}
285
+ {matlabJsd}
286
+ {overlay}
287
+ </div>
288
+ )}
289
+ </React.Fragment>
241
290
  );
242
291
  }
243
292
 
@@ -1,9 +1,10 @@
1
- // Copyright (c) 2020-2022 The MathWorks, Inc.
1
+ // Copyright 2020-2024 The MathWorks, Inc.
2
2
 
3
3
  import React from 'react';
4
4
  import PropTypes from 'prop-types';
5
5
 
6
- function Confirmation({ confirm, cancel, children }) {
6
+ // Made the Confirmation component more scalable where one can customize all the messages which are to be displayed.
7
+ function Confirmation({ confirm, cancel, title = 'Confirmation', cancelButton = 'Cancel', confirmButton = 'Confirm', children }) {
7
8
  return (
8
9
  <div className="modal show"
9
10
  id="confirmation"
@@ -14,14 +15,14 @@ function Confirmation({ confirm, cancel, children }) {
14
15
  role="document">
15
16
  <div className="modal-content">
16
17
  <div className="modal-header">
17
- <h4 className="modal-title" id="confirmation-dialog-title">Confirmation</h4>
18
+ <h4 className="modal-title" id="confirmation-dialog-title">{title}</h4>
18
19
  </div>
19
20
  <div className="modal-body">
20
21
  {children}
21
22
  </div>
22
23
  <div className="modal-footer">
23
- <button onClick={cancel} data-testid='cancelButton' className="btn companion_btn btn_color_blue">Cancel</button>
24
- <button onClick={confirm} data-testid='confirmButton' className="btn btn_color_blue">Confirm</button>
24
+ <button onClick={cancel} data-testid='cancelButton' className="btn companion_btn btn_color_blue">{cancelButton}</button>
25
+ <button onClick={confirm} data-testid='confirmButton' className="btn btn_color_blue">{confirmButton}</button>
25
26
  </div>
26
27
  </div>
27
28
  </div>
@@ -1,4 +1,4 @@
1
- // Copyright 2020-2023 The MathWorks, Inc.
1
+ // Copyright 2020-2024 The MathWorks, Inc.
2
2
 
3
3
  import { combineReducers } from 'redux';
4
4
 
@@ -14,6 +14,7 @@ import {
14
14
  REQUEST_STOP_MATLAB,
15
15
  REQUEST_START_MATLAB,
16
16
  REQUEST_ENV_CONFIG,
17
+ REQUEST_SERVER_INITIALIZATION,
17
18
  RECEIVE_SET_LICENSING,
18
19
  RECEIVE_TERMINATE_INTEGRATION,
19
20
  RECEIVE_STOP_MATLAB,
@@ -22,6 +23,11 @@ import {
22
23
  RECEIVE_ENV_CONFIG,
23
24
  SET_AUTH_STATUS,
24
25
  SET_AUTH_TOKEN,
26
+ SET_CLIENT_ID,
27
+ RECEIVE_SESSION_STATUS,
28
+ REQUEST_SESSION_STATUS,
29
+ RECEIVE_CONCURRENCY_CHECK,
30
+ WAS_EVER_ACTIVE,
25
31
  } from '../actions';
26
32
 
27
33
  // Stores info on whether token authentication enabled on the backend.
@@ -77,6 +83,17 @@ export function authToken(state = null, action) {
77
83
  }
78
84
  }
79
85
 
86
+ // Stores whether the concurrency is enabled or not
87
+ export function isConcurrencyEnabled(state = false, action) {
88
+ switch(action.type){
89
+ case RECEIVE_ENV_CONFIG:
90
+ case RECEIVE_CONCURRENCY_CHECK:
91
+ return action.config.isConcurrencyEnabled;
92
+ default:
93
+ return state;
94
+ }
95
+ }
96
+
80
97
  export function triggerPosition(state = { x: window.innerWidth / 2 + 27, y: 0 }, action) {
81
98
  switch (action.type) {
82
99
  case SET_TRIGGER_POSITION:
@@ -161,6 +178,14 @@ export function supportedMatlabVersions(state = null, action) {
161
178
  return state;
162
179
  }
163
180
  }
181
+ export function isActiveClient(state = true, action) {
182
+ switch (action.type) {
183
+ case RECEIVE_SESSION_STATUS:
184
+ return action.status.isActiveClient;
185
+ default:
186
+ return state;
187
+ }
188
+ }
164
189
 
165
190
  export function wsEnv(state = null, action) {
166
191
  switch (action.type) {
@@ -183,6 +208,7 @@ export function isFetching(state = false, action) {
183
208
  case REQUEST_STOP_MATLAB:
184
209
  case REQUEST_START_MATLAB:
185
210
  case REQUEST_ENV_CONFIG:
211
+ case REQUEST_SESSION_STATUS:
186
212
  return true;
187
213
  case RECEIVE_SERVER_STATUS:
188
214
  case RECEIVE_SET_LICENSING:
@@ -190,7 +216,7 @@ export function isFetching(state = false, action) {
190
216
  case RECEIVE_STOP_MATLAB:
191
217
  case RECEIVE_START_MATLAB:
192
218
  case RECEIVE_ERROR:
193
- case RECEIVE_ENV_CONFIG:
219
+ case RECEIVE_ENV_CONFIG:
194
220
  return false;
195
221
  default:
196
222
  return state;
@@ -210,6 +236,24 @@ export function hasFetched(state = false, action) {
210
236
  }
211
237
  }
212
238
 
239
+ export function hasClientInitialized(state = false, action) {
240
+ switch(action.type) {
241
+ case REQUEST_SERVER_INITIALIZATION:
242
+ return true;
243
+ default:
244
+ return state;
245
+ }
246
+ }
247
+
248
+ export function wasEverActive(state = false, action) {
249
+ switch(action.type) {
250
+ case WAS_EVER_ACTIVE:
251
+ return true;
252
+ default:
253
+ return state;
254
+ }
255
+ }
256
+
213
257
  export function isSubmitting(state = false, action) {
214
258
  switch (action.type) {
215
259
  case REQUEST_SET_LICENSING:
@@ -309,6 +353,15 @@ export function envConfig(state = null, action) {
309
353
  }
310
354
  }
311
355
 
356
+ export function clientId(state = null, action) {
357
+ switch (action.type) {
358
+ case SET_CLIENT_ID:
359
+ return action.client_id
360
+ default:
361
+ return state;
362
+ }
363
+ }
364
+
312
365
  export const authentication = combineReducers({
313
366
  enabled : authEnabled,
314
367
  status : authStatus,
@@ -327,15 +380,23 @@ export const serverStatus = combineReducers({
327
380
  isFetching,
328
381
  hasFetched,
329
382
  isSubmitting,
330
- fetchFailCount
383
+ fetchFailCount,
331
384
  });
332
385
 
386
+ export const sessionStatus = combineReducers({
387
+ isActiveClient,
388
+ hasClientInitialized,
389
+ wasEverActive,
390
+ isConcurrencyEnabled,
391
+ clientId,
392
+ });
333
393
 
334
394
  export default combineReducers({
335
395
  triggerPosition,
336
396
  tutorialHidden,
337
397
  overlayVisibility,
338
398
  serverStatus,
399
+ sessionStatus,
339
400
  loadUrl,
340
401
  error,
341
402
  warnings,
@@ -1,9 +1,10 @@
1
- // Copyright 2020-2023 The MathWorks, Inc.
1
+ // Copyright 2020-2024 The MathWorks, Inc.
2
2
 
3
3
  import { createSelector } from 'reselect';
4
4
 
5
5
  export const selectTutorialHidden = state => state.tutorialHidden;
6
6
  export const selectServerStatus = state => state.serverStatus;
7
+ export const selectSessionStatus = state => state.sessionStatus;
7
8
  export const selectMatlabStatus = state => state.matlab.status;
8
9
  export const selectMatlabVersionOnPath = state => state.matlab.versionOnPath;
9
10
  export const selectSupportedMatlabVersions = state => state.matlab.supportedVersions;
@@ -21,6 +22,10 @@ export const selectUseMRE = state => state.useMRE === true;
21
22
  export const selectAuthEnabled = state => state.authentication.enabled;
22
23
  export const selectAuthToken = state => state.authentication.token;
23
24
  export const selectIsAuthenticated = state => state.authentication.status === true;
25
+ export const selectIsActiveClient = state => state.sessionStatus.isActiveClient;
26
+ export const selectIsConcurrencyEnabled = state => state.sessionStatus.isConcurrencyEnabled;
27
+ export const selectWasEverActive = state => state.sessionStatus.wasEverActive;
28
+ export const selectClientId = state => state.sessionStatus.clientId;
24
29
 
25
30
  export const selectTriggerPosition = createSelector(
26
31
  state => state.triggerPosition,
@@ -37,9 +42,22 @@ export const selectIsError = createSelector(
37
42
  error => error !== null
38
43
  );
39
44
 
45
+ // If the client is not active then the session is a concurrent session.
46
+ export const selectIsConcurrent = createSelector(
47
+ selectIsActiveClient,
48
+ isActiveClient => !isActiveClient
49
+ );
50
+
40
51
  export const selectIsConnectionError = createSelector(
41
52
  selectServerStatusFetchFailCount,
42
- fails => fails >= 5
53
+ selectIsConcurrencyEnabled,
54
+ selectIsConcurrent,
55
+ (fails, isConcurrencyEnabled, isConcurrent) => {
56
+ if (isConcurrencyEnabled && isConcurrent) {
57
+ return fails >= 1
58
+ }
59
+ return fails >= 5
60
+ }
43
61
  );
44
62
 
45
63
  export const selectMatlabUp = createSelector(
@@ -86,11 +104,14 @@ export const getFetchAbortController = createSelector(
86
104
  serverStatus => serverStatus.fetchAbortController
87
105
  );
88
106
 
107
+ // If the session is concurrent or if there is a connection error then disable the fetching of data such as get_status.
89
108
  export const selectFetchStatusPeriod = createSelector(
90
109
  selectMatlabStatus,
91
110
  selectSubmittingServerStatus,
92
- (matlabStatus, isSubmitting) => {
93
- if (isSubmitting) {
111
+ selectIsConcurrencyEnabled,
112
+ selectIsConcurrent,
113
+ (matlabStatus, isSubmitting, isConcurrencyEnabled, isConcurrent) => {
114
+ if (isSubmitting || (isConcurrencyEnabled && isConcurrent)) {
94
115
  return null;
95
116
  } else if (matlabStatus === 'up') {
96
117
  return 10000;
@@ -1,4 +1,4 @@
1
- // Copyright 2020-2023 The MathWorks, Inc.
1
+ // Copyright 2020-2024 The MathWorks, Inc.
2
2
 
3
3
  import * as selectors from './index';
4
4
  import state from '../test/utils/state'
@@ -48,6 +48,7 @@ describe('selectors', () => {
48
48
  selectAuthEnabled,
49
49
  selectIsAuthenticated,
50
50
  selectAuthToken,
51
+ selectIsActiveClient,
51
52
  selectTriggerPosition,
52
53
  selectIsError,
53
54
  selectIsConnectionError,
@@ -62,6 +63,7 @@ describe('selectors', () => {
62
63
  selectMatlabPending,
63
64
  selectOverlayVisible,
64
65
  selectInformationDetails,
66
+ selectIsConcurrent,
65
67
  } = selectors;
66
68
 
67
69
  describe.each([
@@ -127,6 +129,16 @@ describe('selectors', () => {
127
129
  expect(selectIsConnectionError(modifiedState)).toBe(true);
128
130
  });
129
131
 
132
+ test('selectIsConcurrent should return false when the Client is the active client', () => {
133
+ expect(selectIsConcurrent(state)).toBe(false);
134
+ })
135
+
136
+ test('selectIsConcurrent should return true when the Client is no longer the active client',() => {
137
+ modifiedState = _.cloneDeep(state);
138
+ modifiedState.sessionStatus.isActiveClient = false;
139
+ expect(selectIsConcurrent(modifiedState)).toBe(true);
140
+ })
141
+
130
142
  test('selectMatlabUp should return true when Matlab is up', () => {
131
143
  expect(selectMatlabUp(state)).toBe(true);
132
144
  });
@@ -247,6 +259,7 @@ describe('selectors', () => {
247
259
  test('selectFetchStatusPeriod should return 10000ms when matlab is up ', () => {
248
260
  modifiedState = _.cloneDeep(state);
249
261
  modifiedState.serverStatus.isSubmitting = false;
262
+ modifiedState.isConcurrent = false;
250
263
  expect(selectFetchStatusPeriod(modifiedState)).toBe(10000);
251
264
  })
252
265
 
@@ -254,11 +267,13 @@ describe('selectors', () => {
254
267
  ['starting'],
255
268
  ['down']
256
269
  ])(
257
- 'selectFetchStatusPeriod should return 500ms when matlab %s (ie. not up)',
270
+ 'selectFetchStatusPeriod should return 5000ms when matlab %s (ie. not up)',
258
271
  (input) => {
259
272
 
260
273
  modifiedState = _.cloneDeep(state);
261
274
  modifiedState.serverStatus.isSubmitting = false;
275
+ modifiedState.isConcurrent = false;
276
+ modifiedState.isConnectionError = false;
262
277
  modifiedState.matlab.status = input;
263
278
 
264
279
  expect(selectFetchStatusPeriod(modifiedState)).toBe(5000);
@@ -1,4 +1,4 @@
1
- // Copyright 2023 The MathWorks, Inc.
1
+ // Copyright 2023-2024 The MathWorks, Inc.
2
2
 
3
3
  // A common state variable meant to represent redux state to be used by different tests.
4
4
  const state = {
@@ -44,5 +44,12 @@ const state = {
44
44
  status: false,
45
45
  token: null,
46
46
  },
47
+ sessionStatus: {
48
+ isActiveClient: true,
49
+ hasClientInitialized: false,
50
+ wasEverActive: false,
51
+ isConcurrencyEnabled: false,
52
+ clientId: null,
53
+ },
47
54
  };
48
55
  export default state;