@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.
@@ -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.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
- return (statusObj === null || statusObj === void 0 ? void 0 : statusObj.colour) || '#BC2F32';
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
- isValidStatus = userStatus && statusListLower.includes(userStatus.toLowerCase());
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 = {