@dhis2/app-service-offline 3.7.0 → 3.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/__tests__/integration.test.js +37 -24
- package/build/cjs/index.js +18 -10
- package/build/cjs/lib/__tests__/clear-sensitive-caches.test.js +5 -1
- package/build/cjs/lib/__tests__/{online-status.test.js → network-status.test.js} +41 -20
- package/build/cjs/lib/__tests__/offline-provider.test.js +5 -1
- package/build/cjs/lib/__tests__/use-cacheable-section.test.js +77 -35
- package/build/cjs/lib/__tests__/{use-online-staus-message.test.js → use-online-status-message.test.js} +8 -5
- package/build/cjs/lib/cacheable-section-state.js +17 -13
- package/build/cjs/lib/cacheable-section.js +14 -12
- package/build/cjs/lib/clear-sensitive-caches.js +9 -5
- package/build/cjs/lib/dhis2-connection-status/dev-debug-log.js +26 -0
- package/build/cjs/lib/dhis2-connection-status/dhis2-connection-status.js +224 -0
- package/build/cjs/lib/dhis2-connection-status/dhis2-connection-status.test.js +841 -0
- package/build/cjs/lib/dhis2-connection-status/index.js +19 -0
- package/build/cjs/lib/dhis2-connection-status/is-ping-available.js +43 -0
- package/build/cjs/lib/dhis2-connection-status/is-ping-available.test.js +76 -0
- package/build/cjs/lib/dhis2-connection-status/smart-interval.js +211 -0
- package/build/cjs/lib/dhis2-connection-status/use-ping-query.js +21 -0
- package/build/cjs/lib/global-state-service.js +16 -11
- package/build/cjs/lib/{online-status.js → network-status.js} +8 -5
- package/build/cjs/lib/offline-interface.js +7 -4
- package/build/cjs/lib/offline-provider.js +9 -5
- package/build/cjs/lib/online-status-message.js +5 -4
- package/build/cjs/utils/render-counter.js +6 -4
- package/build/cjs/utils/test-mocks.js +17 -10
- package/build/es/__tests__/integration.test.js +37 -24
- package/build/es/index.js +5 -3
- package/build/es/lib/__tests__/clear-sensitive-caches.test.js +5 -1
- package/build/es/lib/__tests__/{online-status.test.js → network-status.test.js} +35 -14
- package/build/es/lib/__tests__/offline-provider.test.js +5 -1
- package/build/es/lib/__tests__/use-cacheable-section.test.js +77 -34
- package/build/es/lib/__tests__/{use-online-staus-message.test.js → use-online-status-message.test.js} +8 -5
- package/build/es/lib/cacheable-section-state.js +14 -10
- package/build/es/lib/cacheable-section.js +13 -11
- package/build/es/lib/clear-sensitive-caches.js +8 -4
- package/build/es/lib/dhis2-connection-status/dev-debug-log.js +20 -0
- package/build/es/lib/dhis2-connection-status/dhis2-connection-status.js +194 -0
- package/build/es/lib/dhis2-connection-status/dhis2-connection-status.test.js +831 -0
- package/build/es/lib/dhis2-connection-status/index.js +1 -0
- package/build/es/lib/dhis2-connection-status/is-ping-available.js +36 -0
- package/build/es/lib/dhis2-connection-status/is-ping-available.test.js +73 -0
- package/build/es/lib/dhis2-connection-status/smart-interval.js +199 -0
- package/build/es/lib/dhis2-connection-status/use-ping-query.js +12 -0
- package/build/es/lib/global-state-service.js +15 -10
- package/build/es/lib/{online-status.js → network-status.js} +7 -4
- package/build/es/lib/offline-interface.js +7 -4
- package/build/es/lib/offline-provider.js +8 -5
- package/build/es/lib/online-status-message.js +4 -3
- package/build/es/utils/render-counter.js +6 -4
- package/build/es/utils/test-mocks.js +16 -9
- package/build/types/index.d.ts +2 -1
- package/build/types/lib/dhis2-connection-status/dev-debug-log.d.ts +9 -0
- package/build/types/lib/dhis2-connection-status/dhis2-connection-status.d.ts +28 -0
- package/build/types/lib/dhis2-connection-status/index.d.ts +1 -0
- package/build/types/lib/dhis2-connection-status/is-ping-available.d.ts +14 -0
- package/build/types/lib/dhis2-connection-status/smart-interval.d.ts +18 -0
- package/build/types/lib/dhis2-connection-status/use-ping-query.d.ts +1 -0
- package/build/types/lib/{online-status.d.ts → network-status.d.ts} +3 -3
- package/build/types/types.d.ts +6 -0
- package/build/types/utils/test-mocks.d.ts +2 -0
- package/package.json +2 -2
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "Dhis2ConnectionStatusProvider", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _dhis2ConnectionStatus.Dhis2ConnectionStatusProvider;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "useDhis2ConnectionStatus", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _dhis2ConnectionStatus.useDhis2ConnectionStatus;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
var _dhis2ConnectionStatus = require("./dhis2-connection-status");
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.isPingAvailable = isPingAvailable;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Checks the server version to see if the /api/ping endpoint is available for
|
|
10
|
+
* this version.
|
|
11
|
+
*
|
|
12
|
+
* The endpoint was released for versions 2.37.10, 2.38.3, 2.39.2, and 2.40.0
|
|
13
|
+
* (see DHIS2-14531). All versions below that are considered unsupported
|
|
14
|
+
*
|
|
15
|
+
* If the patchVersion is undefined, it's assumed to be a dev server that's
|
|
16
|
+
* newer than the fix versions listed above
|
|
17
|
+
*
|
|
18
|
+
* Major versions above 2 aren't supported 🤷♂️
|
|
19
|
+
*/
|
|
20
|
+
function isPingAvailable(serverVersion) {
|
|
21
|
+
if (!serverVersion) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const {
|
|
26
|
+
minor,
|
|
27
|
+
patch
|
|
28
|
+
} = serverVersion;
|
|
29
|
+
|
|
30
|
+
switch (minor) {
|
|
31
|
+
case 39:
|
|
32
|
+
return patch === undefined || patch >= 2;
|
|
33
|
+
|
|
34
|
+
case 38:
|
|
35
|
+
return patch === undefined || patch >= 3;
|
|
36
|
+
|
|
37
|
+
case 37:
|
|
38
|
+
return patch === undefined || patch >= 10;
|
|
39
|
+
|
|
40
|
+
default:
|
|
41
|
+
return minor >= 40;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _isPingAvailable = require("./is-ping-available");
|
|
4
|
+
|
|
5
|
+
const fixedVersions = [{
|
|
6
|
+
full: 'unimportant',
|
|
7
|
+
major: 2,
|
|
8
|
+
minor: 40,
|
|
9
|
+
patch: 0
|
|
10
|
+
}, {
|
|
11
|
+
full: 'unimportant',
|
|
12
|
+
major: 2,
|
|
13
|
+
minor: 39,
|
|
14
|
+
patch: 2
|
|
15
|
+
}, {
|
|
16
|
+
full: 'unimportant',
|
|
17
|
+
major: 2,
|
|
18
|
+
minor: 38,
|
|
19
|
+
patch: 3
|
|
20
|
+
}, {
|
|
21
|
+
full: 'unimportant',
|
|
22
|
+
major: 2,
|
|
23
|
+
minor: 37,
|
|
24
|
+
patch: 10
|
|
25
|
+
}, {
|
|
26
|
+
full: 'unimportant',
|
|
27
|
+
major: 2,
|
|
28
|
+
minor: 40,
|
|
29
|
+
tag: 'SNAPSHOT'
|
|
30
|
+
}, {
|
|
31
|
+
full: 'unimportant',
|
|
32
|
+
major: 2,
|
|
33
|
+
minor: 3291,
|
|
34
|
+
patch: 0
|
|
35
|
+
}];
|
|
36
|
+
const unsupportedVersions = [{
|
|
37
|
+
full: 'unimportant',
|
|
38
|
+
major: 2,
|
|
39
|
+
minor: 39,
|
|
40
|
+
patch: 1
|
|
41
|
+
}, {
|
|
42
|
+
full: 'unimportant',
|
|
43
|
+
major: 2,
|
|
44
|
+
minor: 38,
|
|
45
|
+
patch: 2
|
|
46
|
+
}, {
|
|
47
|
+
full: 'unimportant',
|
|
48
|
+
major: 2,
|
|
49
|
+
minor: 37,
|
|
50
|
+
patch: 9
|
|
51
|
+
}, {
|
|
52
|
+
full: 'unimportant',
|
|
53
|
+
major: 2,
|
|
54
|
+
minor: 36,
|
|
55
|
+
patch: 12
|
|
56
|
+
}, {
|
|
57
|
+
full: 'unimportant',
|
|
58
|
+
major: 2,
|
|
59
|
+
minor: 35,
|
|
60
|
+
patch: 0
|
|
61
|
+
}, {
|
|
62
|
+
full: 'unimportant',
|
|
63
|
+
major: 2,
|
|
64
|
+
minor: 0,
|
|
65
|
+
patch: 0
|
|
66
|
+
}];
|
|
67
|
+
test('supported server versions pass', () => {
|
|
68
|
+
fixedVersions.forEach(version => {
|
|
69
|
+
expect((0, _isPingAvailable.isPingAvailable)(version)).toBe(true);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
test('unsupported server versions fail', () => {
|
|
73
|
+
unsupportedVersions.forEach(version => {
|
|
74
|
+
expect((0, _isPingAvailable.isPingAvailable)(version)).toBe(false);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.DEFAULT_MAX_DELAY_MS = exports.DEFAULT_INITIAL_DELAY_MS = exports.DEFAULT_INCREMENT_FACTOR = void 0;
|
|
7
|
+
exports.default = createSmartInterval;
|
|
8
|
+
|
|
9
|
+
var _devDebugLog = require("./dev-debug-log");
|
|
10
|
+
|
|
11
|
+
// Exported for tests
|
|
12
|
+
const DEFAULT_INITIAL_DELAY_MS = 1000 * 30; // 30 sec
|
|
13
|
+
|
|
14
|
+
exports.DEFAULT_INITIAL_DELAY_MS = DEFAULT_INITIAL_DELAY_MS;
|
|
15
|
+
const DEFAULT_MAX_DELAY_MS = 1000 * 60 * 5; // 5 min
|
|
16
|
+
|
|
17
|
+
exports.DEFAULT_MAX_DELAY_MS = DEFAULT_MAX_DELAY_MS;
|
|
18
|
+
const DEFAULT_INCREMENT_FACTOR = 1.5;
|
|
19
|
+
exports.DEFAULT_INCREMENT_FACTOR = DEFAULT_INCREMENT_FACTOR;
|
|
20
|
+
|
|
21
|
+
const throwErrorIfNoCallbackIsProvided = () => {
|
|
22
|
+
throw new Error('Provide a callback');
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
function createSmartInterval() {
|
|
26
|
+
let {
|
|
27
|
+
initialDelay = DEFAULT_INITIAL_DELAY_MS,
|
|
28
|
+
maxDelay = DEFAULT_MAX_DELAY_MS,
|
|
29
|
+
delayIncrementFactor = DEFAULT_INCREMENT_FACTOR,
|
|
30
|
+
initialPauseValue = false,
|
|
31
|
+
callback = throwErrorIfNoCallbackIsProvided
|
|
32
|
+
} = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
33
|
+
const state = {
|
|
34
|
+
paused: initialPauseValue,
|
|
35
|
+
delay: initialDelay,
|
|
36
|
+
// Timeout types are weird; this dummy timeout helps fix them:
|
|
37
|
+
// (named to help debugging in tests)
|
|
38
|
+
timeout: setTimeout(function dummyTimeout() {
|
|
39
|
+
return;
|
|
40
|
+
}, 0),
|
|
41
|
+
standbyCallback: null
|
|
42
|
+
};
|
|
43
|
+
/** Increment delay by the increment factor, up to a max value */
|
|
44
|
+
|
|
45
|
+
function incrementDelay() {
|
|
46
|
+
const newDelay = Math.min(state.delay * delayIncrementFactor, maxDelay);
|
|
47
|
+
(0, _devDebugLog.devDebugLog)('[SI] incrementing delay', {
|
|
48
|
+
prev: state.delay,
|
|
49
|
+
new: newDelay
|
|
50
|
+
});
|
|
51
|
+
state.delay = newDelay;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function invokeCallbackAndHandleDelay() {
|
|
55
|
+
// Increment delay before calling callback, so callback can potentially
|
|
56
|
+
// reset the delay to initial before starting the next timeout
|
|
57
|
+
incrementDelay();
|
|
58
|
+
callback();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function clearTimeoutAndStart() {
|
|
62
|
+
(0, _devDebugLog.devDebugLog)('[SI] clearing and starting timeout', {
|
|
63
|
+
delay: state.delay
|
|
64
|
+
}); // Prevent parallel timeouts from occuring
|
|
65
|
+
// (weird note: `if (this.timeout) { clearTimeout(this.timeout) }`
|
|
66
|
+
// does NOT work for some reason)
|
|
67
|
+
|
|
68
|
+
clearTimeout(state.timeout); // A timeout is used instead of an interval for handling slow execution
|
|
69
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/setInterval#ensure_that_execution_duration_is_shorter_than_interval_frequency
|
|
70
|
+
|
|
71
|
+
state.timeout = setTimeout(function callbackAndRestart() {
|
|
72
|
+
if (state.paused) {
|
|
73
|
+
(0, _devDebugLog.devDebugLog)('[SI] entering regular standby'); // If paused, prepare a 'standby callback' to be invoked when
|
|
74
|
+
// `resume()` is called (see its definition below).
|
|
75
|
+
// The timer will not be started again until the standbyCallback
|
|
76
|
+
// is invoked.
|
|
77
|
+
|
|
78
|
+
state.standbyCallback = () => {
|
|
79
|
+
invokeCallbackAndHandleDelay();
|
|
80
|
+
clearTimeoutAndStart();
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
return;
|
|
84
|
+
} // Otherwise, invoke callback
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
invokeCallbackAndHandleDelay(); // and start process over again
|
|
88
|
+
|
|
89
|
+
clearTimeoutAndStart();
|
|
90
|
+
}, state.delay);
|
|
91
|
+
}
|
|
92
|
+
/** Stop the interval. Used for cleaning up */
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
function clear() {
|
|
96
|
+
clearTimeout(state.timeout);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Invoke the provided callback immediately and start the timer over.
|
|
100
|
+
* The timeout to the next invocation will not be increased
|
|
101
|
+
* (unless the timer fully elapses while this interval is paused).
|
|
102
|
+
*
|
|
103
|
+
* If the interval is 'paused', it will not invoke the callback immediately,
|
|
104
|
+
* but enter a 'partial standby', which will invoke the callback upon
|
|
105
|
+
* resuming, but without incrementing the delay. If the regular timeout
|
|
106
|
+
* elapses while paused, the regular standby is entered, overwriting this
|
|
107
|
+
* partial standby.
|
|
108
|
+
*/
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
function invokeCallbackImmediately() {
|
|
112
|
+
if (state.paused) {
|
|
113
|
+
if (state.standbyCallback === null) {
|
|
114
|
+
// If there is not an existing standbyCallback,
|
|
115
|
+
// set one to be called upon `resume()`
|
|
116
|
+
// (but don't overwrite a previous callback).
|
|
117
|
+
// See setTimeout call above too.
|
|
118
|
+
// The timed out function set in `clearTimeoutAndStart` may
|
|
119
|
+
// overwrite this callback if the timer elapses, so that the
|
|
120
|
+
// timeout delay gets incremented appropriately.
|
|
121
|
+
(0, _devDebugLog.devDebugLog)('[SI] entering standby without timer increment');
|
|
122
|
+
|
|
123
|
+
state.standbyCallback = () => {
|
|
124
|
+
// Invoke callback and start timer without incrementing
|
|
125
|
+
callback();
|
|
126
|
+
clearTimeoutAndStart();
|
|
127
|
+
};
|
|
128
|
+
} // Skip rest of execution while paused
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
return;
|
|
132
|
+
} // Invoke callback and start timer without incrementing
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
callback();
|
|
136
|
+
clearTimeoutAndStart();
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Sets a 'paused' flag (doesn't yet stop the timer):
|
|
140
|
+
*
|
|
141
|
+
* If the main timer elapses or `invokeCallbackImmediately` is called
|
|
142
|
+
* while the interval is paused, the timer will not be started again.
|
|
143
|
+
* Instead, a callback function will be saved that will be called when
|
|
144
|
+
* `resume()` is called (see its definition below)
|
|
145
|
+
*
|
|
146
|
+
* This decreases execution activity while 'paused'
|
|
147
|
+
*/
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
function pause() {
|
|
151
|
+
(0, _devDebugLog.devDebugLog)('[SI] pausing');
|
|
152
|
+
state.paused = true;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Removes 'paused' state
|
|
156
|
+
*
|
|
157
|
+
* If the interval is in 'standby', trigger the saved 'standbyCallback',
|
|
158
|
+
* which should start the interval timer again
|
|
159
|
+
*/
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
function resume() {
|
|
163
|
+
(0, _devDebugLog.devDebugLog)('[SI] resuming', {
|
|
164
|
+
standbyCb: state.standbyCallback
|
|
165
|
+
}); // Clear paused state
|
|
166
|
+
|
|
167
|
+
state.paused = false; // If in standby, invoke the saved callback
|
|
168
|
+
// (invokeCallbackImmediately and clearTimeoutAndStart can set a
|
|
169
|
+
// standby callback)
|
|
170
|
+
|
|
171
|
+
if (state.standbyCallback !== null) {
|
|
172
|
+
state.standbyCallback(); // Remove existing standbyCallback
|
|
173
|
+
|
|
174
|
+
state.standbyCallback = null;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Restart the timer to the next callback invocation, using the current
|
|
179
|
+
* delay
|
|
180
|
+
*
|
|
181
|
+
* Expected to be called to delay a ping in response to incidental network
|
|
182
|
+
* traffic, for example
|
|
183
|
+
*/
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
function snooze() {
|
|
187
|
+
(0, _devDebugLog.devDebugLog)('[SI] snoozing timeout');
|
|
188
|
+
clearTimeoutAndStart();
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Cancels the current timeout and starts a new one with the initial delay
|
|
192
|
+
*/
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
function reset() {
|
|
196
|
+
(0, _devDebugLog.devDebugLog)('[SI] resetting interval from beginning');
|
|
197
|
+
state.delay = initialDelay;
|
|
198
|
+
clearTimeoutAndStart();
|
|
199
|
+
} // Start the timer!
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
clearTimeoutAndStart();
|
|
203
|
+
return {
|
|
204
|
+
clear,
|
|
205
|
+
pause,
|
|
206
|
+
resume,
|
|
207
|
+
invokeCallbackImmediately,
|
|
208
|
+
snooze,
|
|
209
|
+
reset
|
|
210
|
+
};
|
|
211
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.usePingQuery = usePingQuery;
|
|
7
|
+
|
|
8
|
+
var _appServiceConfig = require("@dhis2/app-service-config");
|
|
9
|
+
|
|
10
|
+
var _react = require("react");
|
|
11
|
+
|
|
12
|
+
// This function has a separate file for easier mocking
|
|
13
|
+
function usePingQuery() {
|
|
14
|
+
const {
|
|
15
|
+
baseUrl
|
|
16
|
+
} = (0, _appServiceConfig.useConfig)(); // This endpoint doesn't need any extra headers or handling since it's
|
|
17
|
+
// public. It doesn't extend the user session. See DHIS2-14531
|
|
18
|
+
|
|
19
|
+
const ping = (0, _react.useCallback)(() => fetch(baseUrl + '/api/ping'), [baseUrl]);
|
|
20
|
+
return ping;
|
|
21
|
+
}
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
exports.useGlobalState = exports.createStore = exports.GlobalStateProvider = void 0;
|
|
6
7
|
exports.useGlobalStateMutation = useGlobalStateMutation;
|
|
7
|
-
exports.useGlobalState = exports.GlobalStateProvider = exports.createStore = void 0;
|
|
8
8
|
|
|
9
9
|
var _isEqual = _interopRequireDefault(require("lodash/isEqual"));
|
|
10
10
|
|
|
@@ -23,7 +23,8 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
23
23
|
// See more at https://github.com/amcgee/state-service-poc
|
|
24
24
|
const identity = state => state;
|
|
25
25
|
|
|
26
|
-
const createStore = (
|
|
26
|
+
const createStore = function () {
|
|
27
|
+
let initialState = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
27
28
|
const subscriptions = new Set();
|
|
28
29
|
let state = initialState;
|
|
29
30
|
return {
|
|
@@ -50,12 +51,15 @@ const GlobalStateContext = /*#__PURE__*/_react.default.createContext(createStore
|
|
|
50
51
|
|
|
51
52
|
const useGlobalStateStore = () => (0, _react.useContext)(GlobalStateContext);
|
|
52
53
|
|
|
53
|
-
const GlobalStateProvider = ({
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
const GlobalStateProvider = (_ref) => {
|
|
55
|
+
let {
|
|
56
|
+
store,
|
|
57
|
+
children
|
|
58
|
+
} = _ref;
|
|
59
|
+
return /*#__PURE__*/_react.default.createElement(GlobalStateContext.Provider, {
|
|
60
|
+
value: store
|
|
61
|
+
}, children);
|
|
62
|
+
};
|
|
59
63
|
|
|
60
64
|
exports.GlobalStateProvider = GlobalStateProvider;
|
|
61
65
|
GlobalStateProvider.propTypes = {
|
|
@@ -63,7 +67,8 @@ GlobalStateProvider.propTypes = {
|
|
|
63
67
|
store: _propTypes.default.shape({})
|
|
64
68
|
};
|
|
65
69
|
|
|
66
|
-
const useGlobalState = (
|
|
70
|
+
const useGlobalState = function () {
|
|
71
|
+
let selector = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : identity;
|
|
67
72
|
const store = useGlobalStateStore();
|
|
68
73
|
const [selectedState, setSelectedState] = (0, _react.useState)(selector(store.getState()));
|
|
69
74
|
(0, _react.useEffect)(() => {
|
|
@@ -91,7 +96,7 @@ exports.useGlobalState = useGlobalState;
|
|
|
91
96
|
|
|
92
97
|
function useGlobalStateMutation(mutationCreator) {
|
|
93
98
|
const store = useGlobalStateStore();
|
|
94
|
-
return (0, _react.useCallback)((
|
|
95
|
-
store.mutate(mutationCreator(...
|
|
99
|
+
return (0, _react.useCallback)(function () {
|
|
100
|
+
store.mutate(mutationCreator(...arguments));
|
|
96
101
|
}, [mutationCreator, store]);
|
|
97
102
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.useNetworkStatus = useNetworkStatus;
|
|
7
7
|
|
|
8
8
|
var _debounce = _interopRequireDefault(require("lodash/debounce"));
|
|
9
9
|
|
|
@@ -29,15 +29,18 @@ const lastOnlineKey = 'dhis2.lastOnline'; // TODO: Add option to periodically pi
|
|
|
29
29
|
* @returns {Object} `{ online: boolean, offline: boolean, lastOnline: Date | null }`
|
|
30
30
|
*/
|
|
31
31
|
|
|
32
|
-
function
|
|
32
|
+
function useNetworkStatus() {
|
|
33
33
|
var _options$debounceDela;
|
|
34
34
|
|
|
35
|
+
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
35
36
|
// initialize state to `navigator.onLine` value
|
|
36
37
|
const [online, setOnline] = (0, _react.useState)(navigator.onLine); // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
37
38
|
|
|
38
|
-
const updateState = (0, _react.useCallback)((0, _debounce.default)(({
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
const updateState = (0, _react.useCallback)((0, _debounce.default)((_ref) => {
|
|
40
|
+
let {
|
|
41
|
+
type
|
|
42
|
+
} = _ref;
|
|
43
|
+
|
|
41
44
|
if (type === 'online') {
|
|
42
45
|
setOnline(true);
|
|
43
46
|
} else if (type === 'offline') {
|
|
@@ -19,6 +19,8 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
19
19
|
// This is to prevent 'offlineInterface could be null' type-checking errors
|
|
20
20
|
const noopOfflineInterface = {
|
|
21
21
|
pwaEnabled: false,
|
|
22
|
+
latestIsConnected: false,
|
|
23
|
+
subscribeToDhis2ConnectionStatus: () => () => undefined,
|
|
22
24
|
startRecording: async () => undefined,
|
|
23
25
|
getCachedSections: async () => [],
|
|
24
26
|
removeSection: async () => false
|
|
@@ -33,10 +35,11 @@ const OfflineInterfaceContext = /*#__PURE__*/(0, _react.createContext)(noopOffli
|
|
|
33
35
|
* checks for service worker updates and, if updates are ready, prompts the
|
|
34
36
|
* user with an alert to skip waiting and reload the page to use new content.
|
|
35
37
|
*/
|
|
36
|
-
function OfflineInterfaceProvider({
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
function OfflineInterfaceProvider(_ref) {
|
|
39
|
+
let {
|
|
40
|
+
offlineInterface,
|
|
41
|
+
children
|
|
42
|
+
} = _ref;
|
|
40
43
|
return /*#__PURE__*/_react.default.createElement(OfflineInterfaceContext.Provider, {
|
|
41
44
|
value: offlineInterface
|
|
42
45
|
}, children);
|
|
@@ -11,6 +11,8 @@ var _react = _interopRequireDefault(require("react"));
|
|
|
11
11
|
|
|
12
12
|
var _cacheableSectionState = require("./cacheable-section-state");
|
|
13
13
|
|
|
14
|
+
var _dhis2ConnectionStatus = require("./dhis2-connection-status");
|
|
15
|
+
|
|
14
16
|
var _offlineInterface = require("./offline-interface");
|
|
15
17
|
|
|
16
18
|
var _onlineStatusMessage = require("./online-status-message");
|
|
@@ -18,10 +20,12 @@ var _onlineStatusMessage = require("./online-status-message");
|
|
|
18
20
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
19
21
|
|
|
20
22
|
/** A context provider for all the relevant offline contexts */
|
|
21
|
-
function OfflineProvider({
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
function OfflineProvider(_ref) {
|
|
24
|
+
let {
|
|
25
|
+
offlineInterface,
|
|
26
|
+
children
|
|
27
|
+
} = _ref;
|
|
28
|
+
|
|
25
29
|
// If an offline interface is not provided, or if one is provided and PWA
|
|
26
30
|
// is not enabled, skip adding context providers
|
|
27
31
|
if (!offlineInterface || !offlineInterface.pwaEnabled) {
|
|
@@ -30,7 +34,7 @@ function OfflineProvider({
|
|
|
30
34
|
|
|
31
35
|
return /*#__PURE__*/_react.default.createElement(_offlineInterface.OfflineInterfaceProvider, {
|
|
32
36
|
offlineInterface: offlineInterface
|
|
33
|
-
}, /*#__PURE__*/_react.default.createElement(_cacheableSectionState.CacheableSectionProvider, null, /*#__PURE__*/_react.default.createElement(_onlineStatusMessage.OnlineStatusMessageProvider, null, children)));
|
|
37
|
+
}, /*#__PURE__*/_react.default.createElement(_dhis2ConnectionStatus.Dhis2ConnectionStatusProvider, null, /*#__PURE__*/_react.default.createElement(_cacheableSectionState.CacheableSectionProvider, null, /*#__PURE__*/_react.default.createElement(_onlineStatusMessage.OnlineStatusMessageProvider, null, children))));
|
|
34
38
|
}
|
|
35
39
|
|
|
36
40
|
OfflineProvider.propTypes = {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.useOnlineStatusMessage = exports.OnlineStatusMessageProvider = void 0;
|
|
7
7
|
|
|
8
8
|
var _react = _interopRequireWildcard(require("react"));
|
|
9
9
|
|
|
@@ -31,9 +31,10 @@ const useOnlineStatusMessage = () => {
|
|
|
31
31
|
|
|
32
32
|
exports.useOnlineStatusMessage = useOnlineStatusMessage;
|
|
33
33
|
|
|
34
|
-
const OnlineStatusMessageProvider = ({
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
const OnlineStatusMessageProvider = (_ref) => {
|
|
35
|
+
let {
|
|
36
|
+
children
|
|
37
|
+
} = _ref;
|
|
37
38
|
const [onlineStatusMessage, setOnlineStatusMessage] = (0, _react.useState)();
|
|
38
39
|
return /*#__PURE__*/_react.default.createElement(OnlineStatusMessageContext.Provider, {
|
|
39
40
|
value: {
|
|
@@ -9,10 +9,12 @@ var _react = _interopRequireDefault(require("react"));
|
|
|
9
9
|
|
|
10
10
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
11
|
|
|
12
|
-
const RenderCounter = ({
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
const RenderCounter = (_ref) => {
|
|
13
|
+
let {
|
|
14
|
+
id,
|
|
15
|
+
countsObj
|
|
16
|
+
} = _ref;
|
|
17
|
+
|
|
16
18
|
if (!(id in countsObj)) {
|
|
17
19
|
countsObj[id] = 0;
|
|
18
20
|
}
|
|
@@ -3,11 +3,13 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
7
|
-
const successfulRecordingMock = jest.fn().mockImplementation(async ({
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
exports.successfulRecordingMock = exports.mockOfflineInterface = exports.failedMessageRecordingMock = exports.errorRecordingMock = void 0;
|
|
7
|
+
const successfulRecordingMock = jest.fn().mockImplementation(async function () {
|
|
8
|
+
let {
|
|
9
|
+
onStarted,
|
|
10
|
+
onCompleted
|
|
11
|
+
} = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
12
|
+
|
|
11
13
|
// in 100ms, call 'onStarted' callback (allows 'pending' state)
|
|
12
14
|
if (onStarted) {
|
|
13
15
|
setTimeout(onStarted, 100);
|
|
@@ -22,10 +24,12 @@ const successfulRecordingMock = jest.fn().mockImplementation(async ({
|
|
|
22
24
|
return Promise.resolve();
|
|
23
25
|
});
|
|
24
26
|
exports.successfulRecordingMock = successfulRecordingMock;
|
|
25
|
-
const errorRecordingMock = jest.fn().mockImplementation(({
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
const errorRecordingMock = jest.fn().mockImplementation(function () {
|
|
28
|
+
let {
|
|
29
|
+
onStarted,
|
|
30
|
+
onError
|
|
31
|
+
} = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
32
|
+
|
|
29
33
|
// in 100ms, call 'onStarted' callback (allows 'pending' state)
|
|
30
34
|
if (onStarted) {
|
|
31
35
|
setTimeout(onStarted, 100);
|
|
@@ -41,8 +45,11 @@ const failedMessageRecordingMock = jest.fn().mockRejectedValue(new Error('Failed
|
|
|
41
45
|
exports.failedMessageRecordingMock = failedMessageRecordingMock;
|
|
42
46
|
const mockOfflineInterface = {
|
|
43
47
|
pwaEnabled: true,
|
|
48
|
+
latestIsConnected: true,
|
|
44
49
|
startRecording: successfulRecordingMock,
|
|
45
50
|
getCachedSections: jest.fn().mockResolvedValue([]),
|
|
46
|
-
removeSection: jest.fn().mockResolvedValue(true)
|
|
51
|
+
removeSection: jest.fn().mockResolvedValue(true),
|
|
52
|
+
// returns an unsubscribe function
|
|
53
|
+
subscribeToDhis2ConnectionStatus: jest.fn().mockReturnValue(() => undefined)
|
|
47
54
|
};
|
|
48
55
|
exports.mockOfflineInterface = mockOfflineInterface;
|