@copart/ops-tool-kit 1.12.12 → 1.12.13-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ops-tool-kit.js +504 -8
- package/dist/ops-tool-kit.js.map +1 -1
- package/package.json +1 -1
package/dist/ops-tool-kit.js
CHANGED
|
@@ -47,7 +47,7 @@ var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
|
47
47
|
var ReactDOM__default = /*#__PURE__*/_interopDefaultLegacy(ReactDOM);
|
|
48
48
|
|
|
49
49
|
const name$r = "@copart/ops-tool-kit";
|
|
50
|
-
const version$8 = "1.12.
|
|
50
|
+
const version$8 = "1.12.13-alpha.1";
|
|
51
51
|
const main$1 = "dist/ops-tool-kit.js";
|
|
52
52
|
const style = "dist/ops-tool-kit.css";
|
|
53
53
|
const files = [
|
|
@@ -2622,6 +2622,12 @@ var createOpsStorage = function createOpsStorage() {
|
|
|
2622
2622
|
get userEmail() {
|
|
2623
2623
|
return getLocalItem('login', 'userData.entity_mail');
|
|
2624
2624
|
},
|
|
2625
|
+
get userCopartId() {
|
|
2626
|
+
return getLocalItem('login', 'userData.entity_employee_copart_id');
|
|
2627
|
+
},
|
|
2628
|
+
get userSamAccount() {
|
|
2629
|
+
return getLocalItem('login', 'userData.entity_sam_id');
|
|
2630
|
+
},
|
|
2625
2631
|
get userCountry() {
|
|
2626
2632
|
return getLocalItem('login', 'userData.entity_country');
|
|
2627
2633
|
},
|
|
@@ -21417,13 +21423,15 @@ var LogOutMenu = function LogOutMenu(_ref) {
|
|
|
21417
21423
|
availableStatuses = _ref$availableStatuse === void 0 ? [] : _ref$availableStatuse,
|
|
21418
21424
|
currentUserStatus = _ref.currentUserStatus;
|
|
21419
21425
|
var getStatusColor = function getStatusColor() {
|
|
21426
|
+
var _currentUserStatus$to;
|
|
21420
21427
|
if (!currentUserStatus || !Array.isArray(availableStatuses)) {
|
|
21421
21428
|
return '#9A9B98'; // Default color
|
|
21422
21429
|
}
|
|
21423
21430
|
var statusObj = availableStatuses.find(function (status) {
|
|
21424
21431
|
return status.status === currentUserStatus;
|
|
21425
21432
|
});
|
|
21426
|
-
|
|
21433
|
+
var defaultColor = currentUserStatus !== null && currentUserStatus !== void 0 && (_currentUserStatus$to = currentUserStatus.toLowerCase()) !== null && _currentUserStatus$to !== void 0 && _currentUserStatus$to.includes("system") ? "#9A9B98" : '#BC2F32';
|
|
21434
|
+
return (statusObj === null || statusObj === void 0 ? void 0 : statusObj.colour) || defaultColor;
|
|
21427
21435
|
};
|
|
21428
21436
|
var statusColor = getStatusColor();
|
|
21429
21437
|
|
|
@@ -21483,9 +21491,10 @@ var ProfileDetails = function ProfileDetails(_ref) {
|
|
|
21483
21491
|
return status.status === currentUserStatus;
|
|
21484
21492
|
});
|
|
21485
21493
|
if (!statusExists) {
|
|
21494
|
+
var _currentUserStatus$to;
|
|
21486
21495
|
return [].concat(_toConsumableArray(availableStatuses), [{
|
|
21487
21496
|
status: currentUserStatus,
|
|
21488
|
-
colour: '#BC2F32',
|
|
21497
|
+
colour: currentUserStatus !== null && currentUserStatus !== void 0 && (_currentUserStatus$to = currentUserStatus.toLowerCase()) !== null && _currentUserStatus$to !== void 0 && _currentUserStatus$to.includes("system") ? "#9A9B98" : '#BC2F32',
|
|
21489
21498
|
disabled: true
|
|
21490
21499
|
}]);
|
|
21491
21500
|
}
|
|
@@ -35147,6 +35156,41 @@ function LatestReleaseDialog(_ref) {
|
|
|
35147
35156
|
})))));
|
|
35148
35157
|
}
|
|
35149
35158
|
|
|
35159
|
+
var SystemOfflineDialog = function SystemOfflineDialog(_ref) {
|
|
35160
|
+
var isOpen = _ref.isOpen,
|
|
35161
|
+
onClose = _ref.onClose,
|
|
35162
|
+
onMakeAvailable = _ref.onMakeAvailable,
|
|
35163
|
+
onStayOffline = _ref.onStayOffline;
|
|
35164
|
+
var handleStayOffline = function handleStayOffline() {
|
|
35165
|
+
onStayOffline === null || onStayOffline === void 0 ? void 0 : onStayOffline();
|
|
35166
|
+
onClose === null || onClose === void 0 ? void 0 : onClose();
|
|
35167
|
+
};
|
|
35168
|
+
var handleMakeAvailable = function handleMakeAvailable() {
|
|
35169
|
+
onMakeAvailable === null || onMakeAvailable === void 0 ? void 0 : onMakeAvailable();
|
|
35170
|
+
onClose === null || onClose === void 0 ? void 0 : onClose();
|
|
35171
|
+
};
|
|
35172
|
+
return /*#__PURE__*/React__default["default"].createElement(coreComponents.Dialog, {
|
|
35173
|
+
title: "The system marked you as offline",
|
|
35174
|
+
isOpen: isOpen,
|
|
35175
|
+
dismiss: handleStayOffline
|
|
35176
|
+
}, /*#__PURE__*/React__default["default"].createElement("div", {
|
|
35177
|
+
style: {
|
|
35178
|
+
padding: '20px'
|
|
35179
|
+
}
|
|
35180
|
+
}, /*#__PURE__*/React__default["default"].createElement("p", null, "You've been marked offline by the system. Would you like to make yourself available?"), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
35181
|
+
style: {
|
|
35182
|
+
display: 'flex',
|
|
35183
|
+
justifyContent: 'flex-end',
|
|
35184
|
+
marginTop: '16px'
|
|
35185
|
+
}
|
|
35186
|
+
}, /*#__PURE__*/React__default["default"].createElement(coreComponents.Button, {
|
|
35187
|
+
primary: true,
|
|
35188
|
+
onClick: handleMakeAvailable
|
|
35189
|
+
}, "Yes"), /*#__PURE__*/React__default["default"].createElement(coreComponents.Button, {
|
|
35190
|
+
onClick: handleStayOffline
|
|
35191
|
+
}, "Stay offline"))));
|
|
35192
|
+
};
|
|
35193
|
+
|
|
35150
35194
|
var naiveFallback = function () {
|
|
35151
35195
|
if (typeof self === "object" && self) return self;
|
|
35152
35196
|
if (typeof window === "object" && window) return window;
|
|
@@ -35613,7 +35657,7 @@ var fetchAvailableStatuses = /*#__PURE__*/function () {
|
|
|
35613
35657
|
coreAppConfig = storage$1.getLocalItem('opsportal-core:config');
|
|
35614
35658
|
endpoints = coreAppConfig.endpoints;
|
|
35615
35659
|
email = storage$1.userEmail || '';
|
|
35616
|
-
endpoint = frontEndUtils.string.substitute(endpoints.getAvailableStatusesByUser, {
|
|
35660
|
+
endpoint = frontEndUtils.string.substitute(endpoints === null || endpoints === void 0 ? void 0 : endpoints.getAvailableStatusesByUser, {
|
|
35617
35661
|
email: email
|
|
35618
35662
|
});
|
|
35619
35663
|
_context.p = 1;
|
|
@@ -35646,7 +35690,7 @@ var fetchUserStatus = /*#__PURE__*/function () {
|
|
|
35646
35690
|
coreAppConfig = storage$1.getLocalItem('opsportal-core:config');
|
|
35647
35691
|
endpoints = coreAppConfig.endpoints;
|
|
35648
35692
|
email = storage$1.userEmail || '';
|
|
35649
|
-
endpoint = frontEndUtils.string.substitute(endpoints.getUserStatus, {
|
|
35693
|
+
endpoint = frontEndUtils.string.substitute(endpoints === null || endpoints === void 0 ? void 0 : endpoints.getUserStatus, {
|
|
35650
35694
|
email: email
|
|
35651
35695
|
});
|
|
35652
35696
|
_context2.p = 1;
|
|
@@ -35678,7 +35722,7 @@ var updateUserStatus = /*#__PURE__*/function () {
|
|
|
35678
35722
|
case 0:
|
|
35679
35723
|
coreAppConfig = storage$1.getLocalItem('opsportal-core:config');
|
|
35680
35724
|
endpoints = coreAppConfig.endpoints;
|
|
35681
|
-
endpoint = endpoints.updateUserStatus;
|
|
35725
|
+
endpoint = endpoints === null || endpoints === void 0 ? void 0 : endpoints.updateUserStatus;
|
|
35682
35726
|
requestBody = {
|
|
35683
35727
|
status: statusId,
|
|
35684
35728
|
email: storage$1.userEmail,
|
|
@@ -35706,6 +35750,359 @@ var updateUserStatus = /*#__PURE__*/function () {
|
|
|
35706
35750
|
return _ref3.apply(this, arguments);
|
|
35707
35751
|
};
|
|
35708
35752
|
}();
|
|
35753
|
+
var sendHeartBeat = /*#__PURE__*/function () {
|
|
35754
|
+
var _ref4 = _asyncToGenerator$1(/*#__PURE__*/_regenerator().m(function _callee4() {
|
|
35755
|
+
var coreAppConfig, endpoints, endpoint, requestBody, _t4;
|
|
35756
|
+
return _regenerator().w(function (_context4) {
|
|
35757
|
+
while (1) switch (_context4.p = _context4.n) {
|
|
35758
|
+
case 0:
|
|
35759
|
+
coreAppConfig = storage$1.getLocalItem('opsportal-core:config');
|
|
35760
|
+
endpoints = coreAppConfig.endpoints;
|
|
35761
|
+
endpoint = endpoints === null || endpoints === void 0 ? void 0 : endpoints.sendHeartBeat;
|
|
35762
|
+
requestBody = {
|
|
35763
|
+
email: storage$1.userEmail,
|
|
35764
|
+
timeStamp: moment.utc().format('YYYY-MM-DD HH:mm:ss'),
|
|
35765
|
+
copartId: storage$1.userCopartId,
|
|
35766
|
+
samAccount: storage$1.userSamAccount
|
|
35767
|
+
};
|
|
35768
|
+
_context4.p = 1;
|
|
35769
|
+
_context4.n = 2;
|
|
35770
|
+
return fetcher.post(endpoint, requestBody);
|
|
35771
|
+
case 2:
|
|
35772
|
+
_context4.n = 4;
|
|
35773
|
+
break;
|
|
35774
|
+
case 3:
|
|
35775
|
+
_context4.p = 3;
|
|
35776
|
+
_t4 = _context4.v;
|
|
35777
|
+
console.error('Failed to send heart beat:', _t4);
|
|
35778
|
+
case 4:
|
|
35779
|
+
return _context4.a(2);
|
|
35780
|
+
}
|
|
35781
|
+
}, _callee4, null, [[1, 3]]);
|
|
35782
|
+
}));
|
|
35783
|
+
return function sendHeartBeat() {
|
|
35784
|
+
return _ref4.apply(this, arguments);
|
|
35785
|
+
};
|
|
35786
|
+
}();
|
|
35787
|
+
var sendUserInteractionEvent = /*#__PURE__*/function () {
|
|
35788
|
+
var _ref5 = _asyncToGenerator$1(/*#__PURE__*/_regenerator().m(function _callee5() {
|
|
35789
|
+
var didInteract,
|
|
35790
|
+
coreAppConfig,
|
|
35791
|
+
endpoints,
|
|
35792
|
+
endpoint,
|
|
35793
|
+
requestBody,
|
|
35794
|
+
_args5 = arguments,
|
|
35795
|
+
_t5;
|
|
35796
|
+
return _regenerator().w(function (_context5) {
|
|
35797
|
+
while (1) switch (_context5.p = _context5.n) {
|
|
35798
|
+
case 0:
|
|
35799
|
+
didInteract = _args5.length > 0 && _args5[0] !== undefined ? _args5[0] : false;
|
|
35800
|
+
coreAppConfig = storage$1.getLocalItem('opsportal-core:config');
|
|
35801
|
+
endpoints = coreAppConfig.endpoints;
|
|
35802
|
+
endpoint = endpoints === null || endpoints === void 0 ? void 0 : endpoints.sendUserInteractionEvent;
|
|
35803
|
+
requestBody = {
|
|
35804
|
+
email: storage$1.userEmail,
|
|
35805
|
+
timeStamp: moment.utc().format('YYYY-MM-DD HH:mm:ss'),
|
|
35806
|
+
copartId: storage$1.userCopartId,
|
|
35807
|
+
samAccount: storage$1.userSamAccount,
|
|
35808
|
+
userConnectivity: didInteract
|
|
35809
|
+
};
|
|
35810
|
+
_context5.p = 1;
|
|
35811
|
+
_context5.n = 2;
|
|
35812
|
+
return fetcher.post(endpoint, requestBody);
|
|
35813
|
+
case 2:
|
|
35814
|
+
_context5.n = 4;
|
|
35815
|
+
break;
|
|
35816
|
+
case 3:
|
|
35817
|
+
_context5.p = 3;
|
|
35818
|
+
_t5 = _context5.v;
|
|
35819
|
+
console.error('Failed to send user interaction event:', _t5);
|
|
35820
|
+
case 4:
|
|
35821
|
+
return _context5.a(2);
|
|
35822
|
+
}
|
|
35823
|
+
}, _callee5, null, [[1, 3]]);
|
|
35824
|
+
}));
|
|
35825
|
+
return function sendUserInteractionEvent() {
|
|
35826
|
+
return _ref5.apply(this, arguments);
|
|
35827
|
+
};
|
|
35828
|
+
}();
|
|
35829
|
+
|
|
35830
|
+
/**
|
|
35831
|
+
* Single-heartbeat / single-user-interaction across tabs (leader election)
|
|
35832
|
+
* - One tab becomes leader and sends heartbeat + user interaction events
|
|
35833
|
+
* - Other tabs are followers
|
|
35834
|
+
* - If leader dies, re-election happens automatically
|
|
35835
|
+
* - Uses BroadcastChannel + localStorage (works in Chrome, Edge, Firefox, Safari 15.4+)
|
|
35836
|
+
*/
|
|
35837
|
+
|
|
35838
|
+
var LOCK_KEY_PREFIX = 'ops_hb_leader_lock:';
|
|
35839
|
+
var CHANNEL_PREFIX = 'ops_hb_channel:';
|
|
35840
|
+
var LAST_INTERACTION_KEY_PREFIX = 'ops_hb_last_interaction:';
|
|
35841
|
+
var LOCK_TTL_MS = 15000;
|
|
35842
|
+
var RENEW_EVERY_MS = 5000;
|
|
35843
|
+
var ELECTION_INTERVAL_MS = 4000;
|
|
35844
|
+
var JITTER_MS = 800;
|
|
35845
|
+
var STORAGE_TEST_KEY = 'ops_hb_storage_test';
|
|
35846
|
+
var isStorageAvailable = function isStorageAvailable() {
|
|
35847
|
+
try {
|
|
35848
|
+
localStorage.setItem(STORAGE_TEST_KEY, '1');
|
|
35849
|
+
var ok = localStorage.getItem(STORAGE_TEST_KEY) === '1';
|
|
35850
|
+
localStorage.removeItem(STORAGE_TEST_KEY);
|
|
35851
|
+
return ok;
|
|
35852
|
+
} catch (error) {
|
|
35853
|
+
console.error('[TabLeaderCoordinator] Storage availability check failed:', error);
|
|
35854
|
+
return false;
|
|
35855
|
+
}
|
|
35856
|
+
};
|
|
35857
|
+
var getTabId = function getTabId() {
|
|
35858
|
+
if (typeof crypto !== 'undefined' && crypto.randomUUID) {
|
|
35859
|
+
return crypto.randomUUID();
|
|
35860
|
+
}
|
|
35861
|
+
return "tab_".concat(Date.now(), "_").concat(Math.random().toString(36).slice(2));
|
|
35862
|
+
};
|
|
35863
|
+
|
|
35864
|
+
// In-memory fallback when localStorage is disabled (per-tab)
|
|
35865
|
+
var fallbackInteractionStore = new Map();
|
|
35866
|
+
|
|
35867
|
+
/**
|
|
35868
|
+
* Records user interaction timestamp. Call from ANY tab on user interaction.
|
|
35869
|
+
* When localStorage works: leader reads this to determine if user was active.
|
|
35870
|
+
* When localStorage disabled: each tab uses its own in-memory store for per-tab fallback.
|
|
35871
|
+
* @param {string} userKey - Unique user identifier (e.g. email)
|
|
35872
|
+
*/
|
|
35873
|
+
var recordUserInteraction = function recordUserInteraction(userKey) {
|
|
35874
|
+
if (!userKey) return;
|
|
35875
|
+
var ts = Date.now();
|
|
35876
|
+
var key = "".concat(LAST_INTERACTION_KEY_PREFIX).concat(userKey);
|
|
35877
|
+
try {
|
|
35878
|
+
localStorage.setItem(key, String(ts));
|
|
35879
|
+
} catch (error) {
|
|
35880
|
+
console.error('[TabLeaderCoordinator] recordUserInteraction localStorage failed:', error);
|
|
35881
|
+
fallbackInteractionStore.set(userKey, ts);
|
|
35882
|
+
}
|
|
35883
|
+
};
|
|
35884
|
+
var getLastInteractionTime = function getLastInteractionTime(userKey, useFallback) {
|
|
35885
|
+
if (useFallback) {
|
|
35886
|
+
return fallbackInteractionStore.get(userKey) || null;
|
|
35887
|
+
}
|
|
35888
|
+
try {
|
|
35889
|
+
var val = localStorage.getItem("".concat(LAST_INTERACTION_KEY_PREFIX).concat(userKey));
|
|
35890
|
+
return val ? parseInt(val, 10) : null;
|
|
35891
|
+
} catch (error) {
|
|
35892
|
+
console.error('[TabLeaderCoordinator] getLastInteractionTime failed:', error);
|
|
35893
|
+
return null;
|
|
35894
|
+
}
|
|
35895
|
+
};
|
|
35896
|
+
|
|
35897
|
+
/**
|
|
35898
|
+
* Starts the tab leader coordinator. Only the leader tab will call onHeartbeat and onUserInteractionCheck.
|
|
35899
|
+
* When localStorage is disabled (e.g. strict privacy mode), falls back to per-tab behavior: each tab sends
|
|
35900
|
+
* heartbeat and user interaction events independently.
|
|
35901
|
+
* @param {Object} options
|
|
35902
|
+
* @param {() => Promise<void>} options.onHeartbeat - Called periodically by leader
|
|
35903
|
+
* @param {(didInteract: boolean) => Promise<void>} options.onUserInteractionCheck - Called periodically by leader with interaction status
|
|
35904
|
+
* @param {number} options.heartBeatIntervalMs - Heartbeat interval in ms
|
|
35905
|
+
* @param {number} options.userInteractionIntervalMs - User interaction check interval in ms
|
|
35906
|
+
* @param {string} options.userKey - User identifier for lock/channel keys (e.g. storage.userEmail)
|
|
35907
|
+
* @returns {() => void} Stop function - call to release lock and cleanup
|
|
35908
|
+
*/
|
|
35909
|
+
var startTabLeaderCoordinator = function startTabLeaderCoordinator(_ref) {
|
|
35910
|
+
var onHeartbeat = _ref.onHeartbeat,
|
|
35911
|
+
onUserInteractionCheck = _ref.onUserInteractionCheck,
|
|
35912
|
+
heartBeatIntervalMs = _ref.heartBeatIntervalMs,
|
|
35913
|
+
userInteractionIntervalMs = _ref.userInteractionIntervalMs,
|
|
35914
|
+
userKey = _ref.userKey;
|
|
35915
|
+
if (!userKey) return function () {};
|
|
35916
|
+
var runPerTabFallback = function runPerTabFallback() {
|
|
35917
|
+
onHeartbeat === null || onHeartbeat === void 0 ? void 0 : onHeartbeat().catch(function (error) {
|
|
35918
|
+
console.error('[TabLeaderCoordinator] onHeartbeat failed:', error);
|
|
35919
|
+
});
|
|
35920
|
+
var hadInteraction = function hadInteraction() {
|
|
35921
|
+
var last = getLastInteractionTime(userKey, true);
|
|
35922
|
+
if (last == null) return false;
|
|
35923
|
+
return Date.now() - last < userInteractionIntervalMs;
|
|
35924
|
+
};
|
|
35925
|
+
onUserInteractionCheck === null || onUserInteractionCheck === void 0 ? void 0 : onUserInteractionCheck(hadInteraction()).catch(function (error) {
|
|
35926
|
+
console.error('[TabLeaderCoordinator] onUserInteractionCheck failed:', error);
|
|
35927
|
+
});
|
|
35928
|
+
var hbTimer = setInterval(function () {
|
|
35929
|
+
return onHeartbeat === null || onHeartbeat === void 0 ? void 0 : onHeartbeat().catch(function (error) {
|
|
35930
|
+
console.error('[TabLeaderCoordinator] onHeartbeat failed:', error);
|
|
35931
|
+
});
|
|
35932
|
+
}, heartBeatIntervalMs);
|
|
35933
|
+
var interactionTimer = setInterval(function () {
|
|
35934
|
+
onUserInteractionCheck === null || onUserInteractionCheck === void 0 ? void 0 : onUserInteractionCheck(hadInteraction()).catch(function (error) {
|
|
35935
|
+
console.error('[TabLeaderCoordinator] onUserInteractionCheck failed:', error);
|
|
35936
|
+
});
|
|
35937
|
+
}, userInteractionIntervalMs);
|
|
35938
|
+
return function () {
|
|
35939
|
+
clearInterval(hbTimer);
|
|
35940
|
+
clearInterval(interactionTimer);
|
|
35941
|
+
};
|
|
35942
|
+
};
|
|
35943
|
+
if (!isStorageAvailable()) {
|
|
35944
|
+
return runPerTabFallback();
|
|
35945
|
+
}
|
|
35946
|
+
var LOCK_KEY = "".concat(LOCK_KEY_PREFIX).concat(userKey);
|
|
35947
|
+
var CH_NAME = "".concat(CHANNEL_PREFIX).concat(userKey);
|
|
35948
|
+
var TAB_ID = getTabId();
|
|
35949
|
+
var bc = null;
|
|
35950
|
+
try {
|
|
35951
|
+
bc = typeof BroadcastChannel !== 'undefined' ? new BroadcastChannel(CH_NAME) : null;
|
|
35952
|
+
} catch (error) {
|
|
35953
|
+
console.error('[TabLeaderCoordinator] BroadcastChannel creation failed:', error);
|
|
35954
|
+
bc = null;
|
|
35955
|
+
}
|
|
35956
|
+
var isLeader = false;
|
|
35957
|
+
var renewTimer = null;
|
|
35958
|
+
var heartbeatTimer = null;
|
|
35959
|
+
var interactionCheckTimer = null;
|
|
35960
|
+
var electionTimer = null;
|
|
35961
|
+
var now = function now() {
|
|
35962
|
+
return Date.now();
|
|
35963
|
+
};
|
|
35964
|
+
var readLock = function readLock() {
|
|
35965
|
+
try {
|
|
35966
|
+
return JSON.parse(localStorage.getItem(LOCK_KEY) || 'null');
|
|
35967
|
+
} catch (error) {
|
|
35968
|
+
console.error('[TabLeaderCoordinator] readLock failed:', error);
|
|
35969
|
+
return null;
|
|
35970
|
+
}
|
|
35971
|
+
};
|
|
35972
|
+
var writeLock = function writeLock(ownerId) {
|
|
35973
|
+
try {
|
|
35974
|
+
localStorage.setItem(LOCK_KEY, JSON.stringify({
|
|
35975
|
+
ownerId: ownerId,
|
|
35976
|
+
expiresAt: now() + LOCK_TTL_MS
|
|
35977
|
+
}));
|
|
35978
|
+
} catch (error) {
|
|
35979
|
+
console.error('[TabLeaderCoordinator] writeLock failed:', error);
|
|
35980
|
+
}
|
|
35981
|
+
};
|
|
35982
|
+
var clearLockIfMine = function clearLockIfMine() {
|
|
35983
|
+
var lock = readLock();
|
|
35984
|
+
if ((lock === null || lock === void 0 ? void 0 : lock.ownerId) === TAB_ID) {
|
|
35985
|
+
try {
|
|
35986
|
+
localStorage.removeItem(LOCK_KEY);
|
|
35987
|
+
} catch (error) {
|
|
35988
|
+
console.error('[TabLeaderCoordinator] clearLockIfMine failed:', error);
|
|
35989
|
+
}
|
|
35990
|
+
}
|
|
35991
|
+
};
|
|
35992
|
+
var runUserInteractionCheck = function runUserInteractionCheck() {
|
|
35993
|
+
var last = getLastInteractionTime(userKey, false);
|
|
35994
|
+
var checkWindowStart = now() - userInteractionIntervalMs;
|
|
35995
|
+
var hadInteraction = last != null && !Number.isNaN(last) && last >= checkWindowStart;
|
|
35996
|
+
onUserInteractionCheck === null || onUserInteractionCheck === void 0 ? void 0 : onUserInteractionCheck(!!hadInteraction).catch(function (error) {
|
|
35997
|
+
console.error('[TabLeaderCoordinator] onUserInteractionCheck failed:', error);
|
|
35998
|
+
});
|
|
35999
|
+
};
|
|
36000
|
+
var becomeLeader = function becomeLeader() {
|
|
36001
|
+
if (isLeader) return;
|
|
36002
|
+
isLeader = true;
|
|
36003
|
+
if (bc) {
|
|
36004
|
+
try {
|
|
36005
|
+
bc.postMessage({
|
|
36006
|
+
type: 'LEADER',
|
|
36007
|
+
tabId: TAB_ID,
|
|
36008
|
+
at: now()
|
|
36009
|
+
});
|
|
36010
|
+
} catch (error) {
|
|
36011
|
+
console.error('[TabLeaderCoordinator] BroadcastChannel postMessage failed:', error);
|
|
36012
|
+
}
|
|
36013
|
+
}
|
|
36014
|
+
|
|
36015
|
+
// Renew lock periodically
|
|
36016
|
+
renewTimer = setInterval(function () {
|
|
36017
|
+
var lock = readLock();
|
|
36018
|
+
if (!lock || lock.ownerId !== TAB_ID) {
|
|
36019
|
+
becomeFollower();
|
|
36020
|
+
return;
|
|
36021
|
+
}
|
|
36022
|
+
writeLock(TAB_ID);
|
|
36023
|
+
}, RENEW_EVERY_MS);
|
|
36024
|
+
|
|
36025
|
+
// Heartbeat (only leader)
|
|
36026
|
+
heartbeatTimer = setInterval(function () {
|
|
36027
|
+
onHeartbeat === null || onHeartbeat === void 0 ? void 0 : onHeartbeat().catch(function (error) {
|
|
36028
|
+
console.error('[TabLeaderCoordinator] onHeartbeat failed:', error);
|
|
36029
|
+
});
|
|
36030
|
+
}, heartBeatIntervalMs);
|
|
36031
|
+
|
|
36032
|
+
// User interaction check (only leader)
|
|
36033
|
+
interactionCheckTimer = setInterval(runUserInteractionCheck, userInteractionIntervalMs);
|
|
36034
|
+
|
|
36035
|
+
// Immediate calls on becoming leader
|
|
36036
|
+
onHeartbeat === null || onHeartbeat === void 0 ? void 0 : onHeartbeat().catch(function (error) {
|
|
36037
|
+
console.error('[TabLeaderCoordinator] onHeartbeat failed:', error);
|
|
36038
|
+
});
|
|
36039
|
+
runUserInteractionCheck();
|
|
36040
|
+
};
|
|
36041
|
+
var becomeFollower = function becomeFollower() {
|
|
36042
|
+
if (!isLeader) return;
|
|
36043
|
+
isLeader = false;
|
|
36044
|
+
if (renewTimer) clearInterval(renewTimer);
|
|
36045
|
+
if (heartbeatTimer) clearInterval(heartbeatTimer);
|
|
36046
|
+
if (interactionCheckTimer) clearInterval(interactionCheckTimer);
|
|
36047
|
+
renewTimer = heartbeatTimer = interactionCheckTimer = null;
|
|
36048
|
+
};
|
|
36049
|
+
var tryBecomeLeader = function tryBecomeLeader() {
|
|
36050
|
+
var lock = readLock();
|
|
36051
|
+
var expired = !lock || lock.expiresAt <= now();
|
|
36052
|
+
if (expired) {
|
|
36053
|
+
writeLock(TAB_ID);
|
|
36054
|
+
var verify = readLock();
|
|
36055
|
+
if ((verify === null || verify === void 0 ? void 0 : verify.ownerId) === TAB_ID) {
|
|
36056
|
+
becomeLeader();
|
|
36057
|
+
} else {
|
|
36058
|
+
becomeFollower();
|
|
36059
|
+
}
|
|
36060
|
+
} else if (lock.ownerId === TAB_ID) {
|
|
36061
|
+
becomeLeader();
|
|
36062
|
+
} else {
|
|
36063
|
+
becomeFollower();
|
|
36064
|
+
}
|
|
36065
|
+
};
|
|
36066
|
+
var handleStorage = function handleStorage(e) {
|
|
36067
|
+
if (e.key === LOCK_KEY) {
|
|
36068
|
+
var lock = readLock();
|
|
36069
|
+
if ((lock === null || lock === void 0 ? void 0 : lock.ownerId) === TAB_ID) {
|
|
36070
|
+
becomeLeader();
|
|
36071
|
+
} else {
|
|
36072
|
+
becomeFollower();
|
|
36073
|
+
}
|
|
36074
|
+
}
|
|
36075
|
+
};
|
|
36076
|
+
var handleBeforeUnload = function handleBeforeUnload() {
|
|
36077
|
+
if (isLeader) clearLockIfMine();
|
|
36078
|
+
if (bc) bc.close();
|
|
36079
|
+
};
|
|
36080
|
+
if (bc) {
|
|
36081
|
+
bc.onmessage = function (e) {
|
|
36082
|
+
var _e$data;
|
|
36083
|
+
if ((e === null || e === void 0 ? void 0 : (_e$data = e.data) === null || _e$data === void 0 ? void 0 : _e$data.type) === 'LEADER' && e.data.tabId !== TAB_ID) {
|
|
36084
|
+
var lock = readLock();
|
|
36085
|
+
if ((lock === null || lock === void 0 ? void 0 : lock.ownerId) !== TAB_ID) becomeFollower();
|
|
36086
|
+
}
|
|
36087
|
+
};
|
|
36088
|
+
}
|
|
36089
|
+
window.addEventListener('storage', handleStorage);
|
|
36090
|
+
window.addEventListener('beforeunload', handleBeforeUnload);
|
|
36091
|
+
window.addEventListener('pagehide', handleBeforeUnload);
|
|
36092
|
+
electionTimer = setInterval(function () {
|
|
36093
|
+
setTimeout(tryBecomeLeader, Math.random() * JITTER_MS);
|
|
36094
|
+
}, ELECTION_INTERVAL_MS);
|
|
36095
|
+
tryBecomeLeader();
|
|
36096
|
+
return function () {
|
|
36097
|
+
window.removeEventListener('storage', handleStorage);
|
|
36098
|
+
window.removeEventListener('beforeunload', handleBeforeUnload);
|
|
36099
|
+
window.removeEventListener('pagehide', handleBeforeUnload);
|
|
36100
|
+
if (electionTimer) clearInterval(electionTimer);
|
|
36101
|
+
if (isLeader) clearLockIfMine();
|
|
36102
|
+
becomeFollower();
|
|
36103
|
+
if (bc) bc.close();
|
|
36104
|
+
};
|
|
36105
|
+
};
|
|
35709
36106
|
|
|
35710
36107
|
var css_248z$6 = ".utilities_ops-app-frame_ErrorNotification_ErrorNotification--notificationWrapper {\r\n display: flex;\r\n width: -webkit-fit-content;\r\n width: -moz-fit-content;\r\n width: fit-content;\r\n background-color: #f1f1f1;\r\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\r\n border-radius: 4px;\r\n -webkit-animation: utilities_ops-app-frame_ErrorNotification_ErrorNotification--slideUp 0.3s ease-out;\r\n animation: utilities_ops-app-frame_ErrorNotification_ErrorNotification--slideUp 0.3s ease-out;\r\n pointer-events: auto;\r\n}\r\n\r\n@-webkit-keyframes utilities_ops-app-frame_ErrorNotification_ErrorNotification--slideUp {\r\n from {\r\n -webkit-transform: translateY(100%);\r\n transform: translateY(100%);\r\n opacity: 0;\r\n }\r\n to {\r\n -webkit-transform: translateY(0);\r\n transform: translateY(0);\r\n opacity: 1;\r\n }\r\n}\r\n\r\n@keyframes utilities_ops-app-frame_ErrorNotification_ErrorNotification--slideUp {\r\n from {\r\n -webkit-transform: translateY(100%);\r\n transform: translateY(100%);\r\n opacity: 0;\r\n }\r\n to {\r\n -webkit-transform: translateY(0);\r\n transform: translateY(0);\r\n opacity: 1;\r\n }\r\n}\r\n\r\n";
|
|
35711
36108
|
styleInject(css_248z$6);
|
|
@@ -35997,6 +36394,33 @@ if (!enableNewToolkitFeatures) SETTINGS_ITEMS.splice(1, 0, {
|
|
|
35997
36394
|
key: 'settings',
|
|
35998
36395
|
name: 'Settings'
|
|
35999
36396
|
});
|
|
36397
|
+
var isSystemMarkedOffline = function isSystemMarkedOffline(status) {
|
|
36398
|
+
if (!status || typeof status !== 'string') return false;
|
|
36399
|
+
var normalized = String(status).trim().toLowerCase();
|
|
36400
|
+
// Match "Offline(System)", "Offline (System)", "offline - system", unicode variants, etc.
|
|
36401
|
+
var hasOffline = normalized.includes('offline');
|
|
36402
|
+
var hasSystem = normalized.includes('system');
|
|
36403
|
+
return hasOffline && hasSystem;
|
|
36404
|
+
};
|
|
36405
|
+
var getOfflineStatusFromAvailable = function getOfflineStatusFromAvailable(statuses) {
|
|
36406
|
+
if (!Array.isArray(statuses) || statuses.length === 0) return 'Offline';
|
|
36407
|
+
var statusList = statuses.map(function (s) {
|
|
36408
|
+
return s.status;
|
|
36409
|
+
});
|
|
36410
|
+
var offlineIndex = statusList.findIndex(function (s) {
|
|
36411
|
+
var _s$toLowerCase;
|
|
36412
|
+
return s === null || s === void 0 ? void 0 : (_s$toLowerCase = s.toLowerCase) === null || _s$toLowerCase === void 0 ? void 0 : _s$toLowerCase.call(s).includes('offline');
|
|
36413
|
+
});
|
|
36414
|
+
return offlineIndex !== -1 ? statusList[offlineIndex] : 'Offline';
|
|
36415
|
+
};
|
|
36416
|
+
var getAvailableStatusFromStatuses = function getAvailableStatusFromStatuses(statuses) {
|
|
36417
|
+
if (!Array.isArray(statuses) || statuses.length === 0) return 'Available';
|
|
36418
|
+
var found = statuses.find(function (s) {
|
|
36419
|
+
var _s$status, _s$status$toLowerCase;
|
|
36420
|
+
return (s === null || s === void 0 ? void 0 : (_s$status = s.status) === null || _s$status === void 0 ? void 0 : (_s$status$toLowerCase = _s$status.toLowerCase) === null || _s$status$toLowerCase === void 0 ? void 0 : _s$status$toLowerCase.call(_s$status)) === 'available';
|
|
36421
|
+
});
|
|
36422
|
+
return (found === null || found === void 0 ? void 0 : found.status) || 'Available';
|
|
36423
|
+
};
|
|
36000
36424
|
var CountryFlag = function CountryFlag() {
|
|
36001
36425
|
var _storage$activeCountr;
|
|
36002
36426
|
return /*#__PURE__*/React__default["default"].createElement(Flag, {
|
|
@@ -36262,6 +36686,10 @@ var AppBar = function AppBar(_ref) {
|
|
|
36262
36686
|
_useState24 = _slicedToArray(_useState23, 2),
|
|
36263
36687
|
currentUserStatus = _useState24[0],
|
|
36264
36688
|
setCurrentUserStatus = _useState24[1];
|
|
36689
|
+
var _useState25 = React.useState(false),
|
|
36690
|
+
_useState26 = _slicedToArray(_useState25, 2),
|
|
36691
|
+
showSystemOfflineDialog = _useState26[0],
|
|
36692
|
+
setShowSystemOfflineDialog = _useState26[1];
|
|
36265
36693
|
React.useEffect(function () {
|
|
36266
36694
|
listOfAllNotificationsRef.current = listOfAllNotifications;
|
|
36267
36695
|
}, [listOfAllNotifications]);
|
|
@@ -36424,6 +36852,21 @@ var AppBar = function AppBar(_ref) {
|
|
|
36424
36852
|
setCurrentUserStatus(newStatus);
|
|
36425
36853
|
storage$1.setLocalItem('dashboard', newStatus, 'userAvailability');
|
|
36426
36854
|
};
|
|
36855
|
+
React.useEffect(function () {
|
|
36856
|
+
if (isSystemMarkedOffline(currentUserStatus) && !isUserStatusHidden()) {
|
|
36857
|
+
setShowSystemOfflineDialog(true);
|
|
36858
|
+
} else {
|
|
36859
|
+
setShowSystemOfflineDialog(false);
|
|
36860
|
+
}
|
|
36861
|
+
}, [currentUserStatus]);
|
|
36862
|
+
var handleSystemOfflineMakeAvailable = function handleSystemOfflineMakeAvailable() {
|
|
36863
|
+
var availableStatus = getAvailableStatusFromStatuses(availableStatuses);
|
|
36864
|
+
handleUserStatusUpdate(availableStatus);
|
|
36865
|
+
};
|
|
36866
|
+
var handleSystemOfflineStayOffline = function handleSystemOfflineStayOffline() {
|
|
36867
|
+
var offlineStatus = getOfflineStatusFromAvailable(availableStatuses);
|
|
36868
|
+
handleUserStatusUpdate(offlineStatus);
|
|
36869
|
+
};
|
|
36427
36870
|
var _reConnectSocket = function reConnectSocket() {
|
|
36428
36871
|
if (socketRetryCountRef.current < 15) {
|
|
36429
36872
|
socketRetryCountRef.current = socketRetryCountRef.current + 1;
|
|
@@ -36489,7 +36932,7 @@ var AppBar = function AppBar(_ref) {
|
|
|
36489
36932
|
}
|
|
36490
36933
|
var loadUserStatus = /*#__PURE__*/function () {
|
|
36491
36934
|
var _ref5 = _asyncToGenerator$1(/*#__PURE__*/_regenerator().m(function _callee4() {
|
|
36492
|
-
var statuses, userStatus, statusList, statusListLower, isValidStatus, finalStatus, offlineIndex, updatedStatus, _t4, _t5;
|
|
36935
|
+
var _userStatus$toLowerCa, statuses, userStatus, statusList, statusListLower, isSystemAssignedStatus, isValidStatus, finalStatus, offlineIndex, updatedStatus, _t4, _t5;
|
|
36493
36936
|
return _regenerator().w(function (_context4) {
|
|
36494
36937
|
while (1) switch (_context4.p = _context4.n) {
|
|
36495
36938
|
case 0:
|
|
@@ -36516,7 +36959,8 @@ var AppBar = function AppBar(_ref) {
|
|
|
36516
36959
|
statusListLower = statusList.map(function (s) {
|
|
36517
36960
|
return s.toLowerCase();
|
|
36518
36961
|
});
|
|
36519
|
-
|
|
36962
|
+
isSystemAssignedStatus = userStatus && (userStatus === null || userStatus === void 0 ? void 0 : (_userStatus$toLowerCa = userStatus.toLowerCase()) === null || _userStatus$toLowerCa === void 0 ? void 0 : _userStatus$toLowerCa.includes("system"));
|
|
36963
|
+
isValidStatus = userStatus && (statusListLower.includes(userStatus.toLowerCase()) || isSystemAssignedStatus);
|
|
36520
36964
|
finalStatus = userStatus;
|
|
36521
36965
|
if (isValidStatus) {
|
|
36522
36966
|
_context4.n = 8;
|
|
@@ -36611,6 +37055,51 @@ var AppBar = function AppBar(_ref) {
|
|
|
36611
37055
|
clearInterval(expireNotificationsInterval);
|
|
36612
37056
|
};
|
|
36613
37057
|
}, [notifications]);
|
|
37058
|
+
React.useEffect(function () {
|
|
37059
|
+
var heartBeatEnabledStatuses = ((coreAppConfig === null || coreAppConfig === void 0 ? void 0 : coreAppConfig.heartBeatEnabledStatuses) || ['available']).map(function (s) {
|
|
37060
|
+
var _s$toLowerCase2;
|
|
37061
|
+
return (s === null || s === void 0 ? void 0 : (_s$toLowerCase2 = s.toLowerCase) === null || _s$toLowerCase2 === void 0 ? void 0 : _s$toLowerCase2.call(s)) || '';
|
|
37062
|
+
});
|
|
37063
|
+
var isStatusEnabled = currentUserStatus && heartBeatEnabledStatuses.includes(currentUserStatus.toLowerCase());
|
|
37064
|
+
if (isUserStatusHidden() || !isStatusEnabled) return;
|
|
37065
|
+
var MIN_HEARTBEAT_MS = 5000;
|
|
37066
|
+
var MIN_INTERACTION_MS = 10000;
|
|
37067
|
+
var heartBeatIntervalMs = Math.max((parseInt(coreAppConfig === null || coreAppConfig === void 0 ? void 0 : coreAppConfig.heartBeatInterval, 10) || 30) * 1000, MIN_HEARTBEAT_MS);
|
|
37068
|
+
var userInteractionIntervalMs = Math.max((parseInt(coreAppConfig === null || coreAppConfig === void 0 ? void 0 : coreAppConfig.userInteractionInterval, 10) || 60) * 1000, MIN_INTERACTION_MS);
|
|
37069
|
+
var userKey = storage$1.userEmail || '';
|
|
37070
|
+
var updateLastInteractionTime = function updateLastInteractionTime() {
|
|
37071
|
+
recordUserInteraction(userKey);
|
|
37072
|
+
};
|
|
37073
|
+
var handleVisibilityChange = function handleVisibilityChange() {
|
|
37074
|
+
if (document.visibilityState === 'visible') {
|
|
37075
|
+
updateLastInteractionTime();
|
|
37076
|
+
}
|
|
37077
|
+
};
|
|
37078
|
+
var interactionEvents = ['click', 'keydown', 'keypress', 'scroll', 'mousemove', 'mousedown', 'touchstart'];
|
|
37079
|
+
recordUserInteraction(userKey);
|
|
37080
|
+
interactionEvents.forEach(function (event) {
|
|
37081
|
+
document.addEventListener(event, updateLastInteractionTime, {
|
|
37082
|
+
passive: true
|
|
37083
|
+
});
|
|
37084
|
+
});
|
|
37085
|
+
document.addEventListener('visibilitychange', handleVisibilityChange);
|
|
37086
|
+
var stopCoordinator = startTabLeaderCoordinator({
|
|
37087
|
+
onHeartbeat: sendHeartBeat,
|
|
37088
|
+
onUserInteractionCheck: function onUserInteractionCheck(didInteract) {
|
|
37089
|
+
return sendUserInteractionEvent(didInteract);
|
|
37090
|
+
},
|
|
37091
|
+
heartBeatIntervalMs: heartBeatIntervalMs,
|
|
37092
|
+
userInteractionIntervalMs: userInteractionIntervalMs,
|
|
37093
|
+
userKey: userKey
|
|
37094
|
+
});
|
|
37095
|
+
return function () {
|
|
37096
|
+
interactionEvents.forEach(function (event) {
|
|
37097
|
+
document.removeEventListener(event, updateLastInteractionTime);
|
|
37098
|
+
});
|
|
37099
|
+
document.removeEventListener('visibilitychange', handleVisibilityChange);
|
|
37100
|
+
stopCoordinator();
|
|
37101
|
+
};
|
|
37102
|
+
}, [currentUserStatus]);
|
|
36614
37103
|
var STACK = (_window$toolkitEnv2 = window.toolkitEnv) !== null && _window$toolkitEnv2 !== void 0 && _window$toolkitEnv2.STACK ? window.toolkitEnv.STACK : process.env.STACK;
|
|
36615
37104
|
STACK = STACK || 'c';
|
|
36616
37105
|
var modifiedSettings = SETTINGS_ITEMS;
|
|
@@ -36679,6 +37168,13 @@ var AppBar = function AppBar(_ref) {
|
|
|
36679
37168
|
release: latestRelease,
|
|
36680
37169
|
handleClose: handleReleaseClose,
|
|
36681
37170
|
mihelpAppPath: mihelpAppPath
|
|
37171
|
+
}), showSystemOfflineDialog && /*#__PURE__*/React__default["default"].createElement(SystemOfflineDialog, {
|
|
37172
|
+
isOpen: showSystemOfflineDialog,
|
|
37173
|
+
onClose: function onClose() {
|
|
37174
|
+
return setShowSystemOfflineDialog(false);
|
|
37175
|
+
},
|
|
37176
|
+
onMakeAvailable: handleSystemOfflineMakeAvailable,
|
|
37177
|
+
onStayOffline: handleSystemOfflineStayOffline
|
|
36682
37178
|
}));
|
|
36683
37179
|
};
|
|
36684
37180
|
AppBar.defaultProps = {
|