@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 src/SessionHandler.ts
28
+ // src/SessionHandler.ts
30
29
  var SessionHandler = class {
31
30
  eventHandler = mitt_default();
32
31
  authenticated() {
@@ -71,8 +70,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
71
70
  }
72
71
  };
73
72
 
74
- //#endregion
75
- //#region src/UserSession.ts
73
+ // src/UserSession.ts
76
74
  var UserSession = class extends SessionHandler {
77
75
  amDesignator = "a.m.";
78
76
  dayNames = [
@@ -144,8 +142,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
144
142
  }
145
143
  };
146
144
 
147
- //#endregion
148
- //#region src/log.ts
145
+ // src/log.ts
149
146
  const article = window.af?.article?.id ?? window.window?.location.pathname.substring(1).split("/")[0];
150
147
  /**
151
148
  * Logs an activity to the website activity log
@@ -290,15 +287,13 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
290
287
  };
291
288
  }
292
289
 
293
- //#endregion
294
- //#region src/errorHandler.ts
290
+ // src/errorHandler.ts
295
291
  window.window?.addEventListener("error", (event) => {
296
292
  if (typeof event === "object" && "error" in event) logError(event.error);
297
293
  else if (typeof event === "object" && "message" in event) logError(event);
298
294
  });
299
295
 
300
- //#endregion
301
- //#region src/localStorage.ts
296
+ // src/localStorage.ts
302
297
  function getLocalKey(key) {
303
298
  return [
304
299
  af?.article?.id || "",
@@ -333,8 +328,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
333
328
  };
334
329
  var localStorage_default = new LocalStorage();
335
330
 
336
- //#endregion
337
- //#region src/date.ts
331
+ // src/date.ts
338
332
  function toLocalISODate(date) {
339
333
  return date ? toLocalISODateTime(date).substring(0, 10) : null;
340
334
  }
@@ -357,8 +351,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
357
351
  return date ? date.toISOString().substring(0, 16) : "";
358
352
  }
359
353
 
360
- //#endregion
361
- //#region src/downloadBlob.ts
354
+ // src/downloadBlob.ts
362
355
  function downloadBlob(blob, fileName) {
363
356
  return new Promise((resolve, reject) => {
364
357
  try {
@@ -380,8 +373,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
380
373
  });
381
374
  }
382
375
 
383
- //#endregion
384
- //#region src/invariant.ts
376
+ // src/invariant.ts
385
377
  /**
386
378
  * Throws an error if the condition is falsy. The provided message is used as the error message.
387
379
  * A function can be provided to lazily generate the message.
@@ -396,8 +388,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
396
388
  throw new Error(provided ?? "Invariant failed");
397
389
  }
398
390
 
399
- //#endregion
400
- //#region src/downloadRequest.ts
391
+ // src/downloadRequest.ts
401
392
  async function downloadRequest(request, { fileName, signal, onProgress }) {
402
393
  let bytesReceived = 0;
403
394
  onProgress?.({ status: "requested" });
@@ -451,8 +442,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
451
442
  }
452
443
  }
453
444
 
454
- //#endregion
455
- //#region src/parseFunc.ts
445
+ // src/parseFunc.ts
456
446
  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)*)\}$/;
457
447
  const arrowBlockRegex = /^(?:\(([^)]*)\)|([a-zA-Z$_][a-zA-Z0-9$_]*))\s*=>\s*\{([\s\S]*)\}$/;
458
448
  const arrowExpressionRegex = /^(?:\(([^)]*)\)|([a-zA-Z$_][a-zA-Z0-9$_]*))\s*=>\s*([\s\S]+)$/;
@@ -486,13 +476,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
486
476
  };
487
477
  }
488
478
 
489
- //#endregion
490
- //#region src/Namespace.ts
479
+ // src/Namespace.ts
491
480
  function Namespace() {}
492
481
  Namespace.prototype = Object.create(null);
493
482
 
494
- //#endregion
495
- //#region src/requireNamespace.ts
483
+ // src/requireNamespace.ts
496
484
  function requireNamespace(root, namespace) {
497
485
  if (typeof root === "object") {
498
486
  if (typeof namespace === "string") return requireNamespace(root, namespace.split("."));
@@ -504,8 +492,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
504
492
  }
505
493
  }
506
494
 
507
- //#endregion
508
- //#region src/expose.ts
495
+ // src/expose.ts
509
496
  /**
510
497
  * Expose a value to a potentially deeply nested global variable
511
498
  * @param name {string | object} Either a dot-separated path to the global variable, or an object to expose the value on
@@ -535,8 +522,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
535
522
  }
536
523
  }
537
524
 
538
- //#endregion
539
- //#region src/getLocalizedString.ts
525
+ // src/getLocalizedString.ts
540
526
  async function fetchLocalizedString(text, project) {
541
527
  try {
542
528
  let response = await fetch(`/api/user/localize/new/${encodeURIComponent(project)}`, {
@@ -625,8 +611,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
625
611
  };
626
612
  }
627
613
 
628
- //#endregion
629
- //#region src/filter/operators.ts
614
+ // src/filter/operators.ts
630
615
  /**
631
616
  * Operators that take no value at all.
632
617
  *
@@ -640,6 +625,26 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
640
625
  "isblank",
641
626
  "isnotblank"
642
627
  ];
628
+ /**
629
+ * Whole-period checks for dates, such as "Is last week", in the order of the
630
+ * Windows filter editor. They take no value. The framework has no operator for
631
+ * them, so a filter using one is sent as a filter string (`needsFilterString`).
632
+ */
633
+ const PERIOD_OPERATORS = [
634
+ "isbeyondthisyear",
635
+ "islaterthisyear",
636
+ "islaterthismonth",
637
+ "isnextweek",
638
+ "islaterthisweek",
639
+ "istomorrow",
640
+ "istoday",
641
+ "isyesterday",
642
+ "isearlierthisweek",
643
+ "islastweek",
644
+ "isearlierthismonth",
645
+ "isearlierthisyear",
646
+ "ispriorthisyear"
647
+ ];
643
648
  /** Operators whose value is a two element `[from, to]` array. */
