@olenbetong/appframe-core 2.15.1 → 2.16.0
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 +174 -88
- package/dist/esm/af.common.legacy.js +170 -80
- 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 +178 -87
- package/dist/iife/af.common.legacy.js +174 -79
- 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/log.js +32 -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/log.ts +34 -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.150.0/helpers/esm/typeof.js
|
|
28
|
+
// \0@oxc-project+runtime@0.155.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,8 +35,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
36
35
|
}, _typeof(o);
|
|
37
36
|
}
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
//#region \0@oxc-project+runtime@0.150.0/helpers/esm/toPrimitive.js
|
|
38
|
+
// \0@oxc-project+runtime@0.155.0/helpers/esm/toPrimitive.js
|
|
41
39
|
function toPrimitive(t, r) {
|
|
42
40
|
if ("object" != _typeof(t) || !t) return t;
|
|
43
41
|
var e = t[Symbol.toPrimitive];
|
|
@@ -49,15 +47,13 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
49
47
|
return ("string" === r ? String : Number)(t);
|
|
50
48
|
}
|
|
51
49
|
|
|
52
|
-
|
|
53
|
-
//#region \0@oxc-project+runtime@0.150.0/helpers/esm/toPropertyKey.js
|
|
50
|
+
// \0@oxc-project+runtime@0.155.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.150.0/helpers/esm/defineProperty.js
|
|
56
|
+
// \0@oxc-project+runtime@0.155.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
|
|
@@ -267,6 +260,30 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
267
260
|
function getSessionId() {
|
|
268
261
|
return crypto.randomUUID?.();
|
|
269
262
|
}
|
|
263
|
+
/** The version in the first URL served under `/lib/@olenbetong/<name>/<version>/`. */
|
|
264
|
+
function libVersion(name, urls) {
|
|
265
|
+
let pattern = new RegExp(`/lib/@olenbetong/${name}/([^/]+)/`);
|
|
266
|
+
for (let url of urls) {
|
|
267
|
+
let match = typeof url === "string" ? pattern.exec(url) : null;
|
|
268
|
+
if (match) return match[1];
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* The synergi-chrome and synergi-platform versions the page loads on the 2026 site templates,
|
|
273
|
+
* read from the chrome's script tag and the platform import map rather than from the chrome
|
|
274
|
+
* itself, so they are known even when the chrome failed to start. Empty on other pages.
|
|
275
|
+
*/
|
|
276
|
+
function getPlatformVersions() {
|
|
277
|
+
let versions = {};
|
|
278
|
+
try {
|
|
279
|
+
let importMap = document.querySelector("script[type=\"importmap\"]");
|
|
280
|
+
let platform = importMap ? libVersion("synergi-platform", Object.values(JSON.parse(importMap.textContent ?? "{}").imports ?? {})) : void 0;
|
|
281
|
+
if (platform) versions["synergi-platform"] = platform;
|
|
282
|
+
} catch {}
|
|
283
|
+
let chrome = libVersion("synergi-chrome", Array.from(document.scripts, (script) => script.src)) ?? window.ob?.chrome?.version;
|
|
284
|
+
if (chrome) versions["synergi-chrome"] = chrome;
|
|
285
|
+
return versions;
|
|
286
|
+
}
|
|
270
287
|
let sessionStart = Date.now();
|
|
271
288
|
let sessionId = getSessionId();
|
|
272
289
|
let deviceId = "";
|
|
@@ -275,7 +292,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
275
292
|
let startSession = () => logActivity("AfSessionInit", {
|
|
276
293
|
"appframe-core": window.af?.common?.version,
|
|
277
294
|
"appframe-data": window.af?.data?.version,
|
|
278
|
-
"app-version": window.af?.article?.version
|
|
295
|
+
"app-version": window.af?.article?.version,
|
|
296
|
+
...getPlatformVersions()
|
|
279
297
|
});
|
|
280
298
|
document.addEventListener("DOMContentLoaded", () => {
|
|
281
299
|
deviceId = localStorage.getItem("_afDeviceId");
|
|
@@ -309,15 +327,13 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
309
327
|
};
|
|
310
328
|
}
|
|
311
329
|
|
|
312
|
-
|
|
313
|
-
//#region src/errorHandler.ts
|
|
330
|
+
// src/errorHandler.ts
|
|
314
331
|
window.window?.addEventListener("error", (event) => {
|
|
315
332
|
if (typeof event === "object" && "error" in event) logError(event.error);
|
|
316
333
|
else if (typeof event === "object" && "message" in event) logError(event);
|
|
317
334
|
});
|
|
318
335
|
|
|
319
|
-
|
|
320
|
-
//#region src/localStorage.ts
|
|
336
|
+
// src/localStorage.ts
|
|
321
337
|
function getLocalKey(key) {
|
|
322
338
|
return [
|
|
323
339
|
af?.article?.id || "",
|
|
@@ -354,8 +370,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
354
370
|
};
|
|
355
371
|
var localStorage_default = new LocalStorage();
|
|
356
372
|
|
|
357
|
-
|
|
358
|
-
//#region src/date.ts
|
|
373
|
+
// src/date.ts
|
|
359
374
|
function toLocalISODate(date) {
|
|
360
375
|
return date ? toLocalISODateTime(date).substring(0, 10) : null;
|
|
361
376
|
}
|
|
@@ -378,8 +393,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
378
393
|
return date ? date.toISOString().substring(0, 16) : "";
|
|
379
394
|
}
|
|
380
395
|
|
|
381
|
-
|
|
382
|
-
//#region src/downloadBlob.ts
|
|
396
|
+
// src/downloadBlob.ts
|
|
383
397
|
function downloadBlob(blob, fileName) {
|
|
384
398
|
return new Promise((resolve, reject) => {
|
|
385
399
|
try {
|
|
@@ -401,8 +415,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
401
415
|
});
|
|
402
416
|
}
|
|
403
417
|
|
|
404
|
-
|
|
405
|
-
//#region src/invariant.ts
|
|
418
|
+
// src/invariant.ts
|
|
406
419
|
/**
|
|
407
420
|
* Throws an error if the condition is falsy. The provided message is used as the error message.
|
|
408
421
|
* A function can be provided to lazily generate the message.
|
|
@@ -417,8 +430,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
417
430
|
throw new Error(provided ?? "Invariant failed");
|
|
418
431
|
}
|
|
419
432
|
|
|
420
|
-
|
|
421
|
-
//#region src/downloadRequest.ts
|
|
433
|
+
// src/downloadRequest.ts
|
|
422
434
|
async function downloadRequest(request, { fileName, signal, onProgress }) {
|
|
423
435
|
let bytesReceived = 0;
|
|
424
436
|
onProgress?.({ status: "requested" });
|
|
@@ -472,8 +484,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
472
484
|
}
|
|
473
485
|
}
|
|
474
486
|
|
|
475
|
-
|
|
476
|
-
//#region src/parseFunc.ts
|
|
487
|
+
// src/parseFunc.ts
|
|
477
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)*)\}$/;
|
|
478
489
|
const arrowBlockRegex = /^(?:\(([^)]*)\)|([a-zA-Z$_][a-zA-Z0-9$_]*))\s*=>\s*\{([\s\S]*)\}$/;
|
|
479
490
|
const arrowExpressionRegex = /^(?:\(([^)]*)\)|([a-zA-Z$_][a-zA-Z0-9$_]*))\s*=>\s*([\s\S]+)$/;
|
|
@@ -507,13 +518,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
507
518
|
};
|
|
508
519
|
}
|
|
509
520
|
|
|
510
|
-
|
|
511
|
-
//#region src/Namespace.ts
|
|
521
|
+
// src/Namespace.ts
|
|
512
522
|
function Namespace() {}
|
|
513
523
|
Namespace.prototype = Object.create(null);
|
|
514
524
|
|
|
515
|
-
|
|
516
|
-
//#region src/requireNamespace.ts
|
|
525
|
+
// src/requireNamespace.ts
|
|
517
526
|
function requireNamespace(root, namespace) {
|
|
518
527
|
if (typeof root === "object") {
|
|
519
528
|
if (typeof namespace === "string") return requireNamespace(root, namespace.split("."));
|
|
@@ -525,8 +534,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
525
534
|
}
|
|
526
535
|
}
|
|
527
536
|
|
|
528
|
-
|
|
529
|
-
//#region src/expose.ts
|
|
537
|
+
// src/expose.ts
|
|
530
538
|
/**
|
|
531
539
|
* Expose a value to a potentially deeply nested global variable
|
|
532
540
|
* @param name {string | object} Either a dot-separated path to the global variable, or an object to expose the value on
|
|
@@ -556,8 +564,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
556
564
|
}
|
|
557
565
|
}
|
|
558
566
|
|
|
559
|
-
|
|
560
|
-
//#region src/getLocalizedString.ts
|
|
567
|
+
// src/getLocalizedString.ts
|
|
561
568
|
async function fetchLocalizedString(text, project) {
|
|
562
569
|
try {
|
|
563
570
|
let response = await fetch(`/api/user/localize/new/${encodeURIComponent(project)}`, {
|
|
@@ -646,8 +653,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
646
653
|
};
|
|
647
654
|
}
|
|
648
655
|
|
|
649
|
-
|
|
650
|
-
//#region src/filter/operators.ts
|
|
656
|
+
// src/filter/operators.ts
|
|
651
657
|
/**
|
|
652
658
|
* Operators that take no value at all.
|
|
653
659
|
*
|
|
@@ -661,6 +667,26 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
661
667
|
"isblank",
|
|
662
668
|
"isnotblank"
|
|
663
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
|
+
];
|
|
664
690
|
/** Operators whose value is a two element `[from, to]` array. */
|
|
665
691
|
const PAIR_OPERATORS = [
|
|
666
692
|
"between",
|
|
@@ -671,7 +697,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
671
697
|
/** Operators whose value is an array of values. */
|
|
672
698
|
const LIST_OPERATORS = ["inlist", "notinlist"];
|
|
673
699
|
function getOperatorArity(operator) {
|
|
674
|
-
if (PARAMETERLESS_OPERATORS.includes(operator)) return "none";
|
|
700
|
+
if (PARAMETERLESS_OPERATORS.includes(operator) || PERIOD_OPERATORS.includes(operator)) return "none";
|
|
675
701
|
if (PAIR_OPERATORS.includes(operator)) return "pair";
|
|
676
702
|
if (LIST_OPERATORS.includes(operator)) return "list";
|
|
677
703
|
return "single";
|
|
@@ -714,7 +740,20 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
714
740
|
datelessthan: "Before",
|
|
715
741
|
datelessthanorequal: "Up to",
|
|
716
742
|
datebetween: "Between",
|
|
717
|
-
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"
|
|
718
757
|
};
|
|
719
758
|
/** Comparison operator labels used for date and time fields. */
|
|
720
759
|
const DATE_OPERATOR_LABELS = {
|
|
@@ -759,13 +798,15 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
759
798
|
...EQUALITY,
|
|
760
799
|
...LIST_CHECKS,
|
|
761
800
|
...RANGE,
|
|
762
|
-
...COMPARISONS
|
|
801
|
+
...COMPARISONS,
|
|
802
|
+
...PERIOD_OPERATORS
|
|
763
803
|
],
|
|
764
804
|
datetime: [
|
|
765
805
|
...EQUALITY,
|
|
766
806
|
...LIST_CHECKS,
|
|
767
807
|
...RANGE,
|
|
768
|
-
...COMPARISONS
|
|
808
|
+
...COMPARISONS,
|
|
809
|
+
...PERIOD_OPERATORS
|
|
769
810
|
],
|
|
770
811
|
number: [
|
|
771
812
|
...EQUALITY,
|
|
@@ -838,7 +879,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
838
879
|
const RELATIVE_DATE_VALUES = [
|
|
839
880
|
"Yesterday",
|
|
840
881
|
"Today",
|
|
882
|
+
"Now",
|
|
841
883
|
"Tomorrow",
|
|
884
|
+
"DayAfterTomorrow",
|
|
885
|
+
"TwoWeeksAway",
|
|
842
886
|
"ThisWeek",
|
|
843
887
|
"ThisMonth",
|
|
844
888
|
"ThisYear",
|
|
@@ -853,7 +897,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
853
897
|
CurrentUser: "Current user",
|
|
854
898
|
Yesterday: "Yesterday",
|
|
855
899
|
Today: "Today",
|
|
900
|
+
Now: "Now",
|
|
856
901
|
Tomorrow: "Tomorrow",
|
|
902
|
+
DayAfterTomorrow: "Day after tomorrow",
|
|
903
|
+
TwoWeeksAway: "Two weeks away",
|
|
857
904
|
ThisWeek: "This week",
|
|
858
905
|
ThisMonth: "This month",
|
|
859
906
|
ThisYear: "This year",
|
|
@@ -889,6 +936,30 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
889
936
|
if (field.type === "string") return ["CurrentUser"];
|
|
890
937
|
return [];
|
|
891
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
|
+
}
|
|
892
963
|
/**
|
|
893
964
|
* Aliases for names `eOperators.ToString()` can produce that are not operators
|
|
894
965
|
* in their own right. `Not` is the bare negation flag (i.e. "not equal to"),
|
|
@@ -912,8 +983,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
912
983
|
return OPERATOR_ALIASES[normalized] ?? normalized;
|
|
913
984
|
}
|
|
914
985
|
|
|
915
|
-
|
|
916
|
-
//#region src/filter/tree.ts
|
|
986
|
+
// src/filter/tree.ts
|
|
917
987
|
/**
|
|
918
988
|
* Creates the default empty filter: a single `and` group with no conditions.
|
|
919
989
|
*/
|
|
@@ -1000,10 +1070,40 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
1000
1070
|
let arity = getOperatorArity(normalizeOperator(item.operator));
|
|
1001
1071
|
if (arity === "none") return true;
|
|
1002
1072
|
if (item.value === null || item.value === void 0 || item.value === "") return false;
|
|
1003
|
-
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
|
+
});
|
|
1004
1077
|
if (arity === "list") return Array.isArray(item.value) && item.value.length > 0;
|
|
1005
1078
|
return true;
|
|
1006
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
|
+
}
|
|
1007
1107
|
/**
|
|
1008
1108
|
* Creates an expression for a field, using the field's default operator and an
|
|
1009
1109
|
* empty value of the right shape.
|
|
@@ -1034,8 +1134,9 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
1034
1134
|
let previousArity = getOperatorArity(normalizeOperator(expression.operator));
|
|
1035
1135
|
let arity = getOperatorArity(operator);
|
|
1036
1136
|
let value = expression.value;
|
|
1037
|
-
|
|
1038
|
-
|
|
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);
|
|
1039
1140
|
return {
|
|
1040
1141
|
...expression,
|
|
1041
1142
|
operator,
|
|
@@ -1101,8 +1202,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
1101
1202
|
return insertNodeAtPath(filter, path, createEmptyGroup(parent && isGroup(parent) && parent.mode === "and" ? "or" : "and"));
|
|
1102
1203
|
}
|
|
1103
1204
|
|
|
1104
|
-
|
|
1105
|
-
//#region src/filter/convertFilter.ts
|
|
1205
|
+
// src/filter/convertFilter.ts
|
|
1106
1206
|
const CONVERT_URL = "/api/filter/convert";
|
|
1107
1207
|
/**
|
|
1108
1208
|
* Converts between a structured filter and a DevExpress filter string.
|
|
@@ -1127,8 +1227,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
1127
1227
|
};
|
|
1128
1228
|
}
|
|
1129
1229
|
|
|
1130
|
-
|
|
1131
|
-
//#region src/filter/describeFilter.ts
|
|
1230
|
+
// src/filter/describeFilter.ts
|
|
1132
1231
|
/**
|
|
1133
1232
|
* Builds a human-readable description of a filter, without contacting the
|
|
1134
1233
|
* server. Use this for read-only summaries; the authoritative filter string is
|
|
@@ -1156,18 +1255,19 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
1156
1255
|
let label = getOperatorLabel(operator, field?.type);
|
|
1157
1256
|
let arity = getOperatorArity(operator);
|
|
1158
1257
|
if (arity === "none") return `[${caption}] ${label}`;
|
|
1159
|
-
return `[${caption}] ${label} ${formatValue(expression, arity)}`;
|
|
1258
|
+
return `[${caption}] ${label} ${formatValue(expression, arity, fields)}`;
|
|
1160
1259
|
}
|
|
1161
|
-
function formatValue(expression, arity) {
|
|
1260
|
+
function formatValue(expression, arity, fields) {
|
|
1162
1261
|
let { value, valueType } = expression;
|
|
1163
|
-
if (valueType === "special" && typeof value === "string") return getDynamicValueLabel(value);
|
|
1164
1262
|
if (Array.isArray(value)) {
|
|
1165
|
-
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));
|
|
1166
1264
|
return arity === "pair" ? formatted.join(" - ") : `(${formatted.join(", ")})`;
|
|
1167
1265
|
}
|
|
1168
|
-
return formatScalar(value, valueType);
|
|
1266
|
+
return formatScalar(value, valueType, fields);
|
|
1169
1267
|
}
|
|
1170
|
-
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}]`;
|
|
1171
1271
|
if (value === null || value === void 0) return "";
|
|
1172
1272
|
if (value instanceof Date) return value.toISOString().slice(0, 10);
|
|
1173
1273
|
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
@@ -1175,8 +1275,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
1175
1275
|
return `'${String(value)}'`;
|
|
1176
1276
|
}
|
|
1177
1277
|
|
|
1178
|
-
|
|
1179
|
-
//#region src/filter/fields.ts
|
|
1278
|
+
// src/filter/fields.ts
|
|
1180
1279
|
const FIELD_TYPES = [
|
|
1181
1280
|
"string",
|
|
1182
1281
|
"number",
|
|
@@ -1211,8 +1310,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
1211
1310
|
return records.map(toFieldMetadata).filter((field) => field.name !== "" && !field.excludeFromFilter).sort((a, b) => a.name.localeCompare(b.name));
|
|
1212
1311
|
}
|
|
1213
1312
|
|
|
1214
|
-
|
|
1215
|
-
//#region src/filter/standardLayout.ts
|
|
1313
|
+
// src/filter/standardLayout.ts
|
|
1216
1314
|
/**
|
|
1217
1315
|
* The "standard layout" is the simplified shape the Windows filter editor can
|
|
1218
1316
|
* render in its flow view: an outer `or` group whose items are `and` groups of
|
|
@@ -1294,8 +1392,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
1294
1392
|
for (let child of item.items) collectExpressions(child, into);
|
|
1295
1393
|
}
|
|
1296
1394
|
|
|
1297
|
-
|
|
1298
|
-
//#region src/filter/savedFilters.ts
|
|
1395
|
+
// src/filter/savedFilters.ts
|
|
1299
1396
|
/**
|
|
1300
1397
|
* `sviw_Database_MyFilters` unions in a synthetic "No Filter" row so the Windows
|
|
1301
1398
|
* tree can render a "no filter" entry. It is not a real filter and must be
|
|
@@ -1394,8 +1491,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
1394
1491
|
*/
|
|
1395
1492
|
const canSetCrossDomain = canRenameSavedFilter;
|
|
1396
1493
|
|
|
1397
|
-
|
|
1398
|
-
//#region src/getUserImage.ts
|
|
1494
|
+
// src/getUserImage.ts
|
|
1399
1495
|
const sizeMap = {
|
|
1400
1496
|
xs: 64,
|
|
1401
1497
|
sm: 128,
|
|
@@ -1410,8 +1506,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
1410
1506
|
return `/api/data/blob/EmployeesLookup/${primKeyOrOptions}/Image/${encodeURIComponent(login ?? "")}${login ? "." : ""}${encodeURIComponent(hash)}.jpg${sizePx ? `?width=${sizePx}` : ""}`;
|
|
1411
1507
|
}
|
|
1412
1508
|
|
|
1413
|
-
|
|
1414
|
-
//#region src/localize.ts
|
|
1509
|
+
// src/localize.ts
|
|
1415
1510
|
/**
|
|
1416
1511
|
* Localization function for tagged templates. Replaces the arguments
|
|
1417
1512
|
* with $n, where n is the index, before asking Appframe to translate
|
|
@@ -1435,8 +1530,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
1435
1530
|
return localized;
|
|
1436
1531
|
}
|
|
1437
1532
|
|
|
1438
|
-
|
|
1439
|
-
//#region src/report/recordSource.ts
|
|
1533
|
+
// src/report/recordSource.ts
|
|
1440
1534
|
const XML_ENTITIES = {
|
|
1441
1535
|
amp: "&",
|
|
1442
1536
|
lt: "<",
|
|
@@ -1522,8 +1616,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
1522
1616
|
};
|
|
1523
1617
|
}
|
|
1524
1618
|
|
|
1525
|
-
|
|
1526
|
-
//#region src/report/parameters.ts
|
|
1619
|
+
// src/report/parameters.ts
|
|
1527
1620
|
/**
|
|
1528
1621
|
* Report parameters: mapping the metadata records onto something renderable,
|
|
1529
1622
|
* and the XML the parameter values are stored as on a saved filter.
|
|
@@ -1676,8 +1769,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
1676
1769
|
return values;
|
|
1677
1770
|
}
|
|
1678
1771
|
|
|
1679
|
-
|
|
1680
|
-
//#region src/report/parameterDefaults.ts
|
|
1772
|
+
// src/report/parameterDefaults.ts
|
|
1681
1773
|
/**
|
|
1682
1774
|
* Resolving report parameter defaults that name a stored procedure.
|
|
1683
1775
|
*
|
|
@@ -1739,8 +1831,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
1739
1831
|
return row;
|
|
1740
1832
|
}
|
|
1741
1833
|
|
|
1742
|
-
|
|
1743
|
-
//#region src/report/render.ts
|
|
1834
|
+
// src/report/render.ts
|
|
1744
1835
|
/**
|
|
1745
1836
|
* Rendering a report through the framework's report route.
|
|
1746
1837
|
*
|
|
@@ -1944,8 +2035,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
1944
2035
|
}));
|
|
1945
2036
|
}
|
|
1946
2037
|
|
|
1947
|
-
|
|
1948
|
-
//#region src/report/report.ts
|
|
2038
|
+
// src/report/report.ts
|
|
1949
2039
|
/**
|
|
1950
2040
|
* Mapping a `sviw_WinClient_MyReports` record onto the report model, including
|
|
1951
2041
|
* which output formats the report offers.
|
|
@@ -1989,8 +2079,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
1989
2079
|
};
|
|
1990
2080
|
}
|
|
1991
2081
|
|
|
1992
|
-
|
|
1993
|
-
//#region src/alert.ts
|
|
2082
|
+
// src/alert.ts
|
|
1994
2083
|
const template = `
|
|
1995
2084
|
<dialog class="alert-dialog">
|
|
1996
2085
|
<form method="dialog">
|
|
@@ -2101,8 +2190,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2101
2190
|
});
|
|
2102
2191
|
}
|
|
2103
2192
|
|
|
2104
|
-
|
|
2105
|
-
//#region src/settings.ts
|
|
2193
|
+
// src/settings.ts
|
|
2106
2194
|
function getKey(article) {
|
|
2107
2195
|
return `${article ?? window.af?.article?.id ?? window.window?.location.pathname.substring(1).split("/")[0]}.${window.af?.userSession.login ?? "anonymous"}`;
|
|
2108
2196
|
}
|
|
@@ -2122,13 +2210,12 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2122
2210
|
localStorage.setItem(key, JSON.stringify(userSettings));
|
|
2123
2211
|
}
|
|
2124
2212
|
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
const version = "2.15.1";
|
|
2213
|
+
// src/index.ts
|
|
2214
|
+
const version = "2.15.2";
|
|
2128
2215
|
|
|
2129
|
-
//#endregion
|
|
2130
2216
|
exports.ConfirmButtons = ConfirmButtons;
|
|
2131
2217
|
exports.NO_FILTER_ID = NO_FILTER_ID;
|
|
2218
|
+
exports.PERIOD_OPERATORS = PERIOD_OPERATORS;
|
|
2132
2219
|
exports.RELATIVE_DATE_VALUES = RELATIVE_DATE_VALUES;
|
|
2133
2220
|
exports.SessionHandler = SessionHandler;
|
|
2134
2221
|
exports.UserSession = UserSession;
|
|
@@ -2158,6 +2245,7 @@ exports.encodeXml = encodeXml;
|
|
|
2158
2245
|
exports.expose = expose;
|
|
2159
2246
|
exports.fetchParameterDefault = fetchParameterDefault;
|
|
2160
2247
|
exports.findSavedFilter = findSavedFilter;
|
|
2248
|
+
exports.getColumnsForField = getColumnsForField;
|
|
2161
2249
|
exports.getDefaultOperator = getDefaultOperator;
|
|
2162
2250
|
exports.getDefaultParameterValues = getDefaultParameterValues;
|
|
2163
2251
|
exports.getDynamicValueLabel = getDynamicValueLabel;
|
|
@@ -2183,12 +2271,14 @@ exports.isEmptyFilter = isEmptyFilter;
|
|
|
2183
2271
|
exports.isExpression = isExpression;
|
|
2184
2272
|
exports.isGroup = isGroup;
|
|
2185
2273
|
exports.isProcedureDefault = isProcedureDefault;
|
|
2274
|
+
exports.isRangeEnd = isRangeEnd;
|
|
2186
2275
|
exports.isStandardLayout = isStandardLayout;
|
|
2187
2276
|
exports.localStorage = localStorage_default;
|
|
2188
2277
|
exports.localize = localize;
|
|
2189
2278
|
exports.logActivity = logActivity;
|
|
2190
2279
|
exports.logError = logError;
|
|
2191
2280
|
exports.mitt = mitt_default;
|
|
2281
|
+
exports.needsFilterString = needsFilterString;
|
|
2192
2282
|
exports.normalizeOperator = normalizeOperator;
|
|
2193
2283
|
exports.openAlertDialog = openAlertDialog;
|
|
2194
2284
|
exports.openReport = openReport;
|
|
@@ -2208,6 +2298,7 @@ exports.saveSettings = saveSettings;
|
|
|
2208
2298
|
exports.serializeParameters = serializeParameters;
|
|
2209
2299
|
exports.setGroupMode = setGroupMode;
|
|
2210
2300
|
exports.startActivity = startActivity;
|
|
2301
|
+
exports.supportsColumnValue = supportsColumnValue;
|
|
2211
2302
|
exports.time = time;
|
|
2212
2303
|
exports.toFieldMetadata = toFieldMetadata;
|
|
2213
2304
|
exports.toFieldMetadataList = toFieldMetadataList;
|