spitfirepm 1.10.65 → 1.10.69

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/globals.d.ts CHANGED
@@ -31,6 +31,9 @@ declare global {
31
31
  interface RefreshPageParts {
32
32
  (eventTarget: string, eventArg: string): void;
33
33
  }
34
+ interface SimpleBooleanPromise {
35
+ (): Promise<boolean>;
36
+ }
34
37
  interface SimpleMethod {
35
38
  (): void;
36
39
  }
@@ -38,6 +41,7 @@ declare global {
38
41
  client: {
39
42
  ReConnectDelay: number;
40
43
  ForWindowRX: RegExp;
44
+ SkipAutoReconnect: boolean;
41
45
  afterDocumentSaved: AfterDocumentSaved;
42
46
  dashboardOpenLink: DashboardOpenLink;
43
47
  dashboardRefreshPartByName: DashboardRefreshPartByName;
@@ -59,7 +63,7 @@ declare global {
59
63
  server: {
60
64
  dashboardHeartbeat: HeartbeatMonitor;
61
65
  dashboardOpenLink: DashboardOpenLink;
62
- sessionAlive: SimpleMethod;
66
+ sessionAlive: SimpleBooleanPromise;
63
67
  subscribeToDocument: DMKMethod;
64
68
  };
65
69
  }
@@ -484,8 +484,15 @@ export declare class sfRestClient {
484
484
  * @param dep4
485
485
  */
486
486
  sfAC($AC: string | JQuery<HTMLInputElement>, lookupName: string, depends1: string | string[], dep2?: string, dep3?: string, dep4?: string): void;
487
+ /** Displays a modal dialog and returns a reference to the dialog for further manipulation
488
+ * @argument msg the text for the dialog message. Can include html
489
+ * @argument title optional title
490
+ * @argument uiAlertIcon if specified, and not false, ui-icon class name (see https://api.jqueryui.com/theming/icons/)
491
+ */
492
+ jqAlert(msg: string, title?: string, uiAlertIcon?: string): JQuery<HTMLElement>;
487
493
  ModalDialog(url: string, eventId: string, eventArg: string, eventContext: Window): Promise<boolean | undefined> | undefined;
488
494
  protected $LookupDialog: JQuery<HTMLDivElement> | undefined;
495
+ protected $LookupDialogStack: JQuery<HTMLDivElement>[];
489
496
  protected $LookupFrame: JQuery<HTMLIFrameElement> | undefined;
490
497
  protected ResolveLookupFrame(forDialog?: JQuery<HTMLDivElement> | undefined): JQuery<HTMLIFrameElement> | undefined;
491
498
  SetModalDialogTitle(theDialog: JQuery<HTMLElement>, toText: string, ptSize?: string | number | undefined): JQuery<HTMLElement>;
@@ -501,6 +508,13 @@ export declare class sfRestClient {
501
508
  * this is the lookup DIV
502
509
  */
503
510
  protected sfModelDialogResizedHandler(): void;
511
+ /**
512
+ * (OBSOLETE) Resize parent sfDash window
513
+ * @deprecated We cannot change the size of the parent window (dates back to sfDash)
514
+ * @param canShrink
515
+ * @param DesiredWidth
516
+ * @param DesiredHeight
517
+ */
504
518
  protected sfSetParentWindowSize(canShrink: boolean, DesiredWidth: number, DesiredHeight: number): void;
505
519
  private sfLookupHeightChangeTo;
506
520
  private _LookupViewPortAdjustments;
@@ -551,7 +565,7 @@ export declare class sfRestClient {
551
565
  protected static LogoutPageURL(mValue: string): string;
552
566
  protected static LoginPageURL(mValue: string): string;
553
567
  protected static _NextPingTimerID: number | undefined;
554
- pingServer(): void;
568
+ pingServer(): Promise<void>;
555
569
  static PageServerPingAttempts: number;
556
570
  static PageServerPingOK: number;
557
571
  static PageServerPingFailRunCount: number;
@@ -9,7 +9,7 @@ const BrowserExtensionChecker_1 = require("./BrowserExtensionChecker");
9
9
  //import localForage from "localforage"; requires --allowSyntheticDefaultImports in tsconfig
10
10
  const localForage = require("localforage");
11
11
  //import {dialog} from "jquery-ui";
12
- const ClientPackageVersion = "1.10.65";
12
+ const ClientPackageVersion = "1.10.69";
13
13
  //export type GUID = string //& { isGuid: true };
14
14
  /* eslint-disable prefer-template */
15
15
  /* eslint-disable no-extend-native */
@@ -335,6 +335,7 @@ class sfRestClient {
335
335
  });
336
336
  return table;
337
337
  };
338
+ this.$LookupDialogStack = [];
338
339
  this._LookupViewPortAdjustments = { outsidExtraW: 65, outsidExtraH: 64, vpExtraW: 16, vpExtraH: 32, frameExtraH: 8 };
339
340
  //var $LookupFrame = $($LookupDialog.children("iframe").get(0))
340
341
  this.DialogViewPortAdjustments = { outsidExtraW: 65, outsidExtraH: 64, vpExtraW: 16, vpExtraH: 32, frameExtraH: 8 };
@@ -1980,11 +1981,13 @@ class sfRestClient {
1980
1981
  console.warn("InvokeAction ignoring empty action");
1981
1982
  return;
1982
1983
  }
1984
+ if (!sfRestClient.ExternalToolsLoadedPromise)
1985
+ sfRestClient.ExternalToolsLoadedPromise = new Promise(r => { r(false); });
1983
1986
  if (ActionString.startsWith(this._SiteURL)) {
1984
1987
  //if (ActionString.indexOf("?") === -1 && ActionString.indexOf(".aspx&set") > 0 ) ActionString = ActionString.replaceAll("&set","?set");// kludge to fix ?set being &set
1985
1988
  if (ActionString.indexOf("?") < 0 && ActionString.indexOf("#") < 0)
1986
1989
  ActionString += "?fq=1"; //fake query parameter
1987
- if (ActionString.indexOf("?") > 0 && ActionString.indexOf("xbia") < 0)
1990
+ if (ActionString.indexOf("?") > 0 && ActionString.indexOf("xbia") < 0 && this.IsPowerUXPage())
1988
1991
  ActionString += "&xbia=1";
1989
1992
  if (ActionString.indexOf("libview.aspx") > 1) {
1990
1993
  var ActionOptions = "";
@@ -2452,6 +2455,51 @@ class sfRestClient {
2452
2455
  console.log(`sfAC Key ${e.which}; autofocus off`);
2453
2456
  }).data("acOpen", false).data("acChange", false);
2454
2457
  }
2458
+ /** Displays a modal dialog and returns a reference to the dialog for further manipulation
2459
+ * @argument msg the text for the dialog message. Can include html
2460
+ * @argument title optional title
2461
+ * @argument uiAlertIcon if specified, and not false, ui-icon class name (see https://api.jqueryui.com/theming/icons/)
2462
+ */
2463
+ jqAlert(msg, title, uiAlertIcon) {
2464
+ console.log("jqAlert: " + msg);
2465
+ var $ALERT;
2466
+ if (!title)
2467
+ title = "Message from Web Application";
2468
+ if ((typeof uiAlertIcon === "undefined") || (typeof uiAlertIcon === "boolean" && uiAlertIcon)) {
2469
+ uiAlertIcon = '<span class="ui-icon ui-icon-alert" style="float: left; margin: 0 7px 20px 0;"></span>';
2470
+ }
2471
+ else if ((typeof uiAlertIcon === "boolean" && !uiAlertIcon))
2472
+ uiAlertIcon = "";
2473
+ else if ((typeof uiAlertIcon === "string") && (uiAlertIcon.length > 1))
2474
+ uiAlertIcon = `<span class="ui-icon ${uiAlertIcon}" style="float: left; margin: 0 7px 20px 0;"></span>`;
2475
+ var fullMsg = `<div id="sfUI-Dialog-Alert" title="${title}" style="font-size: 0.8em">${uiAlertIcon}<span id="AlertMsgText">${msg}</span></div>`;
2476
+ var dialogOptions = {
2477
+ modal: true,
2478
+ minWidth: 250,
2479
+ width: "300",
2480
+ height: 'auto',
2481
+ show: {
2482
+ effect: "blind",
2483
+ duration: 444
2484
+ },
2485
+ hide: {
2486
+ effect: "puff",
2487
+ duration: 333
2488
+ },
2489
+ buttons: {
2490
+ Ok: function () {
2491
+ $(this).dialog("close");
2492
+ }
2493
+ },
2494
+ open: function () {
2495
+ $(this).parent('DIV').find('.ui-dialog-buttonpane button:eq(0)').trigger("focus");
2496
+ }
2497
+ };
2498
+ if (msg.length > 20)
2499
+ dialogOptions.width = "auto";
2500
+ $ALERT = $(fullMsg).dialog(dialogOptions);
2501
+ return ($ALERT);
2502
+ }
2455
2503
  ModalDialog(url, eventId, eventArg, eventContext) {
2456
2504
  var newValue;
2457
2505
  var formName = "0";
@@ -2477,19 +2525,14 @@ class sfRestClient {
2477
2525
  if (!DefaultWidth || DefaultWidth < 500)
2478
2526
  DefaultWidth = 500;
2479
2527
  if (this.$LookupDialog) {
2480
- try {
2481
- this.$LookupDialog.dialog('destroy');
2482
- }
2483
- catch (e) {
2484
- // console.warn(`LookupDialog destroy:`,e)
2485
- }
2486
- this.$LookupDialog?.remove();
2528
+ this.$LookupDialogStack.push(this.$LookupDialog);
2487
2529
  this.$LookupDialog = undefined;
2488
2530
  }
2489
2531
  if (!this.$LookupDialog) {
2490
2532
  this.$LookupDialog = $(`<div class='clsJQLookup' autofocus='autofocus' ><iframe id='sfClassicUIHolder' src='${sfRestClient._Options.BlankPageURI}' style='width: 100%; height: 150px;border:0;' seamless='seamless' autofocus='autofocus' /></div>`)
2491
2533
  .dialog({ autoOpen: false, modal: true, title: 'Lookup Dialog', width: DefaultWidth, height: 200, close: top.sfClient.sfModalDialogClosed, dialogClass: "lookup",
2492
- resizeStop: top?.sfClient.sfModelDialogResizedHandler });
2534
+ resizeStop: top?.sfClient.sfModelDialogResizedHandler,
2535
+ dragStop: top?.sfClient.sfModelDialogResizedHandler });
2493
2536
  top?.sfClient.AddDialogTitleButton(top.sfClient.$LookupDialog, "btnMaximizeDialog", "Maximize", "ui-icon-arrow-4-diag").on("click", function () {
2494
2537
  var $BTN = $(this);
2495
2538
  var $DialogDiv = $(top.sfClient.$LookupDialog).closest("DIV.ui-dialog");
@@ -2525,7 +2568,7 @@ class sfRestClient {
2525
2568
  var OpenUrl = url;
2526
2569
  if (!RESTClient.IsSiteURL(OpenUrl))
2527
2570
  OpenUrl = `${RESTClient._SiteRootURL}/${url}`;
2528
- if (OpenUrl.indexOf("xbia=1")) {
2571
+ if (OpenUrl.indexOf("xbia=1") && top?.sfClient.IsPowerUXPage()) {
2529
2572
  //ui-icon-script
2530
2573
  top?.sfClient.AddDialogTitleButton(top.sfClient.$LookupDialog, "btnToClassicUI", "Classic UI", "ui-icon-script").on("click", function () {
2531
2574
  top.location.href = OpenUrl.replace("xbia=1", "xbia=0");
@@ -2572,6 +2615,8 @@ class sfRestClient {
2572
2615
  var ThisURLHash = OpenUrl.sfHashCode();
2573
2616
  if (sfRestClient._DialogCoordinateCache.has(ThisURLHash)) {
2574
2617
  var TargetSizeData = sfRestClient._DialogCoordinateCache.get(ThisURLHash);
2618
+ if (sfRestClient._Options.LogLevel >= LoggingLevels.Verbose)
2619
+ console.log('ModalDialog() Target size/loc', TargetSizeData);
2575
2620
  var $DialogDiv = $(top.sfClient.$LookupDialog).closest("DIV.ui-dialog");
2576
2621
  top?.sfClient.sfLookupHeightChangeTo(top.sfClient.$LookupDialog, TargetSizeData.height);
2577
2622
  top?.sfClient.sfLookupWidthChangeTo(top.sfClient.$LookupDialog, TargetSizeData.width);
@@ -2763,6 +2808,12 @@ class sfRestClient {
2763
2808
  $LookupDialog.dialog('destroy');
2764
2809
  this.$LookupDialog?.remove();
2765
2810
  this.$LookupDialog = undefined;
2811
+ if (!Array.isArray(this.$LookupDialogStack)) {
2812
+ console.warn("sfModalDialogClosed: re-init $LookupDialogStack");
2813
+ this.$LookupDialogStack = [];
2814
+ }
2815
+ if (this.$LookupDialogStack.length > 0)
2816
+ this.$LookupDialog = this.$LookupDialogStack.pop();
2766
2817
  if (dialogMode == 'modalDialog') {
2767
2818
  if (newValue == null)
2768
2819
  newValue = postbackEventArg;
@@ -2824,6 +2875,13 @@ class sfRestClient {
2824
2875
  }
2825
2876
  top?.sfClient.sfModelDialogResized($LookupDialog);
2826
2877
  }
2878
+ /**
2879
+ * (OBSOLETE) Resize parent sfDash window
2880
+ * @deprecated We cannot change the size of the parent window (dates back to sfDash)
2881
+ * @param canShrink
2882
+ * @param DesiredWidth
2883
+ * @param DesiredHeight
2884
+ */
2827
2885
  sfSetParentWindowSize(canShrink, DesiredWidth, DesiredHeight) {
2828
2886
  console.warn("sfSetParentWindowSize not implemented");
2829
2887
  // if (top == window) {
@@ -2835,37 +2893,45 @@ class sfRestClient {
2835
2893
  }
2836
2894
  sfLookupHeightChangeTo(ld, newValue) {
2837
2895
  // here newValue represents the intended size for the inner iFrame's rendering area
2896
+ if (typeof newValue === "undefined")
2897
+ newValue = 890;
2898
+ if (typeof newValue === "string")
2899
+ newValue = Number.parseInt(newValue);
2900
+ if (newValue === NaN)
2901
+ newValue = 789;
2838
2902
  if ($("HTML").css("font-size") > "16px") {
2839
2903
  newValue = newValue * 1.1;
2840
2904
  } //"Enlarged" theme is 18px
2841
- if (($(window).height() < (newValue + this._LookupViewPortAdjustments.outsidExtraH)))
2842
- this.sfSetParentWindowSize(false, -1, newValue + this._LookupViewPortAdjustments.outsidExtraH);
2905
+ // if (($(window).height()! < (newValue + this._LookupViewPortAdjustments.outsidExtraH))) this.sfSetParentWindowSize(false, -1, newValue + this._LookupViewPortAdjustments.outsidExtraH);
2843
2906
  if (($(window).height() < (newValue + this._LookupViewPortAdjustments.outsidExtraH))) {
2844
2907
  // requested size still too large
2845
2908
  var requestedH = newValue;
2846
2909
  newValue = $(window).height() - this._LookupViewPortAdjustments.outsidExtraH;
2847
- console.log('dialog height requested cannot be accomidated by window, reduce from ' + requestedH + ' to ' + newValue);
2910
+ if (sfRestClient._Options.LogLevel >= LoggingLevels.Verbose)
2911
+ console.log('dialog height requested cannot be accomidated by window, reduce from ' + requestedH + ' to ' + newValue);
2848
2912
  }
2849
2913
  var tdh = newValue + this._LookupViewPortAdjustments.vpExtraH + this._LookupViewPortAdjustments.frameExtraH;
2850
2914
  ld.dialog('option', "height", tdh);
2851
2915
  //var LookupFrame = $(ld.children("iframe").get(0))
2852
2916
  top?.sfClient.sfModelDialogResized(ld);
2853
2917
  ld.dialog('option', 'position', 'center');
2854
- console.log('dialog height explicitly set to ' + newValue);
2918
+ if (sfRestClient._Options.LogLevel >= LoggingLevels.Debug)
2919
+ console.log('dialog height explicitly set to ' + newValue);
2855
2920
  }
2856
2921
  sfLookupWidthChangeTo(ld, newValue) {
2857
- if (($(window).width() < (newValue + this._LookupViewPortAdjustments.outsidExtraW)))
2858
- this.sfSetParentWindowSize(false, newValue + this._LookupViewPortAdjustments.outsidExtraW + this._LookupViewPortAdjustments.vpExtraW, -1);
2922
+ // if (($(window).width()! < (newValue + this._LookupViewPortAdjustments.outsidExtraW))) this.sfSetParentWindowSize(false, newValue + this._LookupViewPortAdjustments.outsidExtraW + this._LookupViewPortAdjustments.vpExtraW, -1);
2859
2923
  if (($(window).width() < (newValue + this._LookupViewPortAdjustments.outsidExtraW))) {
2860
2924
  // requested size still too wide
2861
2925
  var requestedW = newValue;
2862
2926
  newValue = $(window).width() - this._LookupViewPortAdjustments.outsidExtraW;
2863
- console.log('dialog width requested cannot be accomidated by window, reduce from ' + requestedW + ' to ' + newValue);
2927
+ if (sfRestClient._Options.LogLevel >= LoggingLevels.Verbose)
2928
+ console.log('dialog width requested cannot be accomidated by window, reduce from ' + requestedW + ' to ' + newValue);
2864
2929
  }
2865
2930
  ld.dialog('option', "width", newValue + this._LookupViewPortAdjustments.vpExtraW);
2866
2931
  top?.sfClient.sfModelDialogResized(ld);
2867
2932
  setTimeout(function () { ld.dialog('option', 'position', 'center'); }, 259); // need this to happen after above has all completed
2868
- console.log('dialog width explicitly set to ' + newValue);
2933
+ if (sfRestClient._Options.LogLevel >= LoggingLevels.Debug)
2934
+ console.log('dialog width explicitly set to ' + newValue);
2869
2935
  }
2870
2936
  /**
2871
2937
  * Updates internal sizes after the dialog frame size is changed
@@ -2873,7 +2939,7 @@ class sfRestClient {
2873
2939
  * @returns
2874
2940
  */
2875
2941
  sfModelDialogResized(forDialog) {
2876
- // this is called after a user resizes the dialog
2942
+ // this is called after a user resizes or moves the dialog
2877
2943
  var dg = forDialog;
2878
2944
  if (!$(window))
2879
2945
  return;
@@ -2882,15 +2948,14 @@ class sfRestClient {
2882
2948
  var height = dg.height(); // actual content area
2883
2949
  var width = Math.round(dg.width() + 1); // actual content area
2884
2950
  var fh = dg.height() - this.DialogViewPortAdjustments.frameExtraH;
2885
- console.log('sfDialogResized resized to {0}w, {1}h inside {2}x{3}, frame h={4}'.sfFormat(width, height, tdw, tdh, fh));
2886
- if ((($(window).width() < (width + this.DialogViewPortAdjustments.outsidExtraW)) || ($(window).height() < (height + this.DialogViewPortAdjustments.outsidExtraH))))
2887
- this.sfSetParentWindowSize(false, width + this.DialogViewPortAdjustments.outsidExtraW, height + this.DialogViewPortAdjustments.outsidExtraH);
2951
+ // console.log('sfDialogResized resized to {0}w, {1}h inside {2}x{3}, frame h={4}'.sfFormat( width ,height , tdw , tdh, fh));
2952
+ // if ((($(window).width()! < (width + this.DialogViewPortAdjustments.outsidExtraW)) || ($(window).height()! < (height + this.DialogViewPortAdjustments.outsidExtraH)))) this.sfSetParentWindowSize(false, width + this.DialogViewPortAdjustments.outsidExtraW, height + this.DialogViewPortAdjustments.outsidExtraH);
2888
2953
  var $DFrame = $(dg.children("iframe").get(0)); // what if there is no frame???
2889
2954
  // $($DFrame).contents().find("html").outerHeight() -- but not a good place to force the height
2890
2955
  $DFrame.css('height', fh); // also iframe
2891
2956
  $DFrame.css('width', '100%'); // also iframe
2892
2957
  var NewSizeData;
2893
- var PositionNow = dg.position();
2958
+ var PositionNow = dg.closest("DIV.ui-dialog").position();
2894
2959
  NewSizeData = { top: PositionNow.top,
2895
2960
  left: PositionNow.left, width: dg.width(),
2896
2961
  height: dg.height()
@@ -2898,6 +2963,8 @@ class sfRestClient {
2898
2963
  var DialogURL = $DFrame.attr("src");
2899
2964
  var DialogURLHash = DialogURL.sfHashCode();
2900
2965
  sfRestClient._DialogCoordinateCache.set(DialogURLHash, NewSizeData);
2966
+ if (sfRestClient._Options.LogLevel >= LoggingLevels.Verbose)
2967
+ console.log(`sfDialogResized(${width}w,${height}h) size cache `, NewSizeData);
2901
2968
  }
2902
2969
  /**
2903
2970
  * Applies UI CFG to all rows in a dataset
@@ -3016,6 +3083,10 @@ class sfRestClient {
3016
3083
  var InGlobalInstance = this.IsGlobalInstance();
3017
3084
  console.log(`sfRestClient.ClearCache(${this.ThisInstanceID}), ${alsoClearSessionStorage ? " w/sessionStorage" : ""}, ${InGlobalInstance ? " Global" : ""}, UPRC:${sfRestClient._UserPermitResultCache.size}`);
3018
3085
  PartStorageData._LoadedParts.clear();
3086
+ try {
3087
+ $.connection.hub.stop();
3088
+ }
3089
+ catch { }
3019
3090
  sfRestClient._UserPermitResultCache.clear();
3020
3091
  sfRestClient._LoadedPermits.clear();
3021
3092
  sfRestClient._LoadingPermitRequests.clear();
@@ -3201,18 +3272,19 @@ class sfRestClient {
3201
3272
  $("SPAN.clsBrandingFooterText").append("<span id='spnDashOWarning' class='sfPingHealthTip' title='{1}'>Weak server connection. (Reported by Push Signal)</span>");
3202
3273
  });
3203
3274
  $.connection.hub.disconnected(function () {
3204
- console.log(`${new Date().toSFLogTimeString()} sfPMSHub: disconnected. Sleep ${sfHub.client.ReConnectDelay}ms`);
3275
+ console.log(`${new Date().toSFLogTimeString()} sfPMSHub: disconnected. Sleep ${sfHub.client.ReConnectDelay}ms; Reconnect:${!sfHub.client.SkipAutoReconnect}`);
3205
3276
  if ($.connection.hub.lastError) {
3206
3277
  console.log($.connection.hub.lastError.message);
3207
3278
  }
3208
- setTimeout(function () {
3209
- $.connection.hub.start().done(function hubReStart() {
3210
- console.log(`${new Date().toLocaleTimeString()} sfPMSHub Hub has been re-started...`);
3211
- if (top?.sfClient.IsDocumentPage()) {
3212
- sfHub.server.subscribeToDocument(top.sfClient.GetPageContextValue("DataPK"));
3213
- }
3214
- });
3215
- }, sfHub.client.ReConnectDelay); // Restart connection after 5 seconds.
3279
+ if (!sfHub.client.SkipAutoReconnect)
3280
+ setTimeout(function () {
3281
+ $.connection.hub.start().done(function hubReStart() {
3282
+ console.log(`${new Date().toLocaleTimeString()} sfPMSHub Hub has been re-started...`);
3283
+ if (top?.sfClient.IsDocumentPage()) {
3284
+ sfHub.server.subscribeToDocument(top.sfClient.GetPageContextValue("DataPK"));
3285
+ }
3286
+ });
3287
+ }, sfHub.client.ReConnectDelay); // Restart connection after 5 seconds.
3216
3288
  if (sfHub.client.ReConnectDelay < 120000)
3217
3289
  sfHub.client.ReConnectDelay *= 2;
3218
3290
  });
@@ -3231,7 +3303,7 @@ class sfRestClient {
3231
3303
  var RESTClient = top.sfClient;
3232
3304
  var isPowerUX = RESTClient.IsPowerUXPage();
3233
3305
  isPowerUX = false;
3234
- result = `${RESTClient._SiteRootURL}/${isPowerUX ? "spax.html#!/login" : "admin/Logout.aspx"}?m={mValue}`;
3306
+ result = `${RESTClient._SiteRootURL}/${isPowerUX ? "spax.html#!/login" : "admin/Logout.aspx"}?m=${mValue}`;
3235
3307
  }
3236
3308
  return result;
3237
3309
  }
@@ -3247,7 +3319,7 @@ class sfRestClient {
3247
3319
  }
3248
3320
  return result;
3249
3321
  }
3250
- pingServer() {
3322
+ async pingServer() {
3251
3323
  var id = "TBD";
3252
3324
  try {
3253
3325
  var RESTClient = this;
@@ -3269,10 +3341,9 @@ class sfRestClient {
3269
3341
  if ($("DIV.ui-dialog-content.sfStopPingServer").length > 0)
3270
3342
  return;
3271
3343
  sfRestClient.PageServerPingAttempts++;
3272
- if (top.sfPMSHub && top.sfPMSHub.connection.state === $.signalR.connectionState.connected)
3273
- top.sfPMSHub.server.sessionAlive();
3344
+ top.sfPMSHub.server.sessionAlive();
3274
3345
  top.sfPMSHub.server.dashboardHeartbeat(id, sfRestClient.PageNotificationCount)
3275
- .then(function (responseText) {
3346
+ .then(async function (responseText) {
3276
3347
  if (responseText > "") {
3277
3348
  var isOK = (responseText.startsWith("OK"));
3278
3349
  //$(jqSelector).html(responseText);
@@ -3291,8 +3362,35 @@ class sfRestClient {
3291
3362
  }
3292
3363
  }
3293
3364
  else if (responseText === "NAK: Not Authenticated") {
3294
- RESTClient.DisplaySysNotification("Lost authentication. ", 60000);
3295
- setTimeout(`location="${sfRestClient.LogoutPageURL('idle')}";`, 9753);
3365
+ // first try and repair
3366
+ await top.sfPMSHub.server.sessionAlive().then(async (isAlive) => {
3367
+ if (!isAlive) {
3368
+ console.log("pingServer() signalR begin stop/start....");
3369
+ try {
3370
+ top.sfPMSHub.client.SkipAutoReconnect = true;
3371
+ await $.connection.hub.stop();
3372
+ await $.connection.hub.start();
3373
+ }
3374
+ catch {
3375
+ console.warn("pingServer() signalR stop/start exception....");
3376
+ }
3377
+ finally {
3378
+ top.sfPMSHub.client.SkipAutoReconnect = false;
3379
+ }
3380
+ console.log("pingServer() signalR after stop/start....", top.sfPMSHub.connection.state);
3381
+ }
3382
+ });
3383
+ await top.sfPMSHub.server.sessionAlive().then(async (isAlive) => {
3384
+ if (!isAlive) {
3385
+ console.log("pingServer() NAK persists....");
3386
+ RESTClient.DisplaySysNotification("Lost authentication. ", 65432);
3387
+ setTimeout(`location="${sfRestClient.LogoutPageURL('auth-lost')}";`, 9753);
3388
+ }
3389
+ else {
3390
+ responseText = "NAK:Rejuvinated";
3391
+ retryInterval = 8642;
3392
+ }
3393
+ });
3296
3394
  }
3297
3395
  else {
3298
3396
  var msgText = false;
@@ -3372,7 +3470,8 @@ class sfRestClient {
3372
3470
  if ((top?.sfClient.DevMode()) || sfRestClient.PageServerPingOK < 2 || ((top?.sfPMSHub) && top.sfPMSHub.connection.logging) || ((responseText) && (responseText != "OK")))
3373
3471
  console.log(`pingServer(${marker},${id},${Math.round((sfRestClient.PageServerPingOK / sfRestClient.PageServerPingAttempts) * 100).toFixed(2)}%) - ${responseText}; Next: ${nextMS}ms at ${new Date(new Date().valueOf() + nextMS).toLocaleTimeString()}`);
3374
3472
  sfRestClient.PageServerPingFailRunCount = 0;
3375
- top.sfPMSHub.client.ReConnectDelay = 5000;
3473
+ top.sfPMSHub.client.ReConnectDelay = 2500;
3474
+ top.sfPMSHub.client.SkipAutoReconnect = false;
3376
3475
  }
3377
3476
  PageServerPingBackFailed(marker, id, jqXHR, nextMS, methodName) {
3378
3477
  var responseText;