644
649
  const PAIR_OPERATORS = [
645
650
  "between",
@@ -650,7 +655,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
650
655
  /** Operators whose value is an array of values. */
651
656
  const LIST_OPERATORS = ["inlist", "notinlist"];
652
657
  function getOperatorArity(operator) {
653
- if (PARAMETERLESS_OPERATORS.includes(operator)) return "none";
658
+ if (PARAMETERLESS_OPERATORS.includes(operator) || PERIOD_OPERATORS.includes(operator)) return "none";
654
659
  if (PAIR_OPERATORS.includes(operator)) return "pair";
655
660
  if (LIST_OPERATORS.includes(operator)) return "list";
656
661
  return "single";
@@ -693,7 +698,20 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
693
698
  datelessthan: "Before",
694
699
  datelessthanorequal: "Up to",
695
700
  datebetween: "Between",
696
- datenotbetween: "Not between"
701
+ datenotbetween: "Not between",
702
+ isbeyondthisyear: "Is beyond this year",
703
+ islaterthisyear: "Is later this year",
704
+ islaterthismonth: "Is later this month",
705
+ isnextweek: "Is next week",
706
+ islaterthisweek: "Is later this week",
707
+ istomorrow: "Is tomorrow",
708
+ istoday: "Is today",
709
+ isyesterday: "Is yesterday",
710
+ isearlierthisweek: "Is earlier this week",
711
+ islastweek: "Is last week",
712
+ isearlierthismonth: "Is earlier this month",
713
+ isearlierthisyear: "Is earlier this year",
714
+ ispriorthisyear: "Is prior to this year"
697
715
  };
698
716
  /** Comparison operator labels used for date and time fields. */
699
717
  const DATE_OPERATOR_LABELS = {
@@ -738,13 +756,15 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
738
756
  ...EQUALITY,
739
757
  ...LIST_CHECKS,
740
758
  ...RANGE,
741
- ...COMPARISONS
759
+ ...COMPARISONS,
760
+ ...PERIOD_OPERATORS
742
761
  ],
743
762
  datetime: [
744
763
  ...EQUALITY,
745
764
  ...LIST_CHECKS,
746
765
  ...RANGE,
747
- ...COMPARISONS
766
+ ...COMPARISONS,
767
+ ...PERIOD_OPERATORS
748
768
  ],
749
769
  number: [
750
770
  ...EQUALITY,
@@ -817,7 +837,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
817
837
  const RELATIVE_DATE_VALUES = [
818
838
  "Yesterday",
819
839
  "Today",
840
+ "Now",
820
841
  "Tomorrow",
842
+ "DayAfterTomorrow",
843
+ "TwoWeeksAway",
821
844
  "ThisWeek",
822
845
  "ThisMonth",
823
846
  "ThisYear",
@@ -832,7 +855,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
832
855
  CurrentUser: "Current user",
833
856
  Yesterday: "Yesterday",
834
857
  Today: "Today",
858
+ Now: "Now",
835
859
  Tomorrow: "Tomorrow",
860
+ DayAfterTomorrow: "Day after tomorrow",
861
+ TwoWeeksAway: "Two weeks away",
836
862
  ThisWeek: "This week",
837
863
  ThisMonth: "This month",
838
864
  ThisYear: "This year",
@@ -868,6 +894,30 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
868
894
  if (field.type === "string") return ["CurrentUser"];
869
895
  return [];
870
896
  }
897
+ /** Operators that can compare a field with another column. */
898
+ const COLUMN_OPERATORS = [
899
+ ...EQUALITY,
900
+ ...RANGE,
901
+ ...COMPARISONS
902
+ ];
903
+ /** Whether an operator can take another column as its value. */
904
+ function supportsColumnValue(operator) {
905
+ return COLUMN_OPERATORS.includes(operator);
906
+ }
907
+ /** Dates and datetimes compare with each other; other types only with their own. */
908
+ function getComparableType(type) {
909
+ return type === "datetime" ? "date" : type;
910
+ }
911
+ /**
912
+ * The columns a field can be compared with: the other fields of the same type,
913
+ * as in the Windows filter editor. Booleans have only true and false checks,
914
+ * so they get none.
915
+ */
916
+ function getColumnsForField(field, fields) {
917
+ if (field.type === "boolean") return [];
918
+ let type = getComparableType(field.type);
919
+ return fields.filter((other) => other.name !== field.name && !other.excludeFromFilter && getComparableType(other.type) === type);
920
+ }
871
921
  /**
872
922
  * Aliases for names `eOperators.ToString()` can produce that are not operators
873
923
  * in their own right. `Not` is the bare negation flag (i.e. "not equal to"),
@@ -891,8 +941,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
891
941
  return OPERATOR_ALIASES[normalized] ?? normalized;
892
942
  }
893
943
 
894
- //#endregion
895
- //#region src/filter/tree.ts
944
+ // src/filter/tree.ts
896
945
  /**
897
946
  * Creates the default empty filter: a single `and` group with no conditions.
898
947
  */
@@ -979,10 +1028,40 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
979
1028
  let arity = getOperatorArity(normalizeOperator(item.operator));
980
1029
  if (arity === "none") return true;
981
1030
  if (item.value === null || item.value === void 0 || item.value === "") return false;
982
- if (arity === "pair") return Array.isArray(item.value) && item.value.length === 2 && item.value.every((v) => v !== "" && v != null);
1031
+ if (arity === "pair") return Array.isArray(item.value) && item.value.length === 2 && item.value.every((v) => {
1032
+ let end = isRangeEnd(v) ? v.value : v;
1033
+ return end !== "" && end != null;
1034
+ });
983
1035
  if (arity === "list") return Array.isArray(item.value) && item.value.length > 0;
984
1036
  return true;
985
1037
  }
1038
+ /** Whether a range value end is a `FilterRangeEnd` rather than a plain value. */
1039
+ function isRangeEnd(value) {
1040
+ return typeof value === "object" && value !== null && !(value instanceof Date) && "valueType" in value;
1041
+ }
1042
+ /** Dynamic values the framework has no `eDynamicValue` member for. */
1043
+ const DYNAMIC_VALUES_WITHOUT_FRAMEWORK_SUPPORT = /* @__PURE__ */ new Set([
1044
+ "Now",
1045
+ "DayAfterTomorrow",
1046
+ "TwoWeeksAway"
1047
+ ]);
1048
+ function needsConversion(valueType, value) {
1049
+ if (valueType === "column") return true;
1050
+ return valueType === "special" && typeof value === "string" && DYNAMIC_VALUES_WITHOUT_FRAMEWORK_SUPPORT.has(value);
1051
+ }
1052
+ /**
1053
+ * True when the filter holds something the framework's data API cannot read
1054
+ * from a filter object: another column, a range end that is not a plain value,
1055
+ * one of the dates only the Windows editor offers, or a whole-period check. Such a filter must be
1056
+ * converted with `convertFilter` and sent as a filter string.
1057
+ */
1058
+ function needsFilterString(filter) {
1059
+ if (!filter) return false;
1060
+ if (isGroup(filter)) return filter.items.some(needsFilterString);
1061
+ if (PERIOD_OPERATORS.includes(normalizeOperator(filter.operator))) return true;
1062
+ if (needsConversion(filter.valueType, filter.value)) return true;
1063
+ return Array.isArray(filter.value) && filter.value.some((item) => isRangeEnd(item));
1064
+ }
986
1065
  /**
987
1066
  * Creates an expression for a field, using the field's default operator and an
988
1067
  * empty value of the right shape.
@@ -1013,8 +1092,9 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1013
1092
  let previousArity = getOperatorArity(normalizeOperator(expression.operator));
1014
1093
  let arity = getOperatorArity(operator);
1015
1094
  let value = expression.value;
1016
- if (arity !== previousArity) value = createEmptyValue(operator);
1017
- let valueType = expression.valueType === "special" && arity === previousArity ? "special" : getValueType(field, operator);
1095
+ let holdsColumn = expression.valueType === "column" || Array.isArray(value) && value.some((item) => isRangeEnd(item) && item.valueType === "column");
1096
+ if (arity !== previousArity || holdsColumn && !supportsColumnValue(operator)) value = createEmptyValue(operator);
1097
+ let valueType = (expression.valueType === "special" || expression.valueType === "column") && value === expression.value ? expression.valueType : getValueType(field, operator);
1018
1098
  return {
1019
1099
  ...expression,
1020
1100
  operator,
@@ -1080,8 +1160,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1080
1160
  return insertNodeAtPath(filter, path, createEmptyGroup(parent && isGroup(parent) && parent.mode === "and" ? "or" : "and"));
1081
1161
  }
1082
1162
 
1083
- //#endregion
1084
- //#region src/filter/convertFilter.ts
1163
+ // src/filter/convertFilter.ts
1085
1164
  const CONVERT_URL = "/api/filter/convert";
1086
1165
  /**
1087
1166
  * Converts between a structured filter and a DevExpress filter string.
@@ -1106,8 +1185,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1106
1185
  };
1107
1186
  }
1108
1187
 
1109
- //#endregion
1110
- //#region src/filter/describeFilter.ts
1188
+ // src/filter/describeFilter.ts
1111
1189
  /**
1112
1190
  * Builds a human-readable description of a filter, without contacting the
1113
1191
  * server. Use this for read-only summaries; the authoritative filter string is
@@ -1135,18 +1213,19 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1135
1213
  let label = getOperatorLabel(operator, field?.type);
1136
1214
  let arity = getOperatorArity(operator);
1137
1215
  if (arity === "none") return `[${caption}] ${label}`;
1138
- return `[${caption}] ${label} ${formatValue(expression, arity)}`;
1216
+ return `[${caption}] ${label} ${formatValue(expression, arity, fields)}`;
1139
1217
  }
1140
- function formatValue(expression, arity) {
1218
+ function formatValue(expression, arity, fields) {
1141
1219
  let { value, valueType } = expression;
1142
- if (valueType === "special" && typeof value === "string") return getDynamicValueLabel(value);
1143
1220
  if (Array.isArray(value)) {
1144
- let formatted = value.map((item) => formatScalar(item, valueType));
1221
+ let formatted = value.map((item) => isRangeEnd(item) ? formatScalar(item.value, item.valueType, fields) : formatScalar(item, valueType, fields));
1145
1222
  return arity === "pair" ? formatted.join(" - ") : `(${formatted.join(", ")})`;
1146
1223
  }
1147
- return formatScalar(value, valueType);
1224
+ return formatScalar(value, valueType, fields);
1148
1225
  }
1149
- function formatScalar(value, valueType) {
1226
+ function formatScalar(value, valueType, fields) {
1227
+ if (valueType === "special" && typeof value === "string") return getDynamicValueLabel(value);
1228
+ if (valueType === "column" && typeof value === "string") return `[${fields.get(value.toLowerCase())?.caption ?? value}]`;
1150
1229
  if (value === null || value === void 0) return "";
1151
1230
  if (value instanceof Date) return value.toISOString().slice(0, 10);
1152
1231
  if (typeof value === "number" || typeof value === "boolean") return String(value);
@@ -1154,8 +1233,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1154
1233
  return `'${String(value)}'`;
1155
1234
  }
1156
1235
 
1157
- //#endregion
1158
- //#region src/filter/fields.ts
1236
+ // src/filter/fields.ts
1159
1237
  const FIELD_TYPES = [
1160
1238
  "string",
1161
1239
  "number",
@@ -1190,8 +1268,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1190
1268
  return records.map(toFieldMetadata).filter((field) => field.name !== "" && !field.excludeFromFilter).sort((a, b) => a.name.localeCompare(b.name));
1191
1269
  }
1192
1270
 
1193
- //#endregion
1194
- //#region src/filter/standardLayout.ts
1271
+ // src/filter/standardLayout.ts
1195
1272
  /**
1196
1273
  * The "standard layout" is the simplified shape the Windows filter editor can
1197
1274
  * render in its flow view: an outer `or` group whose items are `and` groups of
@@ -1273,8 +1350,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1273
1350
  for (let child of item.items) collectExpressions(child, into);
1274
1351
  }
1275
1352
 
1276
- //#endregion
1277
- //#region src/filter/savedFilters.ts
1353
+ // src/filter/savedFilters.ts
1278
1354
  /**
1279
1355
  * `sviw_Database_MyFilters` unions in a synthetic "No Filter" row so the Windows
1280
1356
  * tree can render a "no filter" entry. It is not a real filter and must be
@@ -1373,8 +1449,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1373
1449
  */
1374
1450
  const canSetCrossDomain = canRenameSavedFilter;
1375
1451
 
1376
- //#endregion
1377
- //#region src/getUserImage.ts
1452
+ // src/getUserImage.ts
1378
1453
  const sizeMap = {
1379
1454
  xs: 64,
1380
1455
  sm: 128,
@@ -1389,8 +1464,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1389
1464
  return `/api/data/blob/EmployeesLookup/${primKeyOrOptions}/Image/${encodeURIComponent(login ?? "")}${login ? "." : ""}${encodeURIComponent(hash)}.jpg${sizePx ? `?width=${sizePx}` : ""}`;
1390
1465
  }
1391
1466
 
1392
- //#endregion
1393
- //#region src/localize.ts
1467
+ // src/localize.ts
1394
1468
  /**
1395
1469
  * Localization function for tagged templates. Replaces the arguments
1396
1470
  * with $n, where n is the index, before asking Appframe to translate
@@ -1414,8 +1488,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1414
1488
  return localized;
1415
1489
  }
1416
1490
 
1417
- //#endregion
1418
- //#region src/report/recordSource.ts
1491
+ // src/report/recordSource.ts
1419
1492
  const XML_ENTITIES = {
1420
1493
  amp: "&",
1421
1494
  lt: "<",
@@ -1481,14 +1554,26 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1481
1554
  return columns;
1482
1555
  }
1483
1556
  /**
1557
+ * The record source a document holds. Parameter lookups store one `<afRecordSource>`; a report
1558
+ * stores its record sources as `<ArrayOfAfReportRecordSource>` with one `<afReportRecordSource>`
1559
+ * per data source, of which the one with the ID `Master` feeds the report (else the first).
1560
+ */
1561
+ function pickRecordSource(document) {
1562
+ if (!document) return null;
1563
+ let sources = [...document.matchAll(/<(afRecordSource|afReportRecordSource)(?:\s[^>]*)?>([\s\S]*?)<\/\1>/g)].map((match) => match[2]);
1564
+ if (sources.length === 0) return null;
1565
+ return sources.find((source) => readElement(source, "ID") === "Master") ?? sources[0];
1566
+ }
1567
+ /**
1484
1568
  * Reads the parts of an `afRecordSource` a web client can act on: the view, the
1485
1569
  * selected columns and the design-time filter.
1486
1570
  *
1487
1571
  * Returns `null` for anything that is not a record source, so a missing or
1488
1572
  * empty `RecordSource` column simply means "no lookup".
1489
1573
  */
1490
- function parseRecordSource(xml) {
1491
- if (!xml || !xml.includes("<afRecordSource")) return null;
1574
+ function parseRecordSource(document) {
1575
+ let xml = pickRecordSource(document);
1576
+ if (!xml) return null;
1492
1577
  let viewName = readElement(xml, "ViewName");
1493
1578
  if (!viewName) return null;
1494
1579
  let maxRecords = readElement(xml, "MaxRecords");
@@ -1501,8 +1586,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1501
1586
  };
1502
1587
  }
1503
1588
 
1504
- //#endregion
1505
- //#region src/report/parameters.ts
1589
+ // src/report/parameters.ts
1506
1590
  /**
1507
1591
  * Report parameters: mapping the metadata records onto something renderable,
1508
1592
  * and the XML the parameter values are stored as on a saved filter.
@@ -1655,8 +1739,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1655
1739
  return values;
1656
1740
  }
1657
1741
 
1658
- //#endregion
1659
- //#region src/report/parameterDefaults.ts
1742
+ // src/report/parameterDefaults.ts
1660
1743
  /**
1661
1744
  * Resolving report parameter defaults that name a stored procedure.
1662
1745
  *
@@ -1718,8 +1801,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1718
1801
  return row;
1719
1802
  }
1720
1803
 
1721
- //#endregion
1722
- //#region src/report/render.ts
1804
+ // src/report/render.ts
1723
1805
  /**
1724
1806
  * Rendering a report through the framework's report route.
1725
1807
  *
@@ -1923,8 +2005,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1923
2005
  }));
1924
2006
  }
1925
2007
 
1926
- //#endregion
1927
- //#region src/report/report.ts
2008
+ // src/report/report.ts
1928
2009
  /**
1929
2010
  * Mapping a `sviw_WinClient_MyReports` record onto the report model, including
1930
2011
  * which output formats the report offers.
@@ -1968,8 +2049,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1968
2049
  };
1969
2050
  }
1970
2051
 
1971
- //#endregion
1972
- //#region src/alert.ts
2052
+ // src/alert.ts
1973
2053
  const template = `
1974
2054
  <dialog class="alert-dialog">
1975
2055
  <form method="dialog">
@@ -2080,8 +2160,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2080
2160
  });
2081
2161
  }
2082
2162
 
2083
- //#endregion
2084
- //#region src/settings.ts
2163
+ // src/settings.ts
2085
2164
  function getKey(article) {
2086
2165
  return `${article ?? window.af?.article?.id ?? window.window?.location.pathname.substring(1).split("/")[0]}.${window.af?.userSession.login ?? "anonymous"}`;
2087
2166
  }
@@ -2101,13 +2180,12 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2101
2180
  localStorage.setItem(key, JSON.stringify(userSettings));
2102
2181
  }
2103
2182
 
2104
- //#endregion
2105
- //#region src/index.ts
2106
- const version = "2.15.2";
2183
+ // src/index.ts
2184
+ const version = "2.16.1";
2107
2185
 
2108
- //#endregion
2109
2186
  exports.ConfirmButtons = ConfirmButtons;
2110
2187
  exports.NO_FILTER_ID = NO_FILTER_ID;
2188
+ exports.PERIOD_OPERATORS = PERIOD_OPERATORS;
2111
2189
  exports.RELATIVE_DATE_VALUES = RELATIVE_DATE_VALUES;
2112
2190
  exports.SessionHandler = SessionHandler;
2113
2191
  exports.UserSession = UserSession;
@@ -2137,6 +2215,7 @@ exports.encodeXml = encodeXml;
2137
2215
  exports.expose = expose;
2138
2216
  exports.fetchParameterDefault = fetchParameterDefault;
2139
2217
  exports.findSavedFilter = findSavedFilter;
2218
+ exports.getColumnsForField = getColumnsForField;
2140
2219
  exports.getDefaultOperator = getDefaultOperator;
2141
2220
  exports.getDefaultParameterValues = getDefaultParameterValues;
2142
2221
  exports.getDynamicValueLabel = getDynamicValueLabel;
@@ -2162,12 +2241,14 @@ exports.isEmptyFilter = isEmptyFilter;
2162
2241
  exports.isExpression = isExpression;
2163
2242
  exports.isGroup = isGroup;
2164
2243
  exports.isProcedureDefault = isProcedureDefault;
2244
+ exports.isRangeEnd = isRangeEnd;
2165
2245
  exports.isStandardLayout = isStandardLayout;
2166
2246
  exports.localStorage = localStorage_default;
2167
2247
  exports.localize = localize;
2168
2248
  exports.logActivity = logActivity;
2169
2249
  exports.logError = logError;
2170
2250
  exports.mitt = mitt_default;
2251
+ exports.needsFilterString = needsFilterString;
2171
2252
  exports.normalizeOperator = normalizeOperator;
2172
2253
  exports.openAlertDialog = openAlertDialog;
2173
2254
  exports.openReport = openReport;
@@ -2187,6 +2268,7 @@ exports.saveSettings = saveSettings;
2187
2268
  exports.serializeParameters = serializeParameters;
2188
2269
  exports.setGroupMode = setGroupMode;
2189
2270
  exports.startActivity = startActivity;
2271
+ exports.supportsColumnValue = supportsColumnValue;
2190
2272
  exports.time = time;
2191
2273
  exports.toFieldMetadata = toFieldMetadata;
2192
2274
  exports.toFieldMetadataList = toFieldMetadataList;