@ampath/esm-patient-registration-app 9.2.0-next.14 → 9.2.0-next.15
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/2450.js +1 -0
- package/dist/2450.js.map +1 -0
- package/dist/2615.js +2 -0
- package/dist/2615.js.map +1 -0
- package/dist/3474.js +1 -1
- package/dist/3474.js.map +1 -1
- package/dist/5239.js +1 -1
- package/dist/5239.js.map +1 -1
- package/dist/6276.js +1 -1
- package/dist/6276.js.map +1 -1
- package/dist/8434.js +1 -1
- package/dist/8434.js.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/openmrs-esm-patient-registration-app.js +1 -1
- package/dist/openmrs-esm-patient-registration-app.js.buildmanifest.json +59 -59
- package/dist/routes.json +1 -1
- package/package.json +1 -1
- package/src/patient-registration/client-registry/client-registry-search.component.tsx +233 -0
- package/src/patient-registration/client-registry/client-registry.resource.ts +79 -0
- package/src/patient-registration/client-registry/map-client-registry-to-form-utils.ts +190 -0
- package/src/patient-registration/patient-registration.component.tsx +25 -8
- package/dist/1909.js +0 -2
- package/dist/1909.js.map +0 -1
- package/dist/627.js +0 -1
- package/dist/627.js.map +0 -1
- /package/dist/{1909.js.LICENSE.txt → 2615.js.LICENSE.txt} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
var _ampath_esm_patient_registration_app;(()=>{"use strict";var e,r,t,n,a,o,i,l,s,u,f,p,d,h,c,m,v,g,b,y,w,_={3174:(e,r,t)=>{var n={"./start":()=>Promise.all([t.e(3144),t.e(
|
|
1
|
+
var _ampath_esm_patient_registration_app;(()=>{"use strict";var e,r,t,n,a,o,i,l,s,u,f,p,d,h,c,m,v,g,b,y,w,_={3174:(e,r,t)=>{var n={"./start":()=>Promise.all([t.e(3144),t.e(2615),t.e(1343),t.e(7243),t.e(3474)]).then(()=>()=>t(87821))},a=(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),o=(e,r)=>{if(t.S){var n="default",a=t.S[n];if(a&&a!==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:()=>a,init:()=>o})}},P={};function S(e){var r=P[e];if(void 0!==r)return r.exports;var t=P[e]={id:e,loaded:!1,exports:{}};return _[e].call(t.exports,t,t.exports,S),t.loaded=!0,t.exports}S.m=_,S.c=P,S.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return S.d(r,{a:r}),r},r=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,S.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 a=Object.create(null);S.r(a);var o={};e=e||[null,r({}),r([]),r(r)];for(var i=2&n&&t;"object"==typeof i&&!~e.indexOf(i);i=r(i))Object.getOwnPropertyNames(i).forEach(e=>o[e]=()=>t[e]);return o.default=()=>t,S.d(a,o),a},S.d=(e,r)=>{for(var t in r)S.o(r,t)&&!S.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},S.f={},S.e=e=>Promise.all(Object.keys(S.f).reduce((r,t)=>(S.f[t](e,r),r),[])),S.u=e=>e+".js",S.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),S.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),t={},n="@ampath/esm-patient-registration-app:",S.l=(e,r,a,o)=>{if(t[e])t[e].push(r);else{var i,l;if(void 0!==a)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+a){i=f;break}}i||(l=!0,(i=document.createElement("script")).charset="utf-8",i.timeout=120,S.nc&&i.setAttribute("nonce",S.nc),i.setAttribute("data-webpack",n+a),i.src=e),t[e]=[r];var p=(r,n)=>{i.onerror=i.onload=null,clearTimeout(d);var a=t[e];if(delete t[e],i.parentNode&&i.parentNode.removeChild(i),a&&a.forEach(e=>e(n)),r)return r(n)},d=setTimeout(p.bind(null,void 0,{type:"timeout",target:i}),12e4);i.onerror=p.bind(null,i.onerror),i.onload=p.bind(null,i.onload),l&&document.head.appendChild(i)}},S.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},S.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),(()=>{S.S={};var e={},r={};S.I=(t,n)=>{n||(n=[]);var a=r[t];if(a||(a=r[t]={}),!(n.indexOf(a)>=0)){if(n.push(a),e[t])return e[t];S.o(S.S,t)||(S.S[t]={});var o=S.S[t],i="@ampath/esm-patient-registration-app",l=(e,r,t,n)=>{var a=o[e]=o[e]||{},l=a[r];(!l||!l.loaded&&(!n!=!l.eager?n:i>l.from))&&(a[r]={get:t,from:i,eager:!!n})},s=[];return"default"===t&&(l("@openmrs/esm-framework","8.0.1-pre.3444",()=>Promise.all([S.e(3144),S.e(729),S.e(5239),S.e(2615),S.e(1343),S.e(5434),S.e(2086),S.e(7243),S.e(8394),S.e(320)]).then(()=>()=>S(15239))),l("dayjs","1.11.13",()=>S.e(3464).then(()=>()=>S(23464))),l("react-i18next","16.0.0",()=>Promise.all([S.e(6336),S.e(1343)]).then(()=>()=>S(16336))),l("react-router-dom","6.30.1",()=>Promise.all([S.e(3144),S.e(2913),S.e(1343)]).then(()=>()=>S(52913))),l("react","18.3.1",()=>S.e(4041).then(()=>()=>S(14041))),l("swr/_internal","2.2.5",()=>Promise.all([S.e(2372),S.e(1343)]).then(()=>()=>S(42372))),l("swr/immutable","2.2.5",()=>Promise.all([S.e(1343),S.e(5434),S.e(7495)]).then(()=>()=>S(29876))),l("swr/infinite","2.2.5",()=>Promise.all([S.e(1343),S.e(5434),S.e(89)]).then(()=>()=>S(52470)))),e[t]=s.length?Promise.all(s).then(()=>e[t]=1):1}}})(),(()=>{var e;S.g.importScripts&&(e=S.g.location+"");var r=S.g.document;if(!e&&r&&(r.currentScript&&"SCRIPT"===r.currentScript.tagName.toUpperCase()&&(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(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),S.p=e})(),a=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},o=(e,r)=>{e=a(e),r=a(r);for(var t=0;;){if(t>=e.length)return t<r.length&&"u"!=(typeof r[t])[0];var n=e[t],o=(typeof n)[0];if(t>=r.length)return"u"==o;var i=r[t],l=(typeof i)[0];if(o!=l)return"o"==o&&"n"==l||"s"==l||"u"==o;if("o"!=o&&"u"!=o&&n!=i)return n<i;t++}},i=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,a=1;a<e.length;a++)n--,t+="u"==(typeof(l=e[a]))[0]?"-":(n>0?".":"")+(n=2,l);return t}var o=[];for(a=1;a<e.length;a++){var l=e[a];o.push(0===l?"not("+s()+")":1===l?"("+s()+" || "+s()+")":2===l?o.pop()+" "+o.pop():i(l))}return s();function s(){return o.pop().replace(/^\((.+)\)$/,"$1")}},l=(e,r)=>{if(0 in e){r=a(r);var t=e[0],n=t<0;n&&(t=-t-1);for(var o=0,i=1,s=!0;;i++,o++){var u,f,p=i<e.length?(typeof e[i])[0]:"";if(o>=r.length||"o"==(f=(typeof(u=r[o]))[0]))return!s||("u"==p?i>t&&!n:""==p!=n);if("u"==f){if(!s||"u"!=p)return!1}else if(s)if(p==f)if(i<=t){if(u!=e[i])return!1}else{if(n?u>e[i]:u<e[i])return!1;u!=e[i]&&(s=!1)}else if("s"!=p&&"n"!=p){if(n||i<=t)return!1;s=!1,i--}else{if(i<=t||f<p!=n)return!1;s=!1}else"s"!=p&&"n"!=p&&(s=!1,i--)}}var d=[],h=d.pop.bind(d);for(o=1;o<e.length;o++){var c=e[o];d.push(1==c?h()|h():2==c?h()&h():c?l(c,r):!h())}return!!h()},s=(e,r)=>e&&S.o(e,r),u=e=>(e.loaded=1,e.get()),f=e=>Object.keys(e).reduce((r,t)=>(e[t].eager&&(r[t]=e[t]),r),{}),p=(e,r,t)=>{var n=t?f(e[r]):e[r];return Object.keys(n).reduce((e,r)=>!e||!n[e].loaded&&o(e,r)?r:e,0)},d=(e,r,t,n)=>"Unsatisfied version "+t+" from "+(t&&e[r][t].from)+" of shared singleton module "+r+" (required "+i(n)+")",h=e=>{throw new Error(e)},c=e=>{"undefined"!=typeof console&&console.warn&&console.warn(e)},m=(e,r,t)=>t?t():((e,r)=>h("Shared module "+r+" doesn't exist in shared scope "+e))(e,r),v=(e=>function(r,t,n,a,o){var i=S.I(r);return i&&i.then&&!n?i.then(e.bind(e,r,S.S[r],t,!1,a,o)):e(r,S.S[r],t,n,a,o)})((e,r,t,n,a,o)=>{if(!s(r,t))return m(e,t,o);var i=p(r,t,n);return l(a,i)||c(d(r,t,i,a)),u(r[t][i])}),g={},b={1343:()=>v("default","react",!1,[1,18],()=>S.e(4041).then(()=>()=>S(14041))),55434:()=>v("default","swr/_internal",!1,[1,2],()=>S.e(2372).then(()=>()=>S(42372))),8877:()=>v("default","react-router-dom",!1,[1,6],()=>S.e(2913).then(()=>()=>S(52913))),88010:()=>v("default","swr/immutable",!1,[1,2],()=>S.e(9876).then(()=>()=>S(29876))),46372:()=>v("default","dayjs",!1,[1,1],()=>S.e(3464).then(()=>()=>S(23464))),54440:()=>v("default","@openmrs/esm-framework",!1,[1,8],()=>Promise.all([S.e(729),S.e(5239),S.e(5434),S.e(2086),S.e(8394)]).then(()=>()=>S(15239))),72339:()=>v("default","react-i18next",!1,[1,16],()=>S.e(6336).then(()=>()=>S(16336))),98394:()=>v("default","swr/infinite",!1,[1,2],()=>S.e(2470).then(()=>()=>S(52470)))},y={1343:[1343],2086:[8877,88010],5434:[55434],7243:[46372,54440,72339],8394:[98394]},w={},S.f.consumes=(e,r)=>{S.o(y,e)&&y[e].forEach(e=>{if(S.o(g,e))return r.push(g[e]);if(!w[e]){var t=r=>{g[e]=0,S.m[e]=t=>{delete S.c[e],t.exports=r()}};w[e]=!0;var n=r=>{delete g[e],S.m[e]=t=>{throw delete S.c[e],r}};try{var a=b[e]();a.then?r.push(g[e]=a.then(t).catch(n)):t(a)}catch(e){n(e)}}})},(()=>{var e={5898:0};S.f.j=(r,t)=>{var n=S.o(e,r)?e[r]:void 0;if(0!==n)if(n)t.push(n[2]);else if(/^((13|72)43|2086|5434|8394)$/.test(r))e[r]=0;else{var a=new Promise((t,a)=>n=e[r]=[t,a]);t.push(n[2]=a);var o=S.p+S.u(r),i=new Error;S.l(o,t=>{if(S.o(e,r)&&(0!==(n=e[r])&&(e[r]=void 0),n)){var a=t&&("load"===t.type?"missing":t.type),o=t&&t.target&&t.target.src;i.message="Loading chunk "+r+" failed.\n("+a+": "+o+")",i.name="ChunkLoadError",i.type=a,i.request=o,n[1](i)}},"chunk-"+r,r)}};var r=(r,t)=>{var n,a,[o,i,l]=t,s=0;if(o.some(r=>0!==e[r])){for(n in i)S.o(i,n)&&(S.m[n]=i[n]);l&&l(S)}for(r&&r(t);s<o.length;s++)a=o[s],S.o(e,a)&&e[a]&&e[a][0](),e[a]=0},t=globalThis.webpackChunk_ampath_esm_patient_registration_app=globalThis.webpackChunk_ampath_esm_patient_registration_app||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})(),S.nc=void 0;var j=S(3174);_ampath_esm_patient_registration_app=j})();
|
|
@@ -48,30 +48,6 @@
|
|
|
48
48
|
"hash": "a8d1e9725e2296c1",
|
|
49
49
|
"childrenByOrder": {}
|
|
50
50
|
},
|
|
51
|
-
{
|
|
52
|
-
"rendered": true,
|
|
53
|
-
"initial": false,
|
|
54
|
-
"entry": false,
|
|
55
|
-
"recorded": false,
|
|
56
|
-
"size": 596866,
|
|
57
|
-
"sizes": {
|
|
58
|
-
"javascript": 596866
|
|
59
|
-
},
|
|
60
|
-
"names": [],
|
|
61
|
-
"idHints": [],
|
|
62
|
-
"runtime": [
|
|
63
|
-
"@ampath/esm-patient-registration-app",
|
|
64
|
-
"main"
|
|
65
|
-
],
|
|
66
|
-
"files": [
|
|
67
|
-
"627.js"
|
|
68
|
-
],
|
|
69
|
-
"auxiliaryFiles": [
|
|
70
|
-
"627.js.map"
|
|
71
|
-
],
|
|
72
|
-
"hash": "829aa5bc3ab05266",
|
|
73
|
-
"childrenByOrder": {}
|
|
74
|
-
},
|
|
75
51
|
{
|
|
76
52
|
"rendered": true,
|
|
77
53
|
"initial": false,
|
|
@@ -252,33 +228,6 @@
|
|
|
252
228
|
"hash": "8015d68cc6468b4f",
|
|
253
229
|
"childrenByOrder": {}
|
|
254
230
|
},
|
|
255
|
-
{
|
|
256
|
-
"rendered": true,
|
|
257
|
-
"initial": false,
|
|
258
|
-
"entry": false,
|
|
259
|
-
"recorded": false,
|
|
260
|
-
"reason": "split chunk (cache group: defaultVendors)",
|
|
261
|
-
"size": 2105822,
|
|
262
|
-
"sizes": {
|
|
263
|
-
"javascript": 2105822
|
|
264
|
-
},
|
|
265
|
-
"names": [],
|
|
266
|
-
"idHints": [
|
|
267
|
-
"vendors"
|
|
268
|
-
],
|
|
269
|
-
"runtime": [
|
|
270
|
-
"@ampath/esm-patient-registration-app",
|
|
271
|
-
"main"
|
|
272
|
-
],
|
|
273
|
-
"files": [
|
|
274
|
-
"1909.js"
|
|
275
|
-
],
|
|
276
|
-
"auxiliaryFiles": [
|
|
277
|
-
"1909.js.map"
|
|
278
|
-
],
|
|
279
|
-
"hash": "4ed18d4f674ab1fd",
|
|
280
|
-
"childrenByOrder": {}
|
|
281
|
-
},
|
|
282
231
|
{
|
|
283
232
|
"rendered": false,
|
|
284
233
|
"initial": false,
|
|
@@ -349,6 +298,30 @@
|
|
|
349
298
|
"hash": "6b718b5d763b8955",
|
|
350
299
|
"childrenByOrder": {}
|
|
351
300
|
},
|
|
301
|
+
{
|
|
302
|
+
"rendered": true,
|
|
303
|
+
"initial": false,
|
|
304
|
+
"entry": false,
|
|
305
|
+
"recorded": false,
|
|
306
|
+
"size": 632874,
|
|
307
|
+
"sizes": {
|
|
308
|
+
"javascript": 632874
|
|
309
|
+
},
|
|
310
|
+
"names": [],
|
|
311
|
+
"idHints": [],
|
|
312
|
+
"runtime": [
|
|
313
|
+
"@ampath/esm-patient-registration-app",
|
|
314
|
+
"main"
|
|
315
|
+
],
|
|
316
|
+
"files": [
|
|
317
|
+
"2450.js"
|
|
318
|
+
],
|
|
319
|
+
"auxiliaryFiles": [
|
|
320
|
+
"2450.js.map"
|
|
321
|
+
],
|
|
322
|
+
"hash": "2aa438783a992c3c",
|
|
323
|
+
"childrenByOrder": {}
|
|
324
|
+
},
|
|
352
325
|
{
|
|
353
326
|
"rendered": true,
|
|
354
327
|
"initial": false,
|
|
@@ -373,6 +346,33 @@
|
|
|
373
346
|
"hash": "c49aaded432ec875",
|
|
374
347
|
"childrenByOrder": {}
|
|
375
348
|
},
|
|
349
|
+
{
|
|
350
|
+
"rendered": true,
|
|
351
|
+
"initial": false,
|
|
352
|
+
"entry": false,
|
|
353
|
+
"recorded": false,
|
|
354
|
+
"reason": "split chunk (cache group: defaultVendors)",
|
|
355
|
+
"size": 2125998,
|
|
356
|
+
"sizes": {
|
|
357
|
+
"javascript": 2125998
|
|
358
|
+
},
|
|
359
|
+
"names": [],
|
|
360
|
+
"idHints": [
|
|
361
|
+
"vendors"
|
|
362
|
+
],
|
|
363
|
+
"runtime": [
|
|
364
|
+
"@ampath/esm-patient-registration-app",
|
|
365
|
+
"main"
|
|
366
|
+
],
|
|
367
|
+
"files": [
|
|
368
|
+
"2615.js"
|
|
369
|
+
],
|
|
370
|
+
"auxiliaryFiles": [
|
|
371
|
+
"2615.js.map"
|
|
372
|
+
],
|
|
373
|
+
"hash": "2b0fa5ee8227f963",
|
|
374
|
+
"childrenByOrder": {}
|
|
375
|
+
},
|
|
376
376
|
{
|
|
377
377
|
"rendered": true,
|
|
378
378
|
"initial": false,
|
|
@@ -539,7 +539,7 @@
|
|
|
539
539
|
"auxiliaryFiles": [
|
|
540
540
|
"3474.js.map"
|
|
541
541
|
],
|
|
542
|
-
"hash": "
|
|
542
|
+
"hash": "e7f72d4f1fb66fef",
|
|
543
543
|
"childrenByOrder": {}
|
|
544
544
|
},
|
|
545
545
|
{
|
|
@@ -812,7 +812,7 @@
|
|
|
812
812
|
"auxiliaryFiles": [
|
|
813
813
|
"5239.js.map"
|
|
814
814
|
],
|
|
815
|
-
"hash": "
|
|
815
|
+
"hash": "9ea7faee85d66390",
|
|
816
816
|
"childrenByOrder": {}
|
|
817
817
|
},
|
|
818
818
|
{
|
|
@@ -926,7 +926,7 @@
|
|
|
926
926
|
"auxiliaryFiles": [
|
|
927
927
|
"openmrs-esm-patient-registration-app.js.map"
|
|
928
928
|
],
|
|
929
|
-
"hash": "
|
|
929
|
+
"hash": "8be971b674ce5ef1",
|
|
930
930
|
"childrenByOrder": {}
|
|
931
931
|
},
|
|
932
932
|
{
|
|
@@ -972,7 +972,7 @@
|
|
|
972
972
|
"auxiliaryFiles": [
|
|
973
973
|
"6276.js.map"
|
|
974
974
|
],
|
|
975
|
-
"hash": "
|
|
975
|
+
"hash": "f1a33cc868749111",
|
|
976
976
|
"childrenByOrder": {}
|
|
977
977
|
},
|
|
978
978
|
{
|
|
@@ -1314,7 +1314,7 @@
|
|
|
1314
1314
|
"auxiliaryFiles": [
|
|
1315
1315
|
"8434.js.map"
|
|
1316
1316
|
],
|
|
1317
|
-
"hash": "
|
|
1317
|
+
"hash": "954293ebac9c60c7",
|
|
1318
1318
|
"childrenByOrder": {}
|
|
1319
1319
|
},
|
|
1320
1320
|
{
|
|
@@ -1344,10 +1344,10 @@
|
|
|
1344
1344
|
"initial": true,
|
|
1345
1345
|
"entry": true,
|
|
1346
1346
|
"recorded": false,
|
|
1347
|
-
"size":
|
|
1347
|
+
"size": 2433588,
|
|
1348
1348
|
"sizes": {
|
|
1349
1349
|
"consume-shared": 168,
|
|
1350
|
-
"javascript":
|
|
1350
|
+
"javascript": 2411017,
|
|
1351
1351
|
"share-init": 336,
|
|
1352
1352
|
"runtime": 22067
|
|
1353
1353
|
},
|
|
@@ -1364,7 +1364,7 @@
|
|
|
1364
1364
|
"auxiliaryFiles": [
|
|
1365
1365
|
"main.js.map"
|
|
1366
1366
|
],
|
|
1367
|
-
"hash": "
|
|
1367
|
+
"hash": "69f8cc2ef447e53f",
|
|
1368
1368
|
"childrenByOrder": {}
|
|
1369
1369
|
},
|
|
1370
1370
|
{
|
package/dist/routes.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"webservices.rest":">=2.2.0"},"pages":[{"component":"root","route":"patient-registration","online":true,"offline":true},{"component":"editPatient","routeRegex":"patient\\/([a-zA-Z0-9\\-]+)\\/edit","online":true,"offline":true}],"extensions":[{"component":"addPatientLink","name":"add-patient-action","slot":"top-nav-actions-slot","online":true,"offline":true,"order":30},{"component":"patientPhotoExtension","name":"patient-photo-widget","slot":"patient-photo-slot","online":true,"offline":true},{"component":"editPatientDetailsButton","name":"edit-patient-details-button","slot":"patient-actions-slot","online":true,"offline":true},{"component":"editPatientDetailsButton","name":"edit-patient-details-button","slot":"patient-search-actions-slot","online":true,"offline":true}],"modals":[{"name":"cancel-patient-edit-modal","component":"cancelPatientEditModal"},{"name":"delete-identifier-confirmation-modal","component":"deleteIdentifierConfirmationModal"}],"version":"9.2.0-next.
|
|
1
|
+
{"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"webservices.rest":">=2.2.0"},"pages":[{"component":"root","route":"patient-registration","online":true,"offline":true},{"component":"editPatient","routeRegex":"patient\\/([a-zA-Z0-9\\-]+)\\/edit","online":true,"offline":true}],"extensions":[{"component":"addPatientLink","name":"add-patient-action","slot":"top-nav-actions-slot","online":true,"offline":true,"order":30},{"component":"patientPhotoExtension","name":"patient-photo-widget","slot":"patient-photo-slot","online":true,"offline":true},{"component":"editPatientDetailsButton","name":"edit-patient-details-button","slot":"patient-actions-slot","online":true,"offline":true},{"component":"editPatientDetailsButton","name":"edit-patient-details-button","slot":"patient-search-actions-slot","online":true,"offline":true}],"modals":[{"name":"cancel-patient-edit-modal","component":"cancelPatientEditModal"},{"name":"delete-identifier-confirmation-modal","component":"deleteIdentifierConfirmationModal"}],"version":"9.2.0-next.15"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { Button, TextInput, InlineLoading, InlineNotification, Dropdown } from '@carbon/react';
|
|
3
|
+
import { showSnackbar, useSession } from '@openmrs/esm-framework';
|
|
4
|
+
import { useFormikContext } from 'formik';
|
|
5
|
+
import styles from '../patient-registration.scss';
|
|
6
|
+
import { requestCustomOtp, validateCustomOtp, fetchClientRegistryData } from './client-registry.resource';
|
|
7
|
+
import { applyClientRegistryMapping } from './map-client-registry-to-form-utils';
|
|
8
|
+
|
|
9
|
+
export interface ClientRegistryLookupSectionProps {
|
|
10
|
+
onClientVerified?: () => void;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type IdentifierType = 'National ID' | 'Alien ID' | 'Passport' | 'Mandate Number' | 'Refugee ID';
|
|
14
|
+
|
|
15
|
+
export const IDENTIFIER_TYPES: IdentifierType[] = [
|
|
16
|
+
'National ID',
|
|
17
|
+
'Alien ID',
|
|
18
|
+
'Passport',
|
|
19
|
+
'Mandate Number',
|
|
20
|
+
'Refugee ID',
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
const ClientRegistryLookupSection: React.FC<ClientRegistryLookupSectionProps> = ({ onClientVerified }) => {
|
|
24
|
+
const { setFieldValue } = useFormikContext<any>();
|
|
25
|
+
const [identifierType, setIdentifierType] = useState<IdentifierType>('National ID');
|
|
26
|
+
const [identifierValue, setIdentifierValue] = useState('');
|
|
27
|
+
const [otp, setOtp] = useState('');
|
|
28
|
+
const [otpSent, setOtpSent] = useState(false);
|
|
29
|
+
const [otpVerified, setOtpVerified] = useState(false);
|
|
30
|
+
const [loading, setLoading] = useState(false);
|
|
31
|
+
const [sessionId, setSessionId] = useState('');
|
|
32
|
+
const [error, setError] = useState<string>('');
|
|
33
|
+
const { sessionLocation } = useSession();
|
|
34
|
+
const locationUuid = sessionLocation?.uuid;
|
|
35
|
+
|
|
36
|
+
async function withTimeout<T>(promise: Promise<T>, ms = 10000): Promise<T> {
|
|
37
|
+
const controller = new AbortController();
|
|
38
|
+
const timeout = setTimeout(() => controller.abort(), ms);
|
|
39
|
+
try {
|
|
40
|
+
const response = await promise;
|
|
41
|
+
return response;
|
|
42
|
+
} catch (err: any) {
|
|
43
|
+
if (err.name === 'AbortError') throw new Error('Request timeout');
|
|
44
|
+
throw err;
|
|
45
|
+
} finally {
|
|
46
|
+
clearTimeout(timeout);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const handleFetchCR = async () => {
|
|
51
|
+
setLoading(true);
|
|
52
|
+
setError('');
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
const payload = {
|
|
56
|
+
identificationNumber: identifierValue,
|
|
57
|
+
identificationType: identifierType,
|
|
58
|
+
locationUuid,
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const result = await withTimeout(fetchClientRegistryData(payload));
|
|
62
|
+
const patients = Array.isArray(result) ? result : [];
|
|
63
|
+
|
|
64
|
+
if (patients.length === 0) throw new Error('No matching patient found in Client Registry.');
|
|
65
|
+
|
|
66
|
+
const patient = patients[0];
|
|
67
|
+
applyClientRegistryMapping(patient, setFieldValue);
|
|
68
|
+
|
|
69
|
+
showSnackbar({
|
|
70
|
+
kind: 'success',
|
|
71
|
+
title: 'Client Data Loaded',
|
|
72
|
+
subtitle: `Patient ${patient.first_name} ${patient.last_name} fetched successfully.`,
|
|
73
|
+
});
|
|
74
|
+
} catch (err: any) {
|
|
75
|
+
const errorMessage = err.message || 'Failed to fetch client data';
|
|
76
|
+
setError(errorMessage);
|
|
77
|
+
showSnackbar({
|
|
78
|
+
kind: 'error',
|
|
79
|
+
title: 'Fetch Failed',
|
|
80
|
+
subtitle: errorMessage,
|
|
81
|
+
});
|
|
82
|
+
} finally {
|
|
83
|
+
setLoading(false);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const handleSendOtp = async () => {
|
|
88
|
+
if (!identifierValue.trim()) {
|
|
89
|
+
setError('Please enter a valid ID value');
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
setLoading(true);
|
|
94
|
+
setError('');
|
|
95
|
+
|
|
96
|
+
try {
|
|
97
|
+
const payload = {
|
|
98
|
+
identificationNumber: identifierValue,
|
|
99
|
+
identificationType: identifierType,
|
|
100
|
+
locationUuid,
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const response = await withTimeout(requestCustomOtp(payload));
|
|
104
|
+
setSessionId(response.sessionId);
|
|
105
|
+
setOtpSent(true);
|
|
106
|
+
|
|
107
|
+
showSnackbar({
|
|
108
|
+
kind: 'success',
|
|
109
|
+
title: 'OTP sent successfully',
|
|
110
|
+
subtitle: `A code was sent to ${response.maskedPhone}`,
|
|
111
|
+
});
|
|
112
|
+
} catch (err: any) {
|
|
113
|
+
const errorMessage = err.message || 'Failed to send OTP';
|
|
114
|
+
setError(errorMessage);
|
|
115
|
+
showSnackbar({
|
|
116
|
+
kind: 'error',
|
|
117
|
+
title: 'Error sending OTP',
|
|
118
|
+
subtitle: errorMessage,
|
|
119
|
+
});
|
|
120
|
+
} finally {
|
|
121
|
+
setLoading(false);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const handleVerifyOtp = async () => {
|
|
126
|
+
if (!otp.trim()) {
|
|
127
|
+
setError('Please enter the OTP code');
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
setLoading(true);
|
|
132
|
+
setError('');
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
const payload = { sessionId, otp, locationUuid };
|
|
136
|
+
await withTimeout(validateCustomOtp(payload));
|
|
137
|
+
|
|
138
|
+
setOtpVerified(true);
|
|
139
|
+
onClientVerified?.();
|
|
140
|
+
|
|
141
|
+
showSnackbar({
|
|
142
|
+
kind: 'success',
|
|
143
|
+
title: 'OTP Verified',
|
|
144
|
+
subtitle: 'You can now fetch data from Client Registry.',
|
|
145
|
+
});
|
|
146
|
+
} catch (err: any) {
|
|
147
|
+
const errorMessage = err.message || 'OTP verification failed';
|
|
148
|
+
setError(errorMessage);
|
|
149
|
+
showSnackbar({
|
|
150
|
+
kind: 'error',
|
|
151
|
+
title: 'OTP Verification Failed',
|
|
152
|
+
subtitle: errorMessage,
|
|
153
|
+
});
|
|
154
|
+
} finally {
|
|
155
|
+
setLoading(false);
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
return (
|
|
160
|
+
<div className={styles.section}>
|
|
161
|
+
<h4 className={styles.sectionTitle}>Client Registry Verification</h4>
|
|
162
|
+
|
|
163
|
+
{error && (
|
|
164
|
+
<div className={styles.notificationSpacing}>
|
|
165
|
+
<InlineNotification title="Error" subtitle={error} kind="error" lowContrast />
|
|
166
|
+
</div>
|
|
167
|
+
)}
|
|
168
|
+
|
|
169
|
+
<div className={styles.fieldGroup}>
|
|
170
|
+
<Dropdown
|
|
171
|
+
id="identifier-type-dropdown"
|
|
172
|
+
label="Identifier Type"
|
|
173
|
+
titleText="Select Identifier Type"
|
|
174
|
+
items={IDENTIFIER_TYPES}
|
|
175
|
+
selectedItem={identifierType}
|
|
176
|
+
onChange={({ selectedItem }) => setIdentifierType(selectedItem as IdentifierType)}
|
|
177
|
+
disabled={otpSent}
|
|
178
|
+
/>
|
|
179
|
+
</div>
|
|
180
|
+
|
|
181
|
+
<div className={styles.fieldGroup}>
|
|
182
|
+
<TextInput
|
|
183
|
+
id="identifier-value"
|
|
184
|
+
labelText={`${identifierType} Value`}
|
|
185
|
+
value={identifierValue}
|
|
186
|
+
onChange={(e) => setIdentifierValue(e.target.value)}
|
|
187
|
+
disabled={otpSent}
|
|
188
|
+
placeholder={`Enter ${identifierType.toLowerCase()} value`}
|
|
189
|
+
/>
|
|
190
|
+
</div>
|
|
191
|
+
|
|
192
|
+
<div style={{ marginTop: '0.75rem' }}>
|
|
193
|
+
{!otpSent ? (
|
|
194
|
+
<Button kind="secondary" onClick={handleSendOtp} disabled={loading}>
|
|
195
|
+
{loading ? <InlineLoading description="Sending..." /> : 'Send OTP'}
|
|
196
|
+
</Button>
|
|
197
|
+
) : (
|
|
198
|
+
<>
|
|
199
|
+
<div style={{ marginTop: '0.75rem' }}>
|
|
200
|
+
<TextInput
|
|
201
|
+
id="otp-input"
|
|
202
|
+
labelText="Enter OTP"
|
|
203
|
+
value={otp}
|
|
204
|
+
onChange={(e) => setOtp(e.target.value)}
|
|
205
|
+
disabled={otpVerified}
|
|
206
|
+
placeholder="Enter the code sent to your phone"
|
|
207
|
+
/>
|
|
208
|
+
</div>
|
|
209
|
+
|
|
210
|
+
<div style={{ marginTop: '0.5rem', display: 'flex', gap: '0.5rem' }}>
|
|
211
|
+
{!otpVerified ? (
|
|
212
|
+
<Button size="sm" kind="secondary" onClick={handleVerifyOtp} disabled={loading}>
|
|
213
|
+
{loading ? <InlineLoading description="Verifying..." /> : 'Verify OTP'}
|
|
214
|
+
</Button>
|
|
215
|
+
) : (
|
|
216
|
+
<Button kind="primary" onClick={handleFetchCR} disabled={loading}>
|
|
217
|
+
{loading ? <InlineLoading description="Fetching..." /> : 'Fetch Client Registry Data'}
|
|
218
|
+
</Button>
|
|
219
|
+
)}
|
|
220
|
+
{!otpVerified && (
|
|
221
|
+
<Button size="sm" kind="tertiary" onClick={() => setOtpSent(false)}>
|
|
222
|
+
Change ID
|
|
223
|
+
</Button>
|
|
224
|
+
)}
|
|
225
|
+
</div>
|
|
226
|
+
</>
|
|
227
|
+
)}
|
|
228
|
+
</div>
|
|
229
|
+
</div>
|
|
230
|
+
);
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
export default ClientRegistryLookupSection;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const HIE_BASE_URL = 'https://ngx.ampath.or.ke/hie';
|
|
2
|
+
|
|
3
|
+
export type RequestCustomOtpDto = {
|
|
4
|
+
identificationNumber: string | number;
|
|
5
|
+
identificationType: string;
|
|
6
|
+
locationUuid: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export interface RequestCustomOtpResponse {
|
|
10
|
+
message: string;
|
|
11
|
+
sessionId: string;
|
|
12
|
+
maskedPhone: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ValidateHieCustomOtpDto {
|
|
16
|
+
sessionId: string;
|
|
17
|
+
otp: number | string;
|
|
18
|
+
locationUuid: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface ValidateCustomOtpResponse {
|
|
22
|
+
message: string;
|
|
23
|
+
isValid?: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type ClientRegistrySearchRequest = {
|
|
27
|
+
identificationNumber: string | number;
|
|
28
|
+
identificationType: string;
|
|
29
|
+
locationUuid: string;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export type ClientRegistrySearchResponse = any[];
|
|
33
|
+
|
|
34
|
+
async function postJson<T>(url: string, payload: unknown): Promise<T> {
|
|
35
|
+
const response = await fetch(url, {
|
|
36
|
+
method: 'POST',
|
|
37
|
+
headers: { 'Content-Type': 'application/json' },
|
|
38
|
+
body: JSON.stringify(payload),
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
if (!response.ok) {
|
|
42
|
+
const errorText = await response.text();
|
|
43
|
+
throw new Error(`Request failed with ${response.status}: ${errorText}`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return response.json() as Promise<T>;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export async function requestCustomOtp(payload: RequestCustomOtpDto): Promise<RequestCustomOtpResponse> {
|
|
50
|
+
const url = `${HIE_BASE_URL}/client/send-custom-otp`;
|
|
51
|
+
const formattedPayload = {
|
|
52
|
+
identificationNumber: payload.identificationNumber,
|
|
53
|
+
identificationType: payload.identificationType,
|
|
54
|
+
locationUuid: payload.locationUuid,
|
|
55
|
+
};
|
|
56
|
+
return postJson<RequestCustomOtpResponse>(url, formattedPayload);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export async function validateCustomOtp(payload: ValidateHieCustomOtpDto): Promise<ValidateCustomOtpResponse> {
|
|
60
|
+
const url = `${HIE_BASE_URL}/client/validate-custom-otp`;
|
|
61
|
+
const formattedPayload = {
|
|
62
|
+
sessionId: payload.sessionId,
|
|
63
|
+
otp: payload.otp,
|
|
64
|
+
locationUuid: payload.locationUuid,
|
|
65
|
+
};
|
|
66
|
+
return postJson<ValidateCustomOtpResponse>(url, formattedPayload);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export async function fetchClientRegistryData(
|
|
70
|
+
payload: ClientRegistrySearchRequest,
|
|
71
|
+
): Promise<ClientRegistrySearchResponse> {
|
|
72
|
+
const url = `${HIE_BASE_URL}/client/search`;
|
|
73
|
+
const formattedPayload = {
|
|
74
|
+
identificationNumber: payload.identificationNumber,
|
|
75
|
+
identificationType: payload.identificationType,
|
|
76
|
+
locationUuid: payload.locationUuid,
|
|
77
|
+
};
|
|
78
|
+
return postJson<ClientRegistrySearchResponse>(url, formattedPayload);
|
|
79
|
+
}
|