@olenbetong/appframe-core 2.15.2 → 2.16.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.
@@ -2,7 +2,7 @@ this.af = this.af || {};
2
2
  this.af.common = (function(exports) {
3
3
 
4
4
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
5
- //#region ../../node_modules/.pnpm/mitt@3.0.1/node_modules/mitt/dist/mitt.mjs
5
+ // ../../node_modules/.pnpm/mitt@3.0.1/node_modules/mitt/dist/mitt.mjs
6
6
  function mitt_default(n) {
7
7
  return {
8
8
  all: n = n || /* @__PURE__ */ new Map(),
@@ -25,8 +25,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
25
25
  };
26
26
  }
27
27
 
28
- //#endregion
29
- //#region \0@oxc-project+runtime@0.151.0/helpers/esm/typeof.js
28
+ // \0@oxc-project+runtime@0.157.0/helpers/esm/typeof.js
30
29
  function _typeof(o) {
31
30
  "@babel/helpers - typeof";
32
31
  return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
@@ -36,28 +35,25 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
36
35
  }, _typeof(o);
37
36
  }
38
37
 
39
- //#endregion
40
- //#region \0@oxc-project+runtime@0.151.0/helpers/esm/toPrimitive.js
41
- function toPrimitive(t, r) {
38
+ // \0@oxc-project+runtime@0.157.0/helpers/esm/toPrimitive.js
39
+ function toPrimitive(t, e) {
42
40
  if ("object" != _typeof(t) || !t) return t;
43
- var e = t[Symbol.toPrimitive];
44
- if (void 0 !== e) {
45
- var i = e.call(t, r || "default");
41
+ var r;
42
+ if ("undefined" != typeof Symbol && void 0 !== (r = t[Symbol.toPrimitive])) {
43
+ var i = r.call(t, e || "default");
46
44
  if ("object" != _typeof(i)) return i;
47
45
  throw new TypeError("@@toPrimitive must return a primitive value.");
48
46
  }
49
- return ("string" === r ? String : Number)(t);
47
+ return ("string" === e ? String : Number)(t);
50
48
  }
51
49
 
52
- //#endregion
53
- //#region \0@oxc-project+runtime@0.151.0/helpers/esm/toPropertyKey.js
50
+ // \0@oxc-project+runtime@0.157.0/helpers/esm/toPropertyKey.js
54
51
  function toPropertyKey(t) {
55
52
  var i = toPrimitive(t, "string");
56
53
  return "symbol" == _typeof(i) ? i : i + "";
57
54
  }
58
55
 
59
- //#endregion
60
- //#region \0@oxc-project+runtime@0.151.0/helpers/esm/defineProperty.js
56
+ // \0@oxc-project+runtime@0.157.0/helpers/esm/defineProperty.js
61
57
  function _defineProperty(e, r, t) {
62
58
  return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
63
59
  value: t,
@@ -67,8 +63,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
67
63
  }) : e[r] = t, e;
68
64
  }
69
65
 
70
- //#endregion
71
- //#region src/SessionHandler.ts
66
+ // src/SessionHandler.ts
72
67
  var SessionHandler = class {
73
68
  constructor() {
74
69
  _defineProperty(this, "eventHandler", mitt_default());
@@ -115,8 +110,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
115
110
  }
116
111
  };
117
112
 
118
- //#endregion
119
- //#region src/UserSession.ts
113
+ // src/UserSession.ts
120
114
  var UserSession = class extends SessionHandler {
121
115
  constructor(userData) {
122
116
  super();
@@ -188,8 +182,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
188
182
  }
189
183
  };
190
184
 
191
- //#endregion
192
- //#region src/log.ts
185
+ // src/log.ts
193
186
  const article = window.af?.article?.id ?? window.window?.location.pathname.substring(1).split("/")[0];
194
187
  /**
195
188
  * Logs an activity to the website activity log
@@ -334,15 +327,13 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
334
327
  };
335
328
  }
336
329
 
337
- //#endregion
338
- //#region src/errorHandler.ts
330
+ // src/errorHandler.ts
339
331
  window.window?.addEventListener("error", (event) => {
340
332
  if (typeof event === "object" && "error" in event) logError(event.error);
341
333
  else if (typeof event === "object" && "message" in event) logError(event);
342
334
  });
343
335
 
344
- //#endregion
345
- //#region src/localStorage.ts
336
+ // src/localStorage.ts
346
337
  function getLocalKey(key) {
347
338
  return [
348
339
  af?.article?.id || "",
@@ -379,8 +370,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
379
370
  };
380
371
  var localStorage_default = new LocalStorage();
381
372
 
382
- //#endregion
383
- //#region src/date.ts
373
+ // src/date.ts
384
374
  function toLocalISODate(date) {
385
375
  return date ? toLocalISODateTime(date).substring(0, 10) : null;
386
376
  }
@@ -403,8 +393,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
403
393
  return date ? date.toISOString().substring(0, 16) : "";
404
394
  }
405
395
 
406
- //#endregion
407
- //#region src/downloadBlob.ts
396
+ // src/downloadBlob.ts
408
397
  function downloadBlob(blob, fileName) {
409
398
  return new Promise((resolve, reject) => {
410
399
  try {
@@ -426,8 +415,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
426
415
  });
427
416
  }
428
417
 
429
- //#endregion
430
- //#region src/invariant.ts
418
+ // src/invariant.ts
431
419
  /**
432
420
  * Throws an error if the condition is falsy. The provided message is used as the error message.
433
421
  * A function can be provided to lazily generate the message.
@@ -442,8 +430,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
442
430
  throw new Error(provided ?? "Invariant failed");
443
431
  }
444
432
 
445
- //#endregion
446
- //#region src/downloadRequest.ts
433
+ // src/downloadRequest.ts
447
434
  async function downloadRequest(request, { fileName, signal, onProgress }) {
448
435
  let bytesReceived = 0;
449
436
  onProgress?.({ status: "requested" });
@@ -497,8 +484,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
497
484
  }
498
485
  }
499
486
 
500
- //#endregion
501
- //#region src/parseFunc.ts
487
+ // src/parseFunc.ts
502
488
  const funcRegex = /^function(?:\s+([a-zA-Z$_][a-zA-Z0-9$_]*))?\s*\(((?:(?:\s*[a-zA-Z$_][a-zA-Z0-9$_]*)(?:\s*,\s*[a-zA-Z$_][a-zA-Z0-9$_]*)*)?)\s*\)\s*\{((?:.|\n|\r)*)\}$/;
503
489
  const arrowBlockRegex = /^(?:\(([^)]*)\)|([a-zA-Z$_][a-zA-Z0-9$_]*))\s*=>\s*\{([\s\S]*)\}$/;
504
490
  const arrowExpressionRegex = /^(?:\(([^)]*)\)|([a-zA-Z$_][a-zA-Z0-9$_]*))\s*=>\s*([\s\S]+)$/;
@@ -532,13 +518,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
532
518
  };
533
519
  }
534
520
 
535
- //#endregion
536
- //#region src/Namespace.ts
521
+ // src/Namespace.ts
537
522
  function Namespace() {}
538
523
  Namespace.prototype = Object.create(null);
539
524
 
540
- //#endregion
541
- //#region src/requireNamespace.ts
525
+ // src/requireNamespace.ts
542
526
  function requireNamespace(root, namespace) {
543
527
  if (typeof root === "object") {
544
528
  if (typeof namespace === "string") return requireNamespace(root, namespace.split("."));
@@ -550,8 +534,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
550
534
  }
551
535
  }
552
536
 
553
- //#endregion
554
- //#region src/expose.ts
537
+ // src/expose.ts
555
538
  /**
556
539
  * Expose a value to a potentially deeply nested global variable
557
540
  * @param name {string | object} Either a dot-separated path to the global variable, or an object to expose the value on
@@ -581,8 +564,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
581
564
  }
582
565
  }
583
566
 
584
- //#endregion
585
- //#region src/getLocalizedString.ts
567
+ // src/getLocalizedString.ts
586
568
  async function fetchLocalizedString(text, project) {
587
569
  try {
588
570
  let response = await fetch(`/api/user/localize/new/${encodeURIComponent(project)}`, {
@@ -671,8 +653,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
671
653
  };
672
654
  }
673
655
 
674
- //#endregion
675
- //#region src/filter/operators.ts
656
+ // src/filter/operators.ts
676
657
  /**
677
658
  * Operators that take no value at all.
678
659
  *
@@ -686,6 +667,26 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
686
667
  "isblank",
687
668
  "isnotblank"
688
669
  ];
670
+ /**
671
+ * Whole-period checks for dates, such as "Is last week", in the order of the
672
+ * Windows filter editor. They take no value. The framework has no operator for
673
+ * them, so a filter using one is sent as a filter string (`needsFilterString`).
674
+ */
675
+ const PERIOD_OPERATORS = [
676
+ "isbeyondthisyear",
677
+ "islaterthisyear",
678
+ "islaterthismonth",
679
+ "isnextweek",
680
+ "islaterthisweek",
681
+ "istomorrow",
682
+ "istoday",
683
+ "isyesterday",
684
+ "isearlierthisweek",
685
+ "islastweek",
686
+ "isearlierthismonth",
687
+ "isearlierthisyear",
688
+ "ispriorthisyear"
689
+ ];
689
690
  /** Operators whose value is a two element `[from, to]` array. */
690
691
  const PAIR_OPERATORS = [
691
692
  "between",
@@ -696,7 +697,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
696
697
  /** Operators whose value is an array of values. */
697
698
  const LIST_OPERATORS = ["inlist", "notinlist"];
698
699
  function getOperatorArity(operator) {
699
- if (PARAMETERLESS_OPERATORS.includes(operator)) return "none";
700
+ if (PARAMETERLESS_OPERATORS.includes(operator) || PERIOD_OPERATORS.includes(operator)) return "none";
700
701
  if (PAIR_OPERATORS.includes(operator)) return "pair";
701
702
  if (LIST_OPERATORS.includes(operator)) return "list";
702
703
  return "single";
@@ -739,7 +740,20 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
739
740
  datelessthan: "Before",
740
741
  datelessthanorequal: "Up to",
741
742
  datebetween: "Between",
742
- datenotbetween: "Not between"
743
+ datenotbetween: "Not between",
744
+ isbeyondthisyear: "Is beyond this year",
745
+ islaterthisyear: "Is later this year",
746
+ islaterthismonth: "Is later this month",
747
+ isnextweek: "Is next week",
748
+ islaterthisweek: "Is later this week",
749
+ istomorrow: "Is tomorrow",
750
+ istoday: "Is today",
751
+ isyesterday: "Is yesterday",
752
+ isearlierthisweek: "Is earlier this week",
753
+ islastweek: "Is last week",
754
+ isearlierthismonth: "Is earlier this month",
755
+ isearlierthisyear: "Is earlier this year",
756
+ ispriorthisyear: "Is prior to this year"
743
757
  };
744
758
  /** Comparison operator labels used for date and time fields. */
745
759
  const DATE_OPERATOR_LABELS = {
@@ -784,13 +798,15 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
784
798
  ...EQUALITY,
785
799
  ...LIST_CHECKS,
786
800
  ...RANGE,
787
- ...COMPARISONS
801
+ ...COMPARISONS,
802
+ ...PERIOD_OPERATORS
788
803
  ],
789
804
  datetime: [
790
805
  ...EQUALITY,
791
806
  ...LIST_CHECKS,
792
807
  ...RANGE,
793
- ...COMPARISONS
808
+ ...COMPARISONS,
809
+ ...PERIOD_OPERATORS
794
810
  ],
795
811
  number: [
796
812
  ...EQUALITY,
@@ -863,7 +879,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
863
879
  const RELATIVE_DATE_VALUES = [
864
880
  "Yesterday",
865
881
  "Today",
882
+ "Now",
866
883
  "Tomorrow",
884
+ "DayAfterTomorrow",
885
+ "TwoWeeksAway",
867
886
  "ThisWeek",
868
887
  "ThisMonth",
869
888
  "ThisYear",
@@ -878,7 +897,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
878
897
  CurrentUser: "Current user",
879
898
  Yesterday: "Yesterday",
880
899
  Today: "Today",
900
+ Now: "Now",
881
901
  Tomorrow: "Tomorrow",
902
+ DayAfterTomorrow: "Day after tomorrow",
903
+ TwoWeeksAway: "Two weeks away",
882
904
  ThisWeek: "This week",
883
905
  ThisMonth: "This month",
884
906
  ThisYear: "This year",
@@ -914,6 +936,30 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
914
936
  if (field.type === "string") return ["CurrentUser"];
915
937
  return [];
916
938
  }
939
+ /** Operators that can compare a field with another column. */
940
+ const COLUMN_OPERATORS = [
941
+ ...EQUALITY,
942
+ ...RANGE,
943
+ ...COMPARISONS
944
+ ];
945
+ /** Whether an operator can take another column as its value. */
946
+ function supportsColumnValue(operator) {
947
+ return COLUMN_OPERATORS.includes(operator);
948
+ }
949
+ /** Dates and datetimes compare with each other; other types only with their own. */
950
+ function getComparableType(type) {
951
+ return type === "datetime" ? "date" : type;
952
+ }
953
+ /**
954
+ * The columns a field can be compared with: the other fields of the same type,
955
+ * as in the Windows filter editor. Booleans have only true and false checks,
956
+ * so they get none.
957
+ */
958
+ function getColumnsForField(field, fields) {
959
+ if (field.type === "boolean") return [];
960
+ let type = getComparableType(field.type);
961
+ return fields.filter((other) => other.name !== field.name && !other.excludeFromFilter && getComparableType(other.type) === type);
962
+ }
917
963
  /**
918
964
  * Aliases for names `eOperators.ToString()` can produce that are not operators
919
965
  * in their own right. `Not` is the bare negation flag (i.e. "not equal to"),
@@ -937,8 +983,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
937
983
  return OPERATOR_ALIASES[normalized] ?? normalized;
938
984
  }
939
985
 
940
- //#endregion
941
- //#region src/filter/tree.ts
986
+ // src/filter/tree.ts
942
987
  /**
943
988
  * Creates the default empty filter: a single `and` group with no conditions.
944
989
  */
@@ -1025,10 +1070,40 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1025
1070
  let arity = getOperatorArity(normalizeOperator(item.operator));
1026
1071
  if (arity === "none") return true;
1027
1072
  if (item.value === null || item.value === void 0 || item.value === "") return false;
1028
- if (arity === "pair") return Array.isArray(item.value) && item.value.length === 2 && item.value.every((v) => v !== "" && v != null);
1073
+ if (arity === "pair") return Array.isArray(item.value) && item.value.length === 2 && item.value.every((v) => {
1074
+ let end = isRangeEnd(v) ? v.value : v;
1075
+ return end !== "" && end != null;
1076
+ });
1029
1077
  if (arity === "list") return Array.isArray(item.value) && item.value.length > 0;
1030
1078
  return true;
1031
1079
  }
1080
+ /** Whether a range value end is a `FilterRangeEnd` rather than a plain value. */
1081
+ function isRangeEnd(value) {
1082
+ return typeof value === "object" && value !== null && !(value instanceof Date) && "valueType" in value;
1083
+ }
1084
+ /** Dynamic values the framework has no `eDynamicValue` member for. */
1085
+ const DYNAMIC_VALUES_WITHOUT_FRAMEWORK_SUPPORT = /* @__PURE__ */ new Set([
1086
+ "Now",
1087
+ "DayAfterTomorrow",
1088
+ "TwoWeeksAway"
1089
+ ]);
1090
+ function needsConversion(valueType, value) {
1091
+ if (valueType === "column") return true;
1092
+ return valueType === "special" && typeof value === "string" && DYNAMIC_VALUES_WITHOUT_FRAMEWORK_SUPPORT.has(value);
1093
+ }
1094
+ /**
1095
+ * True when the filter holds something the framework's data API cannot read
1096
+ * from a filter object: another column, a range end that is not a plain value,
1097
+ * one of the dates only the Windows editor offers, or a whole-period check. Such a filter must be
1098
+ * converted with `convertFilter` and sent as a filter string.
1099
+ */
1100
+ function needsFilterString(filter) {
1101
+ if (!filter) return false;
1102
+ if (isGroup(filter)) return filter.items.some(needsFilterString);
1103
+ if (PERIOD_OPERATORS.includes(normalizeOperator(filter.operator))) return true;
1104
+ if (needsConversion(filter.valueType, filter.value)) return true;
1105
+ return Array.isArray(filter.value) && filter.value.some((item) => isRangeEnd(item));
1106
+ }
1032
1107
  /**
1033
1108
  * Creates an expression for a field, using the field's default operator and an
1034
1109
  * empty value of the right shape.
@@ -1059,8 +1134,9 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1059
1134
  let previousArity = getOperatorArity(normalizeOperator(expression.operator));
1060
1135
  let arity = getOperatorArity(operator);
1061
1136
  let value = expression.value;
1062
- if (arity !== previousArity) value = createEmptyValue(operator);
1063
- let valueType = expression.valueType === "special" && arity === previousArity ? "special" : getValueType(field, operator);
1137
+ let holdsColumn = expression.valueType === "column" || Array.isArray(value) && value.some((item) => isRangeEnd(item) && item.valueType === "column");
1138
+ if (arity !== previousArity || holdsColumn && !supportsColumnValue(operator)) value = createEmptyValue(operator);
1139
+ let valueType = (expression.valueType === "special" || expression.valueType === "column") && value === expression.value ? expression.valueType : getValueType(field, operator);
1064
1140
  return {
1065
1141
  ...expression,
1066
1142
  operator,
@@ -1126,8 +1202,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1126
1202
  return insertNodeAtPath(filter, path, createEmptyGroup(parent && isGroup(parent) && parent.mode === "and" ? "or" : "and"));
1127
1203
  }
1128
1204
 
1129
- //#endregion
1130
- //#region src/filter/convertFilter.ts
1205
+ // src/filter/convertFilter.ts
1131
1206
  const CONVERT_URL = "/api/filter/convert";
1132
1207
  /**
1133
1208
  * Converts between a structured filter and a DevExpress filter string.
@@ -1152,8 +1227,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1152
1227
  };
1153
1228
  }
1154
1229
 
1155
- //#endregion
1156
- //#region src/filter/describeFilter.ts
1230
+ // src/filter/describeFilter.ts
1157
1231
  /**
1158
1232
  * Builds a human-readable description of a filter, without contacting the
1159
1233
  * server. Use this for read-only summaries; the authoritative filter string is
@@ -1181,18 +1255,19 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1181
1255
  let label = getOperatorLabel(operator, field?.type);
1182
1256
  let arity = getOperatorArity(operator);
1183
1257
  if (arity === "none") return `[${caption}] ${label}`;
1184
- return `[${caption}] ${label} ${formatValue(expression, arity)}`;
1258
+ return `[${caption}] ${label} ${formatValue(expression, arity, fields)}`;
1185
1259
  }
1186
- function formatValue(expression, arity) {
1260
+ function formatValue(expression, arity, fields) {
1187
1261
  let { value, valueType } = expression;
1188
- if (valueType === "special" && typeof value === "string") return getDynamicValueLabel(value);
1189
1262
  if (Array.isArray(value)) {
1190
- let formatted = value.map((item) => formatScalar(item, valueType));
1263
+ let formatted = value.map((item) => isRangeEnd(item) ? formatScalar(item.value, item.valueType, fields) : formatScalar(item, valueType, fields));
1191
1264
  return arity === "pair" ? formatted.join(" - ") : `(${formatted.join(", ")})`;
1192
1265
  }
1193
- return formatScalar(value, valueType);
1266
+ return formatScalar(value, valueType, fields);
1194
1267
  }
1195
- function formatScalar(value, valueType) {
1268
+ function formatScalar(value, valueType, fields) {
1269
+ if (valueType === "special" && typeof value === "string") return getDynamicValueLabel(value);
1270
+ if (valueType === "column" && typeof value === "string") return `[${fields.get(value.toLowerCase())?.caption ?? value}]`;
1196
1271
  if (value === null || value === void 0) return "";
1197
1272
  if (value instanceof Date) return value.toISOString().slice(0, 10);
1198
1273
  if (typeof value === "number" || typeof value === "boolean") return String(value);
@@ -1200,8 +1275,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1200
1275
  return `'${String(value)}'`;
1201
1276
  }
1202
1277
 
1203
- //#endregion
1204
- //#region src/filter/fields.ts
1278
+ // src/filter/fields.ts
1205
1279
  const FIELD_TYPES = [
1206
1280
  "string",
1207
1281
  "number",
@@ -1236,8 +1310,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1236
1310
  return records.map(toFieldMetadata).filter((field) => field.name !== "" && !field.excludeFromFilter).sort((a, b) => a.name.localeCompare(b.name));
1237
1311
  }
1238
1312
 
1239
- //#endregion
1240
- //#region src/filter/standardLayout.ts
1313
+ // src/filter/standardLayout.ts
1241
1314
  /**
1242
1315
  * The "standard layout" is the simplified shape the Windows filter editor can
1243
1316
  * render in its flow view: an outer `or` group whose items are `and` groups of
@@ -1319,8 +1392,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1319
1392
  for (let child of item.items) collectExpressions(child, into);
1320
1393
  }
1321
1394
 
1322
- //#endregion
1323
- //#region src/filter/savedFilters.ts
1395
+ // src/filter/savedFilters.ts
1324
1396
  /**
1325
1397
  * `sviw_Database_MyFilters` unions in a synthetic "No Filter" row so the Windows
1326
1398
  * tree can render a "no filter" entry. It is not a real filter and must be
@@ -1419,8 +1491,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1419
1491
  */
1420
1492
  const canSetCrossDomain = canRenameSavedFilter;
1421
1493
 
1422
- //#endregion
1423
- //#region src/getUserImage.ts
1494
+ // src/getUserImage.ts
1424
1495
  const sizeMap = {
1425
1496
  xs: 64,
1426
1497
  sm: 128,
@@ -1435,8 +1506,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1435
1506
  return `/api/data/blob/EmployeesLookup/${primKeyOrOptions}/Image/${encodeURIComponent(login ?? "")}${login ? "." : ""}${encodeURIComponent(hash)}.jpg${sizePx ? `?width=${sizePx}` : ""}`;
1436
1507
  }
1437
1508
 
1438
- //#endregion
1439
- //#region src/localize.ts
1509
+ // src/localize.ts
1440
1510
  /**
1441
1511
  * Localization function for tagged templates. Replaces the arguments
1442
1512
  * with $n, where n is the index, before asking Appframe to translate
@@ -1460,8 +1530,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1460
1530
  return localized;
1461
1531
  }
1462
1532
 
1463
- //#endregion
1464
- //#region src/report/recordSource.ts
1533
+ // src/report/recordSource.ts
1465
1534
  const XML_ENTITIES = {
1466
1535
  amp: "&",
1467
1536
  lt: "<",
@@ -1527,14 +1596,26 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1527
1596
  return columns;
1528
1597
  }
1529
1598
  /**
1599
+ * The record source a document holds. Parameter lookups store one `<afRecordSource>`; a report
1600
+ * stores its record sources as `<ArrayOfAfReportRecordSource>` with one `<afReportRecordSource>`
1601
+ * per data source, of which the one with the ID `Master` feeds the report (else the first).
1602
+ */
1603
+ function pickRecordSource(document) {
1604
+ if (!document) return null;
1605
+ let sources = [...document.matchAll(/<(afRecordSource|afReportRecordSource)(?:\s[^>]*)?>([\s\S]*?)<\/\1>/g)].map((match) => match[2]);
1606
+ if (sources.length === 0) return null;
1607
+ return sources.find((source) => readElement(source, "ID") === "Master") ?? sources[0];
1608
+ }
1609
+ /**
1530
1610
  * Reads the parts of an `afRecordSource` a web client can act on: the view, the
1531
1611
  * selected columns and the design-time filter.
1532
1612
  *
1533
1613
  * Returns `null` for anything that is not a record source, so a missing or
1534
1614
  * empty `RecordSource` column simply means "no lookup".
1535
1615
  */
1536
- function parseRecordSource(xml) {
1537
- if (!xml || !xml.includes("<afRecordSource")) return null;
1616
+ function parseRecordSource(document) {
1617
+ let xml = pickRecordSource(document);
1618
+ if (!xml) return null;
1538
1619
  let viewName = readElement(xml, "ViewName");
1539
1620
  if (!viewName) return null;
1540
1621
  let maxRecords = readElement(xml, "MaxRecords");
@@ -1547,8 +1628,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1547
1628
  };
1548
1629
  }
1549
1630
 
1550
- //#endregion
1551
- //#region src/report/parameters.ts
1631
+ // src/report/parameters.ts
1552
1632
  /**
1553
1633
  * Report parameters: mapping the metadata records onto something renderable,
1554
1634
  * and the XML the parameter values are stored as on a saved filter.
@@ -1701,8 +1781,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1701
1781
  return values;
1702
1782
  }
1703
1783
 
1704
- //#endregion
1705
- //#region src/report/parameterDefaults.ts
1784
+ // src/report/parameterDefaults.ts
1706
1785
  /**
1707
1786
  * Resolving report parameter defaults that name a stored procedure.
1708
1787
  *
@@ -1764,8 +1843,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1764
1843
  return row;
1765
1844
  }
1766
1845
 
1767
- //#endregion
1768
- //#region src/report/render.ts
1846
+ // src/report/render.ts
1769
1847
  /**
1770
1848
  * Rendering a report through the framework's report route.
1771
1849
  *
@@ -1969,8 +2047,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1969
2047
  }));
1970
2048
  }
1971
2049
 
1972
- //#endregion
1973
- //#region src/report/report.ts
2050
+ // src/report/report.ts
1974
2051
  /**
1975
2052
  * Mapping a `sviw_WinClient_MyReports` record onto the report model, including
1976
2053
  * which output formats the report offers.
@@ -2014,8 +2091,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2014
2091
  };
2015
2092
  }
2016
2093
 
2017
- //#endregion
2018
- //#region src/alert.ts
2094
+ // src/alert.ts
2019
2095
  const template = `
2020
2096
  <dialog class="alert-dialog">
2021
2097
  <form method="dialog">
@@ -2126,8 +2202,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2126
2202
  });
2127
2203
  }
2128
2204
 
2129
- //#endregion
2130
- //#region src/settings.ts
2205
+ // src/settings.ts
2131
2206
  function getKey(article) {
2132
2207
  return `${article ?? window.af?.article?.id ?? window.window?.location.pathname.substring(1).split("/")[0]}.${window.af?.userSession.login ?? "anonymous"}`;
2133
2208
  }
@@ -2147,13 +2222,12 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2147
2222
  localStorage.setItem(key, JSON.stringify(userSettings));
2148
2223
  }
2149
2224
 
2150
- //#endregion
2151
- //#region src/index.ts
2152
- const version = "2.15.2";
2225
+ // src/index.ts
2226
+ const version = "2.16.1";
2153
2227
 
2154
- //#endregion
2155
2228
  exports.ConfirmButtons = ConfirmButtons;
2156
2229
  exports.NO_FILTER_ID = NO_FILTER_ID;
2230
+ exports.PERIOD_OPERATORS = PERIOD_OPERATORS;
2157
2231
  exports.RELATIVE_DATE_VALUES = RELATIVE_DATE_VALUES;
2158
2232
  exports.SessionHandler = SessionHandler;
2159
2233
  exports.UserSession = UserSession;
@@ -2183,6 +2257,7 @@ exports.encodeXml = encodeXml;
2183
2257
  exports.expose = expose;
2184
2258
  exports.fetchParameterDefault = fetchParameterDefault;
2185
2259
  exports.findSavedFilter = findSavedFilter;
2260
+ exports.getColumnsForField = getColumnsForField;
2186
2261
  exports.getDefaultOperator = getDefaultOperator;
2187
2262
  exports.getDefaultParameterValues = getDefaultParameterValues;
2188
2263
  exports.getDynamicValueLabel = getDynamicValueLabel;
@@ -2208,12 +2283,14 @@ exports.isEmptyFilter = isEmptyFilter;
2208
2283
  exports.isExpression = isExpression;
2209
2284
  exports.isGroup = isGroup;
2210
2285
  exports.isProcedureDefault = isProcedureDefault;
2286
+ exports.isRangeEnd = isRangeEnd;
2211
2287
  exports.isStandardLayout = isStandardLayout;
2212
2288
  exports.localStorage = localStorage_default;
2213
2289
  exports.localize = localize;
2214
2290
  exports.logActivity = logActivity;
2215
2291
  exports.logError = logError;
2216
2292
  exports.mitt = mitt_default;
2293
+ exports.needsFilterString = needsFilterString;
2217
2294
  exports.normalizeOperator = normalizeOperator;
2218
2295
  exports.openAlertDialog = openAlertDialog;
2219
2296
  exports.openReport = openReport;
@@ -2233,6 +2310,7 @@ exports.saveSettings = saveSettings;
2233
2310
  exports.serializeParameters = serializeParameters;
2234
2311
  exports.setGroupMode = setGroupMode;
2235
2312
  exports.startActivity = startActivity;
2313
+ exports.supportsColumnValue = supportsColumnValue;
2236
2314
  exports.time = time;
2237
2315
  exports.toFieldMetadata = toFieldMetadata;
2238
2316
  exports.toFieldMetadataList = toFieldMetadataList;