spitfirepm 1.20.91 → 1.20.95

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.
@@ -1,21 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.sfRestClient = exports.DataModelCollection = exports.DataModelRow = exports.WCCData = exports.NVPair = exports.LoggingLevels = void 0;
3
+ exports.sfRestClient = exports.DataModelCollection = exports.InvokeOptions = exports.DataModelRow = exports.WCCData = exports.NVPair = exports.LoggingLevels = void 0;
4
4
  //import { sfApplicationRootPath } from "./string.extensions";
5
5
  const SwaggerClients_1 = require("./SwaggerClients");
6
6
  const _SwaggerClientExports = require("./SwaggerClients");
7
7
  const $ = require("jquery");
8
8
  const BrowserExtensionChecker_1 = require("./BrowserExtensionChecker");
9
9
  //import {dialog} from "jquery-ui";
10
- const ClientPackageVersion = "1.20.91";
11
- //export type GUID = string //& { isGuid: true };
12
- /* eslint-disable prefer-template */
13
- /* eslint-disable no-extend-native */
14
- /* eslint-disable prefer-spread */
15
- /* eslint-disable no-undef */
16
- /* eslint-disable prefer-arrow-callback */
17
- /* eslint-disable vars-on-top */
18
- /* eslint-disable no-var */
10
+ const ClientPackageVersion = "1.20.95";
19
11
  // original script created by Stan York and modified for typescript and linter requirements by Uladzislau Kumakou
20
12
  var LoggingLevels;
