@openmrs/esm-form-engine-lib 2.1.0-pre.1510 → 2.1.0-pre.1513
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/__mocks__/forms/rfe-forms/bmi-test-form.json +66 -66
- package/__mocks__/forms/rfe-forms/bsa-test-form.json +66 -66
- package/__mocks__/forms/rfe-forms/edd-test-form.json +87 -87
- package/__mocks__/forms/rfe-forms/external_data_source_form.json +35 -36
- package/__mocks__/forms/rfe-forms/historical-expressions-form.json +1 -1
- package/__mocks__/forms/rfe-forms/labour_and_delivery_test_form.json +1 -1
- package/__mocks__/forms/rfe-forms/months-on-art-form.json +89 -89
- package/__mocks__/forms/rfe-forms/next-visit-test-form.json +77 -77
- package/dist/openmrs-esm-form-engine-lib.js +1 -1
- package/package.json +1 -1
- package/src/components/inputs/multi-select/multi-select.component.tsx +3 -3
- package/src/components/inputs/number/number.component.tsx +2 -1
- package/src/components/inputs/ui-select-extended/ui-select-extended.component.tsx +1 -1
- package/src/components/inputs/ui-select-extended/ui-select-extended.test.tsx +5 -0
- package/src/processors/encounter/encounter-form-processor.ts +2 -7
- package/src/utils/common-expression-helpers.test.ts +74 -5
- package/src/utils/common-expression-helpers.ts +21 -26
- package/src/utils/expression-runner.test.ts +156 -69
- package/src/utils/expression-runner.ts +85 -135
- package/src/utils/expression-parser.test.ts +0 -308
- package/src/utils/expression-parser.ts +0 -158
@@ -1,90 +1,90 @@
|
|
1
1
|
{
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
}
|
2
|
+
"name": "",
|
3
|
+
"pages": [
|
4
|
+
{
|
5
|
+
"label": "POC Test months on ART",
|
6
|
+
"sections": [
|
7
|
+
{
|
8
|
+
"label": "Test months on ART",
|
9
|
+
"isExpanded": "true",
|
10
|
+
"questions": [
|
11
|
+
{
|
12
|
+
"label": "Antiretroviral treatment start date",
|
13
|
+
"type": "obs",
|
14
|
+
"questionOptions": {
|
15
|
+
"rendering": "date",
|
16
|
+
"weeksList": "",
|
17
|
+
"concept": "159599AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
18
|
+
"conceptMappings": [
|
19
|
+
{
|
20
|
+
"type": "PIH",
|
21
|
+
"value": "2516"
|
22
|
+
},
|
23
|
+
{
|
24
|
+
"type": "PIH-Malawi",
|
25
|
+
"value": "2516"
|
26
|
+
},
|
27
|
+
{
|
28
|
+
"type": "SNOMED-MVP",
|
29
|
+
"value": "1595991000105005"
|
30
|
+
},
|
31
|
+
{
|
32
|
+
"type": "CIEL",
|
33
|
+
"value": "159599"
|
34
|
+
}
|
35
|
+
]
|
36
|
+
},
|
37
|
+
"id": "artStartDate"
|
38
|
+
},
|
39
|
+
{
|
40
|
+
"label": "Months on ART",
|
41
|
+
"type": "obs",
|
42
|
+
"questionOptions": {
|
43
|
+
"rendering": "number",
|
44
|
+
"calculate": {
|
45
|
+
"calculateExpression": "calcMonthsOnART(artStartDate)"
|
46
|
+
},
|
47
|
+
"concept": "159368AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
48
|
+
"conceptMappings": [
|
49
|
+
{
|
50
|
+
"type": "CIEL",
|
51
|
+
"value": "159368"
|
52
|
+
},
|
53
|
+
{
|
54
|
+
"type": "AMPATH",
|
55
|
+
"value": "1897"
|
56
|
+
},
|
57
|
+
{
|
58
|
+
"type": "SNOMED-CT",
|
59
|
+
"value": "261774000"
|
60
|
+
},
|
61
|
+
{
|
62
|
+
"type": "SNOMED-CT",
|
63
|
+
"value": "261774000"
|
64
|
+
},
|
65
|
+
{
|
66
|
+
"type": "AMPATH",
|
67
|
+
"value": "1897"
|
68
|
+
},
|
69
|
+
{
|
70
|
+
"type": "CIEL",
|
71
|
+
"value": "159368"
|
72
|
+
}
|
73
|
+
],
|
74
|
+
"max": "",
|
75
|
+
"min": "",
|
76
|
+
"showDate": ""
|
77
|
+
},
|
78
|
+
"id": "monthsOnART"
|
79
|
+
}
|
80
|
+
]
|
81
|
+
}
|
82
|
+
]
|
83
|
+
}
|
84
|
+
],
|
85
|
+
"availableIntents": [],
|
86
|
+
"processor": "EncounterFormProcessor",
|
87
|
+
"uuid": "da24c540-cc83-43bc-978f-c1ef180a497f",
|
88
|
+
"referencedForms": [],
|
89
|
+
"encounterType": "79c1f50f-f77d-42e2-ad2a-d29304dde2fe"
|
90
|
+
}
|
@@ -1,78 +1,78 @@
|
|
1
1
|
{
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
}
|
2
|
+
"name": "",
|
3
|
+
"pages": [
|
4
|
+
{
|
5
|
+
"label": "Test Next Visit Calculation",
|
6
|
+
"sections": [
|
7
|
+
{
|
8
|
+
"label": "Test Next Visit",
|
9
|
+
"isExpanded": "true",
|
10
|
+
"questions": [
|
11
|
+
{
|
12
|
+
"label": "Followup Date",
|
13
|
+
"type": "obs",
|
14
|
+
"questionOptions": {
|
15
|
+
"rendering": "date",
|
16
|
+
"concept": "163137AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
17
|
+
"weeksList": ""
|
18
|
+
},
|
19
|
+
"id": "followupDate"
|
20
|
+
},
|
21
|
+
{
|
22
|
+
"label": "ARV dispensed in days",
|
23
|
+
"type": "obs",
|
24
|
+
"questionOptions": {
|
25
|
+
"rendering": "number",
|
26
|
+
"concept": "3a0709e9-d7a8-44b9-9512-111db5ce3989",
|
27
|
+
"max": "",
|
28
|
+
"min": "",
|
29
|
+
"showDate": ""
|
30
|
+
},
|
31
|
+
"id": "arvDispensedInDays"
|
32
|
+
},
|
33
|
+
{
|
34
|
+
"label": "Next visit date",
|
35
|
+
"type": "obs",
|
36
|
+
"questionOptions": {
|
37
|
+
"rendering": "date",
|
38
|
+
"calculate": {
|
39
|
+
"calculateExpression": "calcNextVisitDate(followupDate, arvDispensedInDays)"
|
40
|
+
},
|
41
|
+
"concept": "5096AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
42
|
+
"weeksList": "",
|
43
|
+
"conceptMappings": [
|
44
|
+
{
|
45
|
+
"type": "SNOMED-MVP",
|
46
|
+
"value": "50961000105000"
|
47
|
+
},
|
48
|
+
{
|
49
|
+
"type": "AMPATH",
|
50
|
+
"value": "5096"
|
51
|
+
},
|
52
|
+
{
|
53
|
+
"type": "org.openmrs.module.mdrtb",
|
54
|
+
"value": "RETURN VISIT DATE"
|
55
|
+
},
|
56
|
+
{
|
57
|
+
"type": "PIH-Malawi",
|
58
|
+
"value": "5096"
|
59
|
+
},
|
60
|
+
{
|
61
|
+
"type": "CIEL",
|
62
|
+
"value": "5096"
|
63
|
+
}
|
64
|
+
]
|
65
|
+
},
|
66
|
+
"id": "nextVisitDate"
|
67
|
+
}
|
68
|
+
]
|
69
|
+
}
|
70
|
+
]
|
71
|
+
}
|
72
|
+
],
|
73
|
+
"availableIntents": [],
|
74
|
+
"processor": "EncounterFormProcessor",
|
75
|
+
"uuid": "da24c540-cc83-43bc-978f-c1ef180a497f",
|
76
|
+
"referencedForms": [],
|
77
|
+
"encounterType": "79c1f50f-f77d-42e2-ad2a-d29304dde2fe"
|
78
|
+
}
|
@@ -1 +1 @@
|
|
1
|
-
var _openmrs_esm_form_engine_lib;(()=>{"use strict";var e,r,t,n,o,i,a,l,s,u,f,p,d,c,h,m,v,g,b={8008:(e,r,t)=>{var n={"./start":()=>Promise.all([t.e(901),t.e(420),t.e(72),t.e(385),t.e(
|
1
|
+
var _openmrs_esm_form_engine_lib;(()=>{"use strict";var e,r,t,n,o,i,a,l,s,u,f,p,d,c,h,m,v,g,b={8008:(e,r,t)=>{var n={"./start":()=>Promise.all([t.e(901),t.e(420),t.e(72),t.e(385),t.e(751)]).then((()=>()=>t(6751)))},o=(e,r)=>(t.R=r,r=t.o(n,e)?n[e]():Promise.resolve().then((()=>{throw new Error('Module "'+e+'" does not exist in container.')})),t.R=void 0,r),i=(e,r)=>{if(t.S){var n="default",o=t.S[n];if(o&&o!==e)throw new Error("Container initialization failed as it has already been initialized with a different share scope");return t.S[n]=e,t.I(n,r)}};t.d(r,{get:()=>o,init:()=>i})}},y={};function w(e){var r=y[e];if(void 0!==r)return r.exports;var t=y[e]={id:e,loaded:!1,exports:{}};return b[e].call(t.exports,t,t.exports,w),t.loaded=!0,t.exports}w.m=b,w.c=y,w.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return w.d(r,{a:r}),r},r=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,w.t=function(t,n){if(1&n&&(t=this(t)),8&n)return t;if("object"==typeof t&&t){if(4&n&&t.__esModule)return t;if(16&n&&"function"==typeof t.then)return t}var o=Object.create(null);w.r(o);var i={};e=e||[null,r({}),r([]),r(r)];for(var a=2&n&&t;"object"==typeof a&&!~e.indexOf(a);a=r(a))Object.getOwnPropertyNames(a).forEach((e=>i[e]=()=>t[e]));return i.default=()=>t,w.d(o,i),o},w.d=(e,r)=>{for(var t in r)w.o(r,t)&&!w.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},w.f={},w.e=e=>Promise.all(Object.keys(w.f).reduce(((r,t)=>(w.f[t](e,r),r)),[])),w.u=e=>e+".js",w.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),w.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),t={},n="@openmrs/esm-form-engine-lib:",w.l=(e,r,o,i)=>{if(t[e])t[e].push(r);else{var a,l;if(void 0!==o)for(var s=document.getElementsByTagName("script"),u=0;u<s.length;u++){var f=s[u];if(f.getAttribute("src")==e||f.getAttribute("data-webpack")==n+o){a=f;break}}a||(l=!0,(a=document.createElement("script")).charset="utf-8",a.timeout=120,w.nc&&a.setAttribute("nonce",w.nc),a.setAttribute("data-webpack",n+o),a.src=e),t[e]=[r];var p=(r,n)=>{a.onerror=a.onload=null,clearTimeout(d);var o=t[e];if(delete t[e],a.parentNode&&a.parentNode.removeChild(a),o&&o.forEach((e=>e(n))),r)return r(n)},d=setTimeout(p.bind(null,void 0,{type:"timeout",target:a}),12e4);a.onerror=p.bind(null,a.onerror),a.onload=p.bind(null,a.onload),l&&document.head.appendChild(a)}},w.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},w.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),(()=>{w.S={};var e={},r={};w.I=(t,n)=>{n||(n=[]);var o=r[t];if(o||(o=r[t]={}),!(n.indexOf(o)>=0)){if(n.push(o),e[t])return e[t];w.o(w.S,t)||(w.S[t]={});var i=w.S[t],a="@openmrs/esm-form-engine-lib",l=(e,r,t,n)=>{var o=i[e]=i[e]||{},l=o[r];(!l||!l.loaded&&(!n!=!l.eager?n:a>l.from))&&(o[r]={get:t,from:a,eager:!!n})},s=[];return"default"===t&&(l("@openmrs/esm-framework","5.8.2-pre.2394",(()=>Promise.all([w.e(151),w.e(72),w.e(766)]).then((()=>()=>w(5151))))),l("@openmrs/esm-patient-common-lib","8.1.1-pre.5183",(()=>Promise.all([w.e(617),w.e(901),w.e(72),w.e(465),w.e(385),w.e(70)]).then((()=>()=>w(8617))))),l("dayjs","1.11.11",(()=>w.e(353).then((()=>()=>w(4353))))),l("i18next","23.11.4",(()=>w.e(635).then((()=>()=>w(2635))))),l("react-i18next","11.18.6",(()=>Promise.all([w.e(422),w.e(72)]).then((()=>()=>w(4422))))),l("react","18.3.1",(()=>w.e(540).then((()=>()=>w(6540))))),l("swr/_internal","2.2.5",(()=>Promise.all([w.e(993),w.e(72)]).then((()=>()=>w(4993))))),l("swr/immutable","2.2.5",(()=>Promise.all([w.e(225),w.e(72),w.e(465)]).then((()=>()=>w(4225))))),l("swr/infinite","2.2.5",(()=>Promise.all([w.e(41),w.e(72),w.e(465)]).then((()=>()=>w(3041)))))),e[t]=s.length?Promise.all(s).then((()=>e[t]=1)):1}}})(),(()=>{var e;w.g.importScripts&&(e=w.g.location+"");var r=w.g.document;if(!e&&r&&(r.currentScript&&(e=r.currentScript.src),!e)){var t=r.getElementsByTagName("script");if(t.length)for(var n=t.length-1;n>-1&&(!e||!/^http(s?):/.test(e));)e=t[n--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),w.p=e})(),o=e=>{var r=e=>e.split(".").map((e=>+e==e?+e:e)),t=/^([^-+]+)?(?:-([^+]+))?(?:\+(.+))?$/.exec(e),n=t[1]?r(t[1]):[];return t[2]&&(n.length++,n.push.apply(n,r(t[2]))),t[3]&&(n.push([]),n.push.apply(n,r(t[3]))),n},i=(e,r)=>{e=o(e),r=o(r);for(var t=0;;){if(t>=e.length)return t<r.length&&"u"!=(typeof r[t])[0];var n=e[t],i=(typeof n)[0];if(t>=r.length)return"u"==i;var a=r[t],l=(typeof a)[0];if(i!=l)return"o"==i&&"n"==l||"s"==l||"u"==i;if("o"!=i&&"u"!=i&&n!=a)return n<a;t++}},a=e=>{var r=e[0],t="";if(1===e.length)return"*";if(r+.5){t+=0==r?">=":-1==r?"<":1==r?"^":2==r?"~":r>0?"=":"!=";for(var n=1,o=1;o<e.length;o++)n--,t+="u"==(typeof(l=e[o]))[0]?"-":(n>0?".":"")+(n=2,l);return t}var i=[];for(o=1;o<e.length;o++){var l=e[o];i.push(0===l?"not("+s()+")":1===l?"("+s()+" || "+s()+")":2===l?i.pop()+" "+i.pop():a(l))}return s();function s(){return i.pop().replace(/^\((.+)\)$/,"$1")}},l=(e,r)=>{if(0 in e){r=o(r);var t=e[0],n=t<0;n&&(t=-t-1);for(var i=0,a=1,s=!0;;a++,i++){var u,f,p=a<e.length?(typeof e[a])[0]:"";if(i>=r.length||"o"==(f=(typeof(u=r[i]))[0]))return!s||("u"==p?a>t&&!n:""==p!=n);if("u"==f){if(!s||"u"!=p)return!1}else if(s)if(p==f)if(a<=t){if(u!=e[a])return!1}else{if(n?u>e[a]:u<e[a])return!1;u!=e[a]&&(s=!1)}else if("s"!=p&&"n"!=p){if(n||a<=t)return!1;s=!1,a--}else{if(a<=t||f<p!=n)return!1;s=!1}else"s"!=p&&"n"!=p&&(s=!1,a--)}}var d=[],c=d.pop.bind(d);for(i=1;i<e.length;i++){var h=e[i];d.push(1==h?c()|c():2==h?c()&c():h?l(h,r):!c())}return!!c()},s=(e,r)=>{var t=e[r];return Object.keys(t).reduce(((e,r)=>!e||!t[e].loaded&&i(e,r)?r:e),0)},u=(e,r,t,n)=>"Unsatisfied version "+t+" from "+(t&&e[r][t].from)+" of shared singleton module "+r+" (required "+a(n)+")",f=(e,r,t,n)=>{var o=s(e,t);return l(n,o)||p(u(e,t,o,n)),d(e[t][o])},p=e=>{"undefined"!=typeof console&&console.warn&&console.warn(e)},d=e=>(e.loaded=1,e.get()),c=(e=>function(r,t,n,o){var i=w.I(r);return i&&i.then?i.then(e.bind(e,r,w.S[r],t,n,o)):e(0,w.S[r],t,n,o)})(((e,r,t,n,o)=>r&&w.o(r,t)?f(r,0,t,n):o())),h={},m={6072:()=>c("default","react",[1,18],(()=>w.e(540).then((()=>()=>w(6540))))),6766:()=>c("default","i18next",[1,23],(()=>w.e(635).then((()=>()=>w(2635))))),8465:()=>c("default","swr/_internal",[1,2],(()=>w.e(993).then((()=>()=>w(4993))))),3941:()=>c("default","react-i18next",[1,11],(()=>w.e(422).then((()=>()=>w(4422))))),5972:()=>c("default","@openmrs/esm-framework",[1,5],(()=>Promise.all([w.e(151),w.e(766)]).then((()=>()=>w(5151))))),6656:()=>c("default","@openmrs/esm-patient-common-lib",[1,8],(()=>Promise.all([w.e(617),w.e(465)]).then((()=>()=>w(8617))))),4209:()=>c("default","swr/immutable",[1,2],(()=>Promise.all([w.e(225),w.e(465)]).then((()=>()=>w(4225))))),231:()=>c("default","dayjs",[1,1],(()=>w.e(353).then((()=>()=>w(4353))))),6339:()=>c("default","swr/infinite",[1,2],(()=>Promise.all([w.e(41),w.e(465)]).then((()=>()=>w(3041)))))},v={70:[4209],72:[6072],385:[3941,5972,6656],465:[8465],751:[231,4209,6339],766:[6766]},g={},w.f.consumes=(e,r)=>{w.o(v,e)&&v[e].forEach((e=>{if(w.o(h,e))return r.push(h[e]);if(!g[e]){var t=r=>{h[e]=0,w.m[e]=t=>{delete w.c[e],t.exports=r()}};g[e]=!0;var n=r=>{delete h[e],w.m[e]=t=>{throw delete w.c[e],r}};try{var o=m[e]();o.then?r.push(h[e]=o.then(t).catch(n)):t(o)}catch(e){n(e)}}}))},(()=>{var e={719:0};w.f.j=(r,t)=>{var n=w.o(e,r)?e[r]:void 0;if(0!==n)if(n)t.push(n[2]);else if(/^(385|465|72|766)$/.test(r))e[r]=0;else{var o=new Promise(((t,o)=>n=e[r]=[t,o]));t.push(n[2]=o);var i=w.p+w.u(r),a=new Error;w.l(i,(t=>{if(w.o(e,r)&&(0!==(n=e[r])&&(e[r]=void 0),n)){var o=t&&("load"===t.type?"missing":t.type),i=t&&t.target&&t.target.src;a.message="Loading chunk "+r+" failed.\n("+o+": "+i+")",a.name="ChunkLoadError",a.type=o,a.request=i,n[1](a)}}),"chunk-"+r,r)}};var r=(r,t)=>{var n,o,[i,a,l]=t,s=0;if(i.some((r=>0!==e[r]))){for(n in a)w.o(a,n)&&(w.m[n]=a[n]);l&&l(w)}for(r&&r(t);s<i.length;s++)o=i[s],w.o(e,o)&&e[o]&&e[o][0](),e[o]=0},t=globalThis.webpackChunk_openmrs_esm_form_engine_lib=globalThis.webpackChunk_openmrs_esm_form_engine_lib||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})(),w.nc=void 0;var _=w(8008);_openmrs_esm_form_engine_lib=_})();
|
package/package.json
CHANGED
@@ -104,7 +104,7 @@ const MultiSelect: React.FC<FormFieldInputProps> = ({ field, value, errors, warn
|
|
104
104
|
initialSelectedItems={initiallySelectedQuestionItems}
|
105
105
|
label={''}
|
106
106
|
titleText={label}
|
107
|
-
key={
|
107
|
+
key={field.id}
|
108
108
|
itemToString={(item) => (item ? item.label : ' ')}
|
109
109
|
disabled={field.isDisabled}
|
110
110
|
invalid={errors.length > 0}
|
@@ -118,10 +118,10 @@ const MultiSelect: React.FC<FormFieldInputProps> = ({ field, value, errors, warn
|
|
118
118
|
{field.questionOptions.answers?.map((value, index) => {
|
119
119
|
return (
|
120
120
|
<Checkbox
|
121
|
-
key={value.concept}
|
121
|
+
key={`${field.id}-${value.concept}`}
|
122
122
|
className={styles.checkbox}
|
123
123
|
labelText={value.label}
|
124
|
-
id={value.concept}
|
124
|
+
id={`${field.id}-${value.concept}`}
|
125
125
|
onChange={() => {
|
126
126
|
handleSelectCheckbox(value);
|
127
127
|
}}
|
@@ -9,6 +9,7 @@ import styles from './number.scss';
|
|
9
9
|
import { useTranslation } from 'react-i18next';
|
10
10
|
import { useFormProviderContext } from '../../../provider/form-provider';
|
11
11
|
import FieldLabel from '../../field-label/field-label.component';
|
12
|
+
import { isEmpty } from '../../../validators/form-validator';
|
12
13
|
|
13
14
|
const NumberField: React.FC<FormFieldInputProps> = ({ field, value, errors, warnings, setFieldValue }) => {
|
14
15
|
const { t } = useTranslation();
|
@@ -31,7 +32,7 @@ const NumberField: React.FC<FormFieldInputProps> = ({ field, value, errors, warn
|
|
31
32
|
|
32
33
|
const handleChange = useCallback(
|
33
34
|
(event) => {
|
34
|
-
const parsedValue = Number(event.target.value);
|
35
|
+
const parsedValue = isEmpty(event.target.value) ? undefined : Number(event.target.value);
|
35
36
|
setFieldValue(isNaN(parsedValue) ? undefined : parsedValue);
|
36
37
|
},
|
37
38
|
[setFieldValue],
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
2
|
-
import debounce from 'lodash-es
|
2
|
+
import { debounce } from 'lodash-es';
|
3
3
|
import { ComboBox, DropdownSkeleton, Layer, InlineLoading } from '@carbon/react';
|
4
4
|
import { isTrue } from '../../../utils/boolean-utils';
|
5
5
|
import { useTranslation } from 'react-i18next';
|
@@ -17,6 +17,11 @@ global.ResizeObserver = require('resize-observer-polyfill');
|
|
17
17
|
jest.mock('../../../hooks/useRestMaxResultsCount', () => jest.fn().mockReturnValue({ systemSetting: { value: '50' } }));
|
18
18
|
jest.mock('lodash-es/debounce', () => jest.fn((fn) => fn));
|
19
19
|
|
20
|
+
jest.mock('lodash-es', () => ({
|
21
|
+
...jest.requireActual('lodash-es'),
|
22
|
+
debounce: jest.fn((fn) => fn),
|
23
|
+
}));
|
24
|
+
|
20
25
|
jest.mock('../../../api', () => {
|
21
26
|
const originalModule = jest.requireActual('../../../api');
|
22
27
|
return {
|
@@ -28,7 +28,7 @@ import { moduleName } from '../../globals';
|
|
28
28
|
import { extractErrorMessagesFromResponse } from '../../utils/error-utils';
|
29
29
|
import { getPreviousEncounter, saveEncounter } from '../../api';
|
30
30
|
import { useEncounterRole } from '../../hooks/useEncounterRole';
|
31
|
-
import { evaluateAsyncExpression,
|
31
|
+
import { evaluateAsyncExpression, type FormNode } from '../../utils/expression-runner';
|
32
32
|
import { hasRendering } from '../../utils/common-utils';
|
33
33
|
import { extractObsValueAndDisplay } from '../../utils/form-helper';
|
34
34
|
|
@@ -337,12 +337,7 @@ async function evaluateCalculateExpression(
|
|
337
337
|
mode: sessionMode,
|
338
338
|
patient: patient,
|
339
339
|
};
|
340
|
-
|
341
|
-
if (field.questionOptions.calculate.calculateExpression.includes('resolve(')) {
|
342
|
-
value = await evaluateAsyncExpression(expression, node, formFields, values, context);
|
343
|
-
} else {
|
344
|
-
value = evaluateExpression(expression, node, formFields, values, context);
|
345
|
-
}
|
340
|
+
const value = await evaluateAsyncExpression(expression, node, formFields, values, context);
|
346
341
|
if (!isEmpty(value)) {
|
347
342
|
values[field.id] = value;
|
348
343
|
}
|
@@ -1,15 +1,36 @@
|
|
1
1
|
import dayjs from 'dayjs';
|
2
|
-
import { CommonExpressionHelpers } from './common-expression-helpers';
|
2
|
+
import { CommonExpressionHelpers, simpleHash } from './common-expression-helpers';
|
3
|
+
import { type FormField } from '../types';
|
3
4
|
|
4
5
|
describe('CommonExpressionHelpers', () => {
|
5
6
|
let helpers: CommonExpressionHelpers;
|
6
7
|
const mockPatient = { birthDate: '1990-01-01', sex: 'male' };
|
7
|
-
const mockFields = [
|
8
|
+
const mockFields: Array<FormField> = [
|
9
|
+
{
|
10
|
+
label: 'Question 1',
|
11
|
+
type: 'obs',
|
12
|
+
questionOptions: {
|
13
|
+
rendering: 'radio',
|
14
|
+
concept: 'question1_concept',
|
15
|
+
answers: [],
|
16
|
+
},
|
17
|
+
id: 'question1',
|
18
|
+
},
|
19
|
+
{
|
20
|
+
label: 'Question 2',
|
21
|
+
type: 'obs',
|
22
|
+
questionOptions: {
|
23
|
+
rendering: 'radio',
|
24
|
+
concept: 'question2_concept',
|
25
|
+
answers: [],
|
26
|
+
},
|
27
|
+
id: 'question2',
|
28
|
+
},
|
29
|
+
];
|
8
30
|
const mockFieldValues = {};
|
9
|
-
const mockFieldKeys = [];
|
10
31
|
|
11
32
|
beforeEach(() => {
|
12
|
-
helpers = new CommonExpressionHelpers(null, mockPatient, mockFields, mockFieldValues
|
33
|
+
helpers = new CommonExpressionHelpers(null, mockPatient, mockFields, mockFieldValues);
|
13
34
|
});
|
14
35
|
|
15
36
|
describe('isEmpty', () => {
|
@@ -86,13 +107,25 @@ describe('CommonExpressionHelpers', () => {
|
|
86
107
|
describe('useFieldValue', () => {
|
87
108
|
it('should return the field value if the key exists', () => {
|
88
109
|
helpers.allFieldValues = { question1: 'value1' };
|
89
|
-
helpers.allFieldsKeys = ['question1'];
|
90
110
|
expect(helpers.useFieldValue('question1')).toBe('value1');
|
91
111
|
});
|
92
112
|
|
93
113
|
it('should return null if the key does not exist', () => {
|
94
114
|
expect(helpers.useFieldValue('question2')).toBe(null);
|
95
115
|
});
|
116
|
+
|
117
|
+
it("should register dependency of the current node to it's determinant", () => {
|
118
|
+
// question1 as the current node
|
119
|
+
helpers.node = {
|
120
|
+
value: mockFields[0],
|
121
|
+
type: 'field',
|
122
|
+
};
|
123
|
+
helpers.allFieldValues = { question1: 'value1', question2: 'value2' };
|
124
|
+
|
125
|
+
helpers.useFieldValue('question2');
|
126
|
+
// assert that question2 lists question1 as dependent
|
127
|
+
expect(Array.from(mockFields[1].fieldDependents)).toStrictEqual(['question1']);
|
128
|
+
});
|
96
129
|
});
|
97
130
|
|
98
131
|
describe('doesNotMatchExpression', () => {
|
@@ -329,3 +362,39 @@ describe('CommonExpressionHelpers', () => {
|
|
329
362
|
});
|
330
363
|
});
|
331
364
|
});
|
365
|
+
|
366
|
+
describe('simpleHash', () => {
|
367
|
+
test('should return the same hash for the same input string', () => {
|
368
|
+
const expression = "linkedToCare == '488b58ff-64f5-4f8a-8979-fa79940b1594'";
|
369
|
+
const hash1 = simpleHash(expression);
|
370
|
+
const hash2 = simpleHash(expression);
|
371
|
+
expect(hash1).toBe(hash2);
|
372
|
+
});
|
373
|
+
|
374
|
+
test('should return different hashes for different input strings', () => {
|
375
|
+
const expression1 = "linkedToCare == '488b58ff-64f5-4f8a-8979-fa79940b1594'";
|
376
|
+
const expression2 = "linkedToCare !== '488b58ff-64f5-4f8a-8979-fa79940b1594'";
|
377
|
+
const hash1 = simpleHash(expression1);
|
378
|
+
const hash2 = simpleHash(expression2);
|
379
|
+
expect(hash1).not.toBe(hash2);
|
380
|
+
});
|
381
|
+
|
382
|
+
test('should handle empty string and return 0', () => {
|
383
|
+
const expression = '';
|
384
|
+
const hash = simpleHash(expression);
|
385
|
+
expect(hash).toBe(0);
|
386
|
+
});
|
387
|
+
|
388
|
+
test('should handle long strings without errors', () => {
|
389
|
+
const longExpression = 'left != right &'.repeat(1000);
|
390
|
+
const hash = simpleHash(longExpression);
|
391
|
+
expect(hash).toBeDefined();
|
392
|
+
});
|
393
|
+
|
394
|
+
test('should return consistent hash for strings with Unicode characters', () => {
|
395
|
+
const str = '😊💻';
|
396
|
+
const hash1 = simpleHash(str);
|
397
|
+
const hash2 = simpleHash(str);
|
398
|
+
expect(hash1).toBe(hash2);
|
399
|
+
});
|
400
|
+
});
|