@openmrs/esm-form-engine-lib 2.1.0-pre.1502 → 2.1.0-pre.1511
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/3a3e1d216bd6470d/3a3e1d216bd6470d.gz +0 -0
- 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/b3059e748360776a/b3059e748360776a.gz +0 -0
- package/dist/openmrs-esm-form-engine-lib.js +1 -1
- package/package.json +1 -1
- package/src/components/inputs/date/date.test.tsx +107 -0
- 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 +13 -14
- package/src/types/schema.ts +0 -2
- 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/aaf8197a12df0c40/aaf8197a12df0c40.gz +0 -0
- package/aba5c979c0dbf1c7/aba5c979c0dbf1c7.gz +0 -0
- package/src/utils/expression-parser.test.ts +0 -308
- package/src/utils/expression-parser.ts +0 -158
- /package/{47245761e3f779c4/47245761e3f779c4.gz → 22ec231da647cd2c/22ec231da647cd2c.gz} +0 -0
- /package/{6f1d94035d69e5e1/6f1d94035d69e5e1.gz → 485e0040f135cee8/485e0040f135cee8.gz} +0 -0
@@ -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
|
+
}
|
Binary file
|
@@ -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
@@ -0,0 +1,107 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { act, render, screen } from '@testing-library/react';
|
3
|
+
import { useFormProviderContext } from 'src/provider/form-provider';
|
4
|
+
import DateField from './date.component';
|
5
|
+
import { type FormField } from 'src/types';
|
6
|
+
import { OpenmrsDatePicker } from '@openmrs/esm-framework';
|
7
|
+
import dayjs from 'dayjs';
|
8
|
+
|
9
|
+
jest.mock('src/provider/form-provider', () => ({
|
10
|
+
useFormProviderContext: jest.fn(),
|
11
|
+
}));
|
12
|
+
|
13
|
+
const mockUseFormProviderContext = useFormProviderContext as jest.Mock;
|
14
|
+
const mockSetFieldValue = jest.fn();
|
15
|
+
|
16
|
+
const mockOpenmrsDatePicker = jest.mocked(OpenmrsDatePicker);
|
17
|
+
|
18
|
+
mockOpenmrsDatePicker.mockImplementation(({ id, labelText, value, onChange, isInvalid, invalidText }) => {
|
19
|
+
return (
|
20
|
+
<>
|
21
|
+
<label htmlFor={id}>{labelText}</label>
|
22
|
+
<input
|
23
|
+
id={id}
|
24
|
+
value={value ? dayjs(value as unknown as string).format('DD/MM/YYYY') : ''}
|
25
|
+
onChange={(evt) => {
|
26
|
+
onChange(dayjs(evt.target.value).toDate());
|
27
|
+
}}
|
28
|
+
/>
|
29
|
+
{isInvalid && <span>{invalidText}</span>}
|
30
|
+
</>
|
31
|
+
);
|
32
|
+
});
|
33
|
+
|
34
|
+
const dateFieldMock: FormField = {
|
35
|
+
id: 'test-date-field',
|
36
|
+
label: 'Test Date Field',
|
37
|
+
type: 'obs',
|
38
|
+
datePickerFormat: 'both',
|
39
|
+
questionOptions: {
|
40
|
+
rendering: 'date',
|
41
|
+
concept: '6089AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
42
|
+
},
|
43
|
+
isHidden: false,
|
44
|
+
isDisabled: false,
|
45
|
+
readonly: false,
|
46
|
+
};
|
47
|
+
|
48
|
+
const renderDateField = async (props) => {
|
49
|
+
await act(() => render(<DateField {...props} />));
|
50
|
+
};
|
51
|
+
|
52
|
+
describe('DateField Component', () => {
|
53
|
+
beforeEach(() => {
|
54
|
+
mockUseFormProviderContext.mockReturnValue({
|
55
|
+
layoutType: 'default',
|
56
|
+
sessionMode: 'edit',
|
57
|
+
workspaceLayout: 'default',
|
58
|
+
formFieldAdapters: {},
|
59
|
+
});
|
60
|
+
});
|
61
|
+
|
62
|
+
it('should render date picker and time picker when datePickerFormat is "both"', async () => {
|
63
|
+
await renderDateField({
|
64
|
+
field: dateFieldMock,
|
65
|
+
value: new Date(),
|
66
|
+
errors: [],
|
67
|
+
warnings: [],
|
68
|
+
setFieldValue: mockSetFieldValue,
|
69
|
+
});
|
70
|
+
|
71
|
+
expect(screen.getByLabelText('Test Date Field')).toBeInTheDocument();
|
72
|
+
expect(screen.getByText('Time')).toBeInTheDocument();
|
73
|
+
});
|
74
|
+
|
75
|
+
it('should display error message when there are errors', async () => {
|
76
|
+
await renderDateField({
|
77
|
+
field: dateFieldMock,
|
78
|
+
value: new Date(),
|
79
|
+
errors: [{ resultType: 'error', message: 'Error message' }],
|
80
|
+
warnings: [],
|
81
|
+
setFieldValue: mockSetFieldValue,
|
82
|
+
});
|
83
|
+
|
84
|
+
const errorMessages = screen.getAllByText(/Error message/i);
|
85
|
+
expect(errorMessages.length).toBeGreaterThan(0);
|
86
|
+
errorMessages.forEach((message) => {
|
87
|
+
expect(message).toBeInTheDocument();
|
88
|
+
});
|
89
|
+
});
|
90
|
+
|
91
|
+
it('should display warning message when there are warnings', async () => {
|
92
|
+
const warnings = [{ resultType: 'warning', message: 'Warning message' }];
|
93
|
+
await renderDateField({
|
94
|
+
field: dateFieldMock,
|
95
|
+
value: new Date(),
|
96
|
+
errors: [],
|
97
|
+
warnings: warnings,
|
98
|
+
setFieldValue: mockSetFieldValue,
|
99
|
+
});
|
100
|
+
|
101
|
+
const warningMessages = screen.getAllByText(/Warning message/i);
|
102
|
+
expect(warningMessages.length).toBeGreaterThan(0);
|
103
|
+
warningMessages.forEach((message) => {
|
104
|
+
expect(message).toBeInTheDocument();
|
105
|
+
});
|
106
|
+
});
|
107
|
+
});
|
@@ -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
|
|
@@ -256,17 +256,11 @@ export class EncounterFormProcessor extends FormProcessor {
|
|
256
256
|
const filteredFields = formFields.filter(
|
257
257
|
(field) => field.questionOptions.rendering !== 'group' && field.type !== 'obsGroup',
|
258
258
|
);
|
259
|
+
const fieldsWithCalculateExpressions = [];
|
259
260
|
await Promise.all(
|
260
261
|
filteredFields.map(async (field) => {
|
261
262
|
const adapter = formFieldAdapters[field.type];
|
262
263
|
initialValues[field.id] = emptyValues[field.questionOptions.rendering] ?? null;
|
263
|
-
if (field.questionOptions.calculate?.calculateExpression) {
|
264
|
-
try {
|
265
|
-
await evaluateCalculateExpression(field, initialValues, context);
|
266
|
-
} catch (error) {
|
267
|
-
console.error(error);
|
268
|
-
}
|
269
|
-
}
|
270
264
|
if (isEmpty(initialValues[field.id]) && contextInitializableTypes.includes(field.type)) {
|
271
265
|
try {
|
272
266
|
initialValues[field.id] = await adapter.getInitialValue(field, null, context);
|
@@ -274,8 +268,18 @@ export class EncounterFormProcessor extends FormProcessor {
|
|
274
268
|
console.error(error);
|
275
269
|
}
|
276
270
|
}
|
271
|
+
if (field.questionOptions.calculate?.calculateExpression) {
|
272
|
+
fieldsWithCalculateExpressions.push(field);
|
273
|
+
}
|
277
274
|
}),
|
278
275
|
);
|
276
|
+
fieldsWithCalculateExpressions.forEach(async (field) => {
|
277
|
+
try {
|
278
|
+
await evaluateCalculateExpression(field, initialValues, context);
|
279
|
+
} catch (error) {
|
280
|
+
console.error(error);
|
281
|
+
}
|
282
|
+
});
|
279
283
|
}
|
280
284
|
return initialValues;
|
281
285
|
}
|
@@ -333,12 +337,7 @@ async function evaluateCalculateExpression(
|
|
333
337
|
mode: sessionMode,
|
334
338
|
patient: patient,
|
335
339
|
};
|
336
|
-
|
337
|
-
if (field.questionOptions.calculate.calculateExpression.includes('resolve(')) {
|
338
|
-
value = await evaluateAsyncExpression(expression, node, formFields, values, context);
|
339
|
-
} else {
|
340
|
-
value = evaluateExpression(expression, node, formFields, values, context);
|
341
|
-
}
|
340
|
+
const value = await evaluateAsyncExpression(expression, node, formFields, values, context);
|
342
341
|
if (!isEmpty(value)) {
|
343
342
|
values[field.id] = value;
|
344
343
|
}
|