@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
|
@@ -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 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
490
|
-
//#region src/Namespace.ts
|
|
479
|
+
// src/Namespace.ts
|
|
491
480
|
function Namespace() {}
|
|
492
481
|
Namespace.prototype = Object.create(null);
|
|
493
482
|
|
|
494
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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) =>
|
|
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
|
-
|
|
1017
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
1491
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2105
|
-
|
|
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;
|