21
13
  (function (LoggingLevels) {
@@ -55,7 +47,7 @@ class PartStorageData {
55
47
  PartStorageData._LoadedParts.set(this._ReferenceKey, this);
56
48
  this._InitializationResultPromise = null;
57
49
  if (!PartStorageData._SiteURL) {
58
- var ApplicationPath = window.location.pathname.substr(1, window.location.pathname.substr(1).indexOf("/"));
50
+ var ApplicationPath = window.__HTTPApplicationName();
59
51
  PartStorageData._SiteURL = `${window.location.origin}/${ApplicationPath || 'sfPMS'}`;
60
52
  }
61
53
  }
@@ -215,6 +207,10 @@ class DataModelRow {
215
207
  }
216
208
  exports.DataModelRow = DataModelRow;
217
209
  ;
210
+ class InvokeOptions {
211
+ }
212
+ exports.InvokeOptions = InvokeOptions;
213
+ ;
218
214
  class DataModelCollection {
219
215
  }
220
216
  exports.DataModelCollection = DataModelCollection;
@@ -343,7 +339,7 @@ class sfRestClient {
343
339
  this.EmptyKey = "00000000-0000-0000-0000-000000000000";
344
340
  this._CachedDVRequests = new Map();
345
341
  this.ThisInstanceID = sfRestClient.InstanceSerialNumberSource++;
346
- var ApplicationPath = window.location.pathname.substr(1, window.location.pathname.substr(1).indexOf("/"));
342
+ var ApplicationPath = window.__HTTPApplicationName();
347
343
  this._SiteURL = `${window.location.origin}/${ApplicationPath || 'sfPMS'}`;
348
344
  this._SiteRootURL = `/${ApplicationPath || 'sfPMS'}`;
349
345
  this.exports = _SwaggerClientExports;
@@ -372,6 +368,10 @@ class sfRestClient {
372
368
  console.log(`sfClient#${this.ThisInstanceID} ${this.ClientVersion}; Window[${window.name}]; ${ThisIsGlobal ? "Global" : ""}`);
373
369
  if (ThisIsGlobal) {
374
370
  var RESTClient = this;
371
+ if (!$.hasData)
372
+ $.fn.extend({ hasData: function (name) {
373
+ return this.data(name) !== undefined;
374
+ } });
375
375
  sfRestClient.ExternalToolsLoadedPromise = RESTClient.AssureJQUITools($("div").first());
376
376
  if ($("title").text().length === 0)
377
377
  $("title").text("Spitfire PM");
@@ -1175,6 +1175,53 @@ class sfRestClient {
1175
1175
  // });
1176
1176
  return forElement;
1177
1177
  }
1178
+ AdjustFluidDialog(dialog, $this) {
1179
+ if (!$this)
1180
+ $this = dialog.closest("ui-dialog");
1181
+ var $DialogContent = $this.find(".ui-dialog-content");
1182
+ // if fluid option == true
1183
+ if (dialog.options.fluid) {
1184
+ dialog.option("width", "auto"); // temp...to calc required size
1185
+ var wWidth = $(window).width();
1186
+ var dWidth = $DialogContent.width();
1187
+ // check window width against dialog width
1188
+ if (wWidth < (dWidth + 50)) {
1189
+ // keep dialog from filling entire screen
1190
+ $this.css("max-width", "90%");
1191
+ }
1192
+ else {
1193
+ // fix maxWidth bug
1194
+ dialog.option("width", dWidth);
1195
+ }
1196
+ //reposition dialog
1197
+ dialog.option("position", dialog.options.position);
1198
+ }
1199
+ }
1200
+ UpdateFluidDialogs() {
1201
+ var RESTClient = this;
1202
+ var $visible = $(".ui-dialog:visible");
1203
+ if ($visible.length === 0)
1204
+ $visible = self.top.$(".ui-dialog:visible");
1205
+ // each open dialog
1206
+ $visible.each(function () {
1207
+ var $this = $(this);
1208
+ var dialog = $this.find(".ui-dialog-content").data("ui-dialog");
1209
+ RESTClient.AdjustFluidDialog(dialog, $this);
1210
+ });
1211
+ }
1212
+ AutoSizeDialog($D) {
1213
+ var RESTClient = this;
1214
+ var dialogOptions = {
1215
+ width: 400,
1216
+ minWidth: 250,
1217
+ height: "auto",
1218
+ fluid: true
1219
+ };
1220
+ $D.dialog(dialogOptions);
1221
+ //$D.dialog("options","width", $D.width());
1222
+ RESTClient.UpdateFluidDialogs();
1223
+ return $D;
1224
+ }
1178
1225
  /** checks with server up to 5 times a second. promise resolves when task has ended or callback returns true;
1179
1226
  * @param taskKey guid key for task
1180
1227
  * @param sessionClient optional existing SessionClient
@@ -1209,6 +1256,97 @@ class sfRestClient {
1209
1256
  result(taskResult);
1210
1257
  });
1211
1258
  }
1259
+ ExportCompetitiveBidData() {
1260
+ var PostBackArgs = "";
1261
+ var TemplateTypeCode = "BA";
1262
+ var RESTClient = this;
1263
+ console.log(`sfExportCobra(${TemplateTypeCode}) ${PostBackArgs}`);
1264
+ $("DIV#divDialogExportGrid").remove();
1265
+ var $Box = $("<div id='divDialogExportGrid' />");
1266
+ var $Dialog;
1267
+ $Dialog = $Box.load(`${RESTClient._SiteURL}/ajhx/ExportGridDialog.html`, function PopFromParentDialogLoaded() {
1268
+ // after loaded
1269
+ var $TemplateDocument = $Box.find("#txtTemplate");
1270
+ var $ButtonPane = $Box.parent().find(".ui-dialog-buttonpane");
1271
+ var $CancelBTN = $ButtonPane.find("#btnDismiss");
1272
+ RESTClient.sfAC($TemplateDocument, "TemplateList", TemplateTypeCode);
1273
+ $TemplateDocument.autocomplete("option", "minLength", 0).autocomplete("option", "delay", 200);
1274
+ $TemplateDocument.data("acPostbackKey", false); // prevent Auto complete from stuffing the key into our input field
1275
+ $TemplateDocument.on("sfAutoCompletedKV sfLookup.Stored", function (e, kv) {
1276
+ console.log(`ExportGrid Template-on:${e.type} = ${kv}`);
1277
+ $TemplateDocument.data("TemplateKey", kv);
1278
+ PostBackArgs = kv;
1279
+ }).on("sfAC.response", function (e, choices) {
1280
+ if (choices.content.length === 1) {
1281
+ var newChoice = choices.content[0];
1282
+ $TemplateDocument.val(newChoice.value).data("acKey", newChoice.key).data("acChange", true);
1283
+ }
1284
+ }).on("focus", () => {
1285
+ $TemplateDocument.autocomplete("search", $TemplateDocument.val());
1286
+ $TemplateDocument.trigger("select");
1287
+ });
1288
+ $TemplateDocument.trigger("focus");
1289
+ RESTClient.AutoSizeDialog($Dialog);
1290
+ return false;
1291
+ }).dialog({
1292
+ title: "Export Competitive Bid Data...",
1293
+ close: function () { $Dialog.dialog('destroy'); }
1294
+ });
1295
+ var DialogButtons = [{
1296
+ text: "Export",
1297
+ "id": "btnExport",
1298
+ click: function () {
1299
+ RESTClient.GADialogEvent("Completed", "ExportCobra");
1300
+ $Dialog.dialog("close");
1301
+ RESTClient.HeyPleaseWait();
1302
+ var api = new _SwaggerClientExports.ExcelToolsClient();
1303
+ api.getCobraExport(PostBackArgs, RESTClient.GetPageContextValue("dsCacheKey")).then(crt => {
1304
+ RESTClient.WaitForTask(crt).then((crtResult) => {
1305
+ RESTClient.ClearPleaseWaitDialog();
1306
+ if (crtResult.ThisReason.indexOf("Failed!") >= 0) {
1307
+ RESTClient.DisplayUserNotification(crtResult.ThisReason);
1308
+ }
1309
+ else {
1310
+ console.log(crtResult.ThisReason);
1311
+ var fn = "CobraExport.xlsx";
1312
+ if (crtResult.ThisReason?.startsWith("{")) {
1313
+ var result = JSON.parse(crtResult.ThisReason);
1314
+ if (result.fn)
1315
+ fn = result.fn;
1316
+ }
1317
+ RESTClient.DisplayUserNotification();
1318
+ window.open(`${top.sfClient._SiteURL}/sfImg.ashx/CRT/${crt}/${fn}`);
1319
+ }
1320
+ });
1321
+ });
1322
+ //setTimeout("top.sfClient.ClearPleaseWaitDialog(); if (top.sfClient.ClearInClientSidePostbackFlag) top.sfClient.ClearInClientSidePostbackFlag(); //ExportCobra", 2345);
1323
+ }
1324
+ }, {
1325
+ "id": "btnDismiss",
1326
+ text: "Dismiss",
1327
+ click: function () {
1328
+ $Dialog.dialog("close");
1329
+ }
1330
+ }];
1331
+ $Dialog.dialog('option', 'buttons', DialogButtons);
1332
+ //return false; // do not return false, IE anchor href issue
1333
+ }
1334
+ HeyPleaseWait() {
1335
+ // this variant applies inside a frame
1336
+ if (sfRestClient.$CurrentPleaseWaitDialog && sfRestClient.$CurrentPleaseWaitDialog.is(":visible"))
1337
+ return sfRestClient.$CurrentPleaseWaitDialog;
1338
+ sfRestClient.$CurrentPleaseWaitDialog = this.jqAlert("Please wait...", "Working", "ui-icon-locked").addClass("sfPleaseWait");
1339
+ var DialogButtons = {};
1340
+ if (DialogButtons)
1341
+ sfRestClient.$CurrentPleaseWaitDialog.dialog('option', 'buttons', DialogButtons);
1342
+ return sfRestClient.$CurrentPleaseWaitDialog;
1343
+ }
1344
+ ClearPleaseWaitDialog() {
1345
+ if (sfRestClient.$CurrentPleaseWaitDialog) {
1346
+ sfRestClient.$CurrentPleaseWaitDialog.dialog("close");
1347
+ sfRestClient.$CurrentPleaseWaitDialog = null;
1348
+ }
1349
+ }
1212
1350
  /**
1213
1351
  * Converts traditional .NET date formats to Webix formats
1214
1352
  * @param dotNetFormat something like d or m/d/yyyy
@@ -1550,16 +1688,16 @@ class sfRestClient {
1550
1688
  var UseID;
1551
1689
  var url = sfRestClient._Options.PopNewDocLegacyURL;
1552
1690
  if (options?.indexOf("&UseID")) {
1553
- UseID = options.substr(options?.indexOf("&UseID") + 7, 36);
1691
+ UseID = options.substring(options?.indexOf("&UseID") + 7, 36);
1554
1692
  }
1555
1693
  else
1556
- UseID = await this.NewGuid(); // todo: fix this!!!
1694
+ UseID = await this.NewGuid();
1557
1695
  if (sfRestClient._Options.PopDocForceXBUI)
1558
1696
  url = sfRestClient._Options.PopNewDocXBURL;
1559
1697
  url = url.sfFormat(thisRestClient._SiteURL, dtk, project, options);
1560
1698
  if (sfRestClient._Options.LogLevel >= LoggingLevels.Verbose)
1561
1699
  console.log("PopNewDoc opening {0} DTK {1} using {2}".sfFormat(UseID, dtk, url));
1562
- var TargetTab = UseID.substr(UseID.lastIndexOf("-") + 1).toLowerCase();
1700
+ var TargetTab = UseID.substring(UseID.lastIndexOf("-") + 1).toLowerCase();
1563
1701
  //todo: determine if we need the "how many tabs" logic and dialog
1564
1702
  if (!window) {
1565
1703
  console.error("PopNewDoc() Must be called from a browser window");
@@ -1603,7 +1741,7 @@ class sfRestClient {
1603
1741
  url = url.sfFormat(thisRestClient._SiteURL, id);
1604
1742
  if (sfRestClient._Options.LogLevel >= LoggingLevels.Verbose)
1605
1743
  console.log("PopDoc opening DMK {0} DTK {1} using {2}".sfFormat(id, thisDocType, url));
1606
- var TargetTab = url.substr(url.lastIndexOf("-") + 1).toLowerCase();
1744
+ var TargetTab = url.substring(url.lastIndexOf("-") + 1).toLowerCase();
1607
1745
  //todo: determine if we need the "how many tabs" logic and dialog
1608
1746
  if (!window) {
1609
1747
  console.error("PopDoc() Must be called from a browser window");
@@ -1964,11 +2102,11 @@ class sfRestClient {
1964
2102
  if (pgHash.length > 0)
1965
2103
  pgname = pgHash; // for xb style
1966
2104
  if (pgname.indexOf("/") >= 0)
1967
- pgname = pgname.substr(pgname.lastIndexOf("/") + 1);
2105
+ pgname = pgname.substring(pgname.lastIndexOf("/") + 1);
1968
2106
  if (pgname.indexOf("?") >= 0)
1969
- pgname = pgname.substr(0, pgname.indexOf("?"));
2107
+ pgname = pgname.substring(0, pgname.indexOf("?"));
1970
2108
  if (pgname.indexOf(".") >= 0)
1971
- pgname = pgname.substr(0, pgname.indexOf("."));
2109
+ pgname = pgname.substring(0, pgname.indexOf("."));
1972
2110
  return pgname;
1973
2111
  }
1974
2112
  XBVariantOfPageName(classicPageName) {
@@ -2084,7 +2222,7 @@ class sfRestClient {
2084
2222
  rItem = `Unexpected ${typeof rItemRaw}`;
2085
2223
  sortPad = ((isGuid || (index.endsWith("ID")) || isJS) ? "" : " ");
2086
2224
  if (isJS) {
2087
- rItem = `<i class="fas fa-boxes sfShowPointer" data-js="${rItem.substr(11)}"></i>`;
2225
+ rItem = `<i class="fas fa-boxes sfShowPointer" data-js="${rItem.substring(11)}"></i>`;
2088
2226
  }
2089
2227
  else if (isGuid && rItem !== RESTClient.EmptyKey) {
2090
2228
  rItem = `${rItem} &nbsp;<i class="far fa-clipboard clsEnabledImgBtn" title="Copy" data-text="${rItem}"></i>`;
@@ -2170,12 +2308,14 @@ class sfRestClient {
2170
2308
  *
2171
2309
  * Actions Supported
2172
2310
  * - vPgPopup(...)
2173
- * - PopDoc(...)
2174
- * - PopTXHistory(...)
2311
+ * - PopDoc(...) and PopNewDoc
2312
+ * - PopTXHistory(...) and PopBFAHistory()
2175
2313
  * - Nav To (dcmodules and admin tools)
2176
2314
  */
2177
- InvokeAction(actionString, rowData) {
2315
+ InvokeAction(actionString, rowData, options) {
2178
2316
  var ActionString = "";
2317
+ var UseNewTabWindow = false;
2318
+ var RESTClient = this;
2179
2319
  if (typeof actionString === "string")
2180
2320
  ActionString = actionString;
2181
2321
  if (actionString instanceof _SwaggerClientExports.MenuAction) {
@@ -2201,6 +2341,7 @@ class sfRestClient {
2201
2341
  ActionOptions = "&" + ActionString.substring(ActionString.indexOf("?") + 1);
2202
2342
  }
2203
2343
  ActionString = `javascript:vPgPopup('v/LibView.aspx', '${ActionOptions}', 850, 950);`; // ... w,h
2344
+ UseNewTabWindow = true;
2204
2345
  }
2205
2346
  else {
2206
2347
  this.ModalDialog(ActionString, undefined, undefined, window);
@@ -2220,7 +2361,12 @@ class sfRestClient {
2220
2361
  var ActionArgs = this.ExpandActionMarkers(match.groups.args, rowData);
2221
2362
  if (ActionArgs && ActionArgs.indexOf("&Project") < 0)
2222
2363
  ActionArgs += "&Project=" + this.GetPageProjectKey();
2223
- this.VModalPage(match.groups.vpgName, ActionArgs, parseInt(match.groups.width), parseInt(match.groups.height), match.groups.default);
2364
+ if (UseNewTabWindow) {
2365
+ var url = `${RESTClient._SiteRootURL}/pvp.aspx?vpg=${match.groups.vpgName}${ActionArgs}`;
2366
+ self.open(url, match.groups.vpgName);
2367
+ }
2368
+ else
2369
+ this.VModalPage(match.groups.vpgName, ActionArgs, parseInt(match.groups.width), parseInt(match.groups.height), match.groups.default);
2224
2370
  }
2225
2371
  else {
2226
2372
  console.warn("InvokeAction::VPg failed match", ActionString);
@@ -2254,17 +2400,56 @@ class sfRestClient {
2254
2400
  console.warn("InvokeAction::PopNewDoc failed match", actionString);
2255
2401
  }
2256
2402
  }
2257
- else if (ActionString.indexOf("PopTXHistory(") >= 0) {
2403
+ else if (ActionString.indexOf("PopTXHistory(") + ActionString.indexOf("PopBFAHistory(") >= 0) {
2258
2404
  console.warn("InvokeAction::TXH not really done", ActionString);
2405
+ var rx;
2406
+ var vpgName;
2407
+ var Project = this.GetPageProjectKey();
2408
+ var Task = "%", Acct = "%", Period = "%";
2409
+ var BFAMode = false;
2410
+ var mode = "";
2411
+ var PageDSK = "";
2412
+ if (!options)
2413
+ options = { ByTask: true, ByAcct: true };
2414
+ if (ActionString.indexOf("PopBFAHistory(") >= 0) {
2415
+ rx = /PopBFAHistory\(['"](?<PGDSK>.*?)['"],\s*?(?<project>.*?),\s*?(?<task>.*?),\s*?(?<acct>.*?),['"](?<mode>.*?)['"]\s*?\)/gm;
2416
+ vpgName = "BFANotes";
2417
+ BFAMode = true;
2418
+ }
2419
+ else {
2420
+ // this rx does not remove quotes from period
2421
+ rx = /PopTXHistory\(\\?['"](?<pgname>.*?)\\?['"],\s*?(?<task>.*?),\s*?(?<acct>.*?) (,\s*?(?<period>.*?)|\));/gm;
2422
+ vpgName = "TranHistory";
2423
+ }
2424
+ var match = rx.exec(ActionString);
2425
+ if (match && match.groups) {
2426
+ // we ignore the task and account in the invoice action string - see InvokeOptions
2427
+ if (match.groups.project)
2428
+ Project = match.groups.project;
2429
+ if (match.groups.mode)
2430
+ mode = match.groups.mode;
2431
+ if (match.groups.PGDSK)
2432
+ PageDSK = match.groups.PGDSK;
2433
+ if (match.groups.period)
2434
+ Period = match.groups.period;
2435
+ }
2436
+ var ModalOptions;
2437
+ if (BFAMode) {
2438
+ ModalOptions = `&project=${Project}&ds=1&task=${Task}&acct=${Acct}&period=${Period}`;
2439
+ }
2440
+ else {
2441
+ ModalOptions = `&project=${Project}&task=${Task}&acct=${Acct}&period=%`;
2442
+ }
2259
2443
  // sample action: javascript:PopTXHistory(\"TranHistory\", ifByTask() ? Row.task.trim() : \"%\", ifByAcct() ? Row.acct.trim() :\"%\" );
2444
+ // sample javascript:PopBFAHistory('$$PDSID$$',row.Project, ifByTask() ? Row.task.trim() : \"%\", ifByAcct() ? Row.acct.trim() :\"%\" ,'PA');
2260
2445
  // sample http://stany2017/SFPMS/pvp.aspx?vpg=TranHistory&project=GC003&ds=1f573cce-ddd8-4463-a6a6-40c641357f47_ProjectCA_dsData&task=01000&acct=%25&period=%
2261
- var Project = this.GetPageProjectKey();
2262
- var Task = "%", Acct = "%";
2263
- if (rowData && rowData["task"])
2446
+ if (options && options.ByTask && rowData && rowData["task"])
2264
2447
  Task = rowData["task"];
2265
- if (rowData && rowData["acct"])
2448
+ if (options && options.ByAcct && rowData && rowData["acct"])
2266
2449
  Acct = rowData["acct"];
2267
- this.VModalPage("TranHistory", "&project={0}&task={1}&acct={2}&period=%".sfFormat(Project, Task, Acct), 999, 444, undefined);
2450
+ if (sfRestClient._Options.LogLevel >= LoggingLevels.Verbose)
2451
+ console.log(`InvokeAction: VModalPage(${vpgName})`, ModalOptions);
2452
+ this.VModalPage(vpgName, ModalOptions, 999, 444, undefined);
2268
2453
  }
2269
2454
  else if (ActionString.indexOf("PopXLTool(") >= 0 ||
2270
2455
  ActionString.indexOf("PopFVC(") >= 0 ||
@@ -2284,7 +2469,7 @@ class sfRestClient {
2284
2469
  var rx = /javascript:(PopMSWindowTool|PopXLTool|PopAuditTool)\(['"`](?<URL>.*)[`'"]\)/gm;
2285
2470
  var match = rx.exec(ActionString);
2286
2471
  if (match && match.groups) {
2287
- targetURL = match.groups.URL;
2472
+ targetURL = this.ExpandActionMarkers(match.groups.URL, rowData);
2288
2473
  }
2289
2474
  else
2290
2475
  console.warn("InvokeAction() could not parse", actionString);
@@ -2295,9 +2480,12 @@ class sfRestClient {
2295
2480
  console.warn("InvokeAction::tools not really done", ActionString);
2296
2481
  top.location.href = ActionString;
2297
2482
  }
2483
+ else if (ActionString.startsWith("javascript:sfExportCompetitiveBidData")) {
2484
+ this.ExportCompetitiveBidData();
2485
+ }
2298
2486
  else if (ActionString.startsWith("javascript:")) {
2299
2487
  try {
2300
- eval(ActionString.substr(11));
2488
+ eval(ActionString.substring(11));
2301
2489
  }
2302
2490
  catch (ex) {
2303
2491
  console.warn("InvokeAction::failed javascript ", ActionString, ex.message);
@@ -2312,10 +2500,14 @@ class sfRestClient {
2312
2500
  console.warn("InvokeAction() could not handle ", actionString);
2313
2501
  }
2314
2502
  }
2503
+ /** Creates an exchange token and calls OpenWindowsLinkHelper() */
2315
2504
  FollowLinkViaSFLink(targetURL, afterOpenArg, autoCloseDoc) {
2316
2505
  var RESTClient = this;
2317
2506
  if (targetURL.endsWith("&Project="))
2318
2507
  targetURL += RESTClient.GetPageProjectKey();
2508
+ console.log(`sfLink(${targetURL})`);
2509
+ if (targetURL.indexOf("$$") > 0)
2510
+ targetURL = this.ExpandActionMarkers(targetURL);
2319
2511
  if (!top?.ClickOnceExtension.HasDotNetApplicationExtension()) {
2320
2512
  var RetryLater = `FollowLinkViaSFLink('${targetURL}'`;
2321
2513
  if (typeof afterOpenArg !== "undefined") {
@@ -2380,7 +2572,7 @@ class sfRestClient {
2380
2572
  /**
2381
2573
  *
2382
2574
  * @param et token passed to sfLink
2383
- * @param afterOpenArg boolean/true: closes document page; false/0: posts back default refresh; ['e','a']: posts back e with a;
2575
+ * @param afterOpenArg boolean/true: closes document page; false/0: posts back default refresh; ['e','a']: posts back e with a; callback function is passed et
2384
2576
  * @param autoCloseDoc
2385
2577
  */
2386
2578
  OpenWindowsLinkHelper(et, afterOpenArg, autoCloseDoc) {
@@ -2401,7 +2593,7 @@ class sfRestClient {
2401
2593
  }
2402
2594
  xscript = `setTimeout(\'${innerScript};\', 242);` + xscript;
2403
2595
  }
2404
- else if (!afterOpenArg || typeof afterOpenArg === "string" || (Array.isArray(afterOpenArg) && afterOpenArg.length === 2)) {
2596
+ else if (typeof self.PostbackRefresh === "function" && !afterOpenArg || typeof afterOpenArg === "string" || (Array.isArray(afterOpenArg) && afterOpenArg.length === 2)) {
2405
2597
  if (!afterOpenArg)
2406
2598
  afterOpenArg = "ibtnRefreshAttachList";
2407
2599
  var pbArg = 'AfterPopFVC';
@@ -2417,20 +2609,46 @@ class sfRestClient {
2417
2609
  console.log("OpenWindowsLinkHelper() - no post action", afterOpenArg);
2418
2610
  if (typeof innerScript === "string" && innerScript.length > 0)
2419
2611
  xscript = `setTimeout(\'${innerScript};\', ${innerDelay});` + xscript;
2420
- setTimeout(xscript, 211);
2612
+ try {
2613
+ $.connection.sfPMSHub.server.activateExchangeToken(openURL).then(ok => {
2614
+ if (!ok)
2615
+ setTimeout(xscript, 211);
2616
+ else {
2617
+ console.log("Activated via SignalR");
2618
+ if (typeof innerScript === "string" && innerScript.length > 0)
2619
+ setTimeout(innerScript, innerDelay);
2620
+ }
2621
+ }).catch(r => {
2622
+ setTimeout(xscript, 211);
2623
+ });
2624
+ }
2625
+ catch (x) {
2626
+ console.warn(x);
2627
+ setTimeout(xscript, 211);
2628
+ }
2421
2629
  }
2422
- /** Finds $$ and other replacable values */
2630
+ /** Finds $$ markers and other replacable values.
2631
+ * Markers are case sensative
2632
+ */
2423
2633
  ExpandActionMarkers(rawAction, rowData) {
2424
2634
  if (rawAction.indexOf("$$PROJECT") >= 0) {
2425
2635
  rawAction = rawAction.replaceAll("$$PROJECT", this.GetActionMarkerReplacement("$$PROJECT", rowData));
2426
2636
  }
2637
+ if (rawAction.indexOf("$$PDSKEY") >= 0) {
2638
+ rawAction = rawAction.replaceAll("$$PDSKEY", this.GetActionMarkerReplacement("$$PDSKEY", rowData));
2639
+ }
2427
2640
  // general case: regex??
2428
2641
  return rawAction;
2429
2642
  }
2643
+ /** given a mark name, returns the replacement value
2644
+ * @see ExpandActionMarkers()
2645
+ * @argument markerName such as $$Project or $$PDSKEY
2646
+ * @argument rowData object containing row data - first source for value to replace the marker
2647
+ */
2430
2648
  GetActionMarkerReplacement(markerName, rowData) {
2431
2649
  var result = "";
2432
2650
  if (markerName.startsWith("$$")) {
2433
- markerName = markerName.substr(2, 1) + markerName.substr(3).toLowerCase();
2651
+ markerName = markerName.substring(2, 3) + markerName.substring(3).toLowerCase();
2434
2652
  }
2435
2653
  if (rowData)
2436
2654
  result = this.FieldValueFromRow(rowData, markerName);
@@ -2438,6 +2656,9 @@ class sfRestClient {
2438
2656
  if (markerName === "Project") {
2439
2657
  result = this.GetPageProjectKey();
2440
2658
  }
2659
+ if (markerName === "Pdskey") {
2660
+ result = this.GetPageContextValue("dsCacheKey");
2661
+ }
2441
2662
  }
2442
2663
  return result;
2443
2664
  }
@@ -2590,14 +2811,13 @@ class sfRestClient {
2590
2811
  });
2591
2812
  }
2592
2813
  GAMonitorPageHit(propertyID, clientID, url, title) {
2593
- if (sfRestClient.GAPageHitSent)
2594
- return;
2814
+ var RESTClient = this;
2595
2815
  if (!url) {
2596
- url = `${top?.location?.origin}${top?.location?.pathname}`;
2597
- var s = top?.location.search;
2598
- if (s && (!s.startsWith("?id=")) && (!s.startsWith("?add=")))
2599
- url = url + s;
2816
+ url = `${RESTClient._SiteURL}/${RESTClient.ResolvePageName()}`;
2600
2817
  }
2818
+ var pageHash = url.sfHashCode();
2819
+ if (sfRestClient.GALastPageHitSent === pageHash)
2820
+ return;
2601
2821
  if (!title)
2602
2822
  title = $('title').text();
2603
2823
  var payload = {
@@ -2608,14 +2828,14 @@ class sfRestClient {
2608
2828
  dl: url,
2609
2829
  dt: title,
2610
2830
  };
2611
- sfRestClient.GAPageHitSent = true;
2831
+ sfRestClient.GALastPageHitSent = pageHash;
2612
2832
  return this.GAMonitorSend(payload)
2613
2833
  .done(function (data, textStatus, jqXHR) {
2614
- console.log(`GAMonitor(pageview:${top?.location.pathname}) ok`);
2834
+ console.log(`GAMonitor(pageview:${url}) ok`);
2615
2835
  })
2616
2836
  .fail(function (jqXHR, textStatus) {
2617
2837
  sfRestClient.GAMonitorSendFailed = true;
2618
- console.warn(`GAMonitor(pgvw:${top?.location.pathname}) failed: ${jqXHR.responseText} `);
2838
+ console.warn(`GAMonitor(pgvw:${url}) failed: ${jqXHR.responseText} `);
2619
2839
  });
2620
2840
  }
2621
2841
  GAMonitorSend(payload) {
@@ -2634,8 +2854,7 @@ class sfRestClient {
2634
2854
  });
2635
2855
  }
2636
2856
  GAMonitorEvent(propertyID, clientID, category, action, label, value) {
2637
- if (!sfRestClient.GAPageHitSent)
2638
- this.GAMonitorPageHit(propertyID, clientID);
2857
+ this.GAMonitorPageHit(propertyID, clientID);
2639
2858
  var payload = {
2640
2859
  v: 1,
2641
2860
  t: "event",
@@ -2648,13 +2867,14 @@ class sfRestClient {
2648
2867
  };
2649
2868
  return this.GAMonitorSend(payload)
2650
2869
  .done(function (data, textStatus, jqXHR) {
2651
- console.log(`GAMonitor(${category}:${action}) ok`);
2870
+ console.log(`GAMonitor(${category}:${action}) ${label} ok`);
2652
2871
  })
2653
2872
  .fail(function (jqXHR, textStatus) {
2654
2873
  console.warn(`GAMonitor(${category}:${action}) failed: ${jqXHR.responseText}`);
2655
2874
  });
2656
2875
  }
2657
- sfGAEvent(category, action, label, value) {
2876
+ /** Google Analytics Event */
2877
+ GAEvent(category, action, label, value) {
2658
2878
  if (!value)
2659
2879
  value = 0;
2660
2880
  if (sfRestClient._WCC.GAFMOptOut) {
@@ -2663,8 +2883,9 @@ class sfRestClient {
2663
2883
  }
2664
2884
  this.GAMonitorEvent('UA-6465434-4', sfRestClient._WCC.SiteID, category, action, label, value);
2665
2885
  }
2666
- sfGADialogEvent(action, dialogName) {
2667
- this.sfGAEvent("Dialog", action, dialogName, 1);
2886
+ /** Shortcut that calls GAEvent("dialog",action, dialogName,1) */
2887
+ GADialogEvent(action, dialogName) {
2888
+ this.GAEvent("Dialog", action, dialogName, 1);
2668
2889
  }
2669
2890
  ValueHasWildcard(theVal) {
2670
2891
  if (theVal.indexOf("%") >= 0)
@@ -3448,10 +3669,10 @@ class sfRestClient {
3448
3669
  var ThisSuffix = "_dv";
3449
3670
  if (item.DataField?.startsWith("cmp_")) {
3450
3671
  // cmp_realfieldname_suffix
3451
- var RealFieldName = item.DataField.substr(4);
3672
+ var RealFieldName = item.DataField.substring(4);
3452
3673
  if (!(RealFieldName in rawRow)) {
3453
3674
  if (RealFieldName.indexOf("_") > 0)
3454
- RealFieldName = RealFieldName.substr(0, RealFieldName.indexOf("_"));
3675
+ RealFieldName = RealFieldName.substring(0, RealFieldName.indexOf("_"));
3455
3676
  if ((RealFieldName in rawRow && !(item.DataField in rawRow))) {
3456
3677
  var FieldValue = thisPart.RestClient.FieldValueFromRow(rawRow, RealFieldName);
3457
3678
  var DependsOn;
@@ -4037,7 +4258,7 @@ sfRestClient._Options = {
4037
4258
  ProjectXBURL: '{0}/spax.html#!/main/projectDashboard?project={1}',
4038
4259
  TaskStatePollInterval: 357
4039
4260
  };
4040
- sfRestClient.GAPageHitSent = false; // !!! this needs work
4261
+ sfRestClient.GALastPageHitSent = 0; // !!! this needs work
4041
4262
  sfRestClient.GAMonitorSendFailed = false;
4042
4263
  sfRestClient.$LookupDialogStack = [];
4043
4264
  sfRestClient._NextPingTimerID = undefined;