@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.
- package/dist/esm/af.common.js +167 -94
- package/dist/esm/af.common.legacy.js +158 -81
- package/dist/esm/af.common.legacy.min.js +3 -3
- package/dist/esm/af.common.legacy.min.js.map +1 -1
- package/dist/esm/af.common.min.js +3 -3
- package/dist/esm/af.common.min.js.map +1 -1
- package/dist/iife/af.common.js +171 -93
- package/dist/iife/af.common.legacy.js +162 -80
- package/dist/iife/af.common.legacy.min.js +3 -3
- package/dist/iife/af.common.legacy.min.js.map +1 -1
- package/dist/iife/af.common.min.js +3 -3
- package/dist/iife/af.common.min.js.map +1 -1
- package/es/filter/columnValues.test.d.ts +1 -0
- package/es/filter/columnValues.test.js +119 -0
- package/es/filter/describeFilter.js +11 -9
- package/es/filter/index.d.ts +3 -3
- package/es/filter/index.js +2 -2
- package/es/filter/operators.d.ts +14 -0
- package/es/filter/operators.js +63 -3
- package/es/filter/tree.d.ts +10 -1
- package/es/filter/tree.js +43 -5
- package/es/filter/types.d.ts +27 -6
- package/es/index.js +1 -1
- package/es/report/recordSource.d.ts +1 -1
- package/es/report/recordSource.js +16 -2
- package/es/report/report.test.js +36 -0
- package/package.json +6 -4
- package/src/filter/columnValues.test.ts +164 -0
- package/src/filter/describeFilter.ts +16 -10
- package/src/filter/index.ts +6 -0
- package/src/filter/operators.ts +74 -3
- package/src/filter/tree.ts +64 -7
- package/src/filter/types.ts +43 -4
- package/src/report/recordSource.ts +17 -2
- package/src/report/report.test.ts +39 -0
package/dist/iife/af.common.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
40
|
-
|
|
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
|
|
44
|
-
if (void 0 !==
|
|
45
|
-
var i =
|
|
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" ===
|
|
47
|
+
return ("string" === e ? String : Number)(t);
|
|
50
48
|
}
|
|
51
49
|
|
|
52
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
536
|
-
//#region src/Namespace.ts
|
|
521
|
+
// src/Namespace.ts
|
|
537
522
|
function Namespace() {}
|
|
538
523
|
Namespace.prototype = Object.create(null);
|
|
539
524
|
|
|
540
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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) =>
|
|
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
|
-
|
|
1063
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
1537
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2151
|
-
|
|
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;
|