@openmrs/esm-fast-data-entry-app 1.0.0-pre.59 → 1.0.1-pre.10

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.
Files changed (87) hide show
  1. package/.husky/pre-push +0 -0
  2. package/.tx/config +9 -0
  3. package/.yarn/plugins/@yarnpkg/plugin-version.cjs +550 -0
  4. package/.yarn/versions/45b499b6.yml +0 -0
  5. package/dist/openmrs-esm-fast-data-entry-app.js +1 -1
  6. package/jest.config.json +20 -18
  7. package/package.json +31 -38
  8. package/src/FormBootstrap.tsx +9 -2
  9. package/src/Root.tsx +12 -5
  10. package/src/add-group-modal/AddGroupModal.tsx +209 -0
  11. package/src/add-group-modal/styles.scss +35 -0
  12. package/src/context/FormWorkflowContext.tsx +1 -1
  13. package/src/context/FormWorkflowReducer.ts +1 -1
  14. package/src/context/GroupFormWorkflowContext.tsx +141 -0
  15. package/src/context/GroupFormWorkflowReducer.ts +272 -0
  16. package/src/empty-state/EmptyState.tsx +12 -8
  17. package/src/form-entry-workflow/FormEntryWorkflow.tsx +23 -13
  18. package/src/{form-review-card → form-entry-workflow/form-review-card}/FormReviewCard.tsx +3 -3
  19. package/src/{form-review-card → form-entry-workflow/form-review-card}/index.ts +0 -0
  20. package/src/form-entry-workflow/form-review-card/styles.scss +39 -0
  21. package/src/{patient-banner → form-entry-workflow/patient-banner}/PatientBanner.test.tsx +0 -0
  22. package/src/{patient-banner → form-entry-workflow/patient-banner}/PatientBanner.tsx +3 -3
  23. package/src/{patient-banner → form-entry-workflow/patient-banner}/index.ts +0 -0
  24. package/src/{patient-banner → form-entry-workflow/patient-banner}/styles.scss +8 -7
  25. package/src/{patient-search-header → form-entry-workflow/patient-search-header}/PatientSearchHeader.tsx +13 -11
  26. package/src/{patient-search-header → form-entry-workflow/patient-search-header}/index.ts +0 -0
  27. package/src/form-entry-workflow/patient-search-header/styles.scss +22 -0
  28. package/src/form-entry-workflow/styles.scss +14 -13
  29. package/src/{workflow-review → form-entry-workflow/workflow-review}/WorkflowReview.tsx +6 -6
  30. package/src/{workflow-review → form-entry-workflow/workflow-review}/index.ts +0 -0
  31. package/src/{workflow-review → form-entry-workflow/workflow-review}/styles.scss +0 -0
  32. package/src/forms-app-menu-link.tsx +2 -2
  33. package/src/forms-page/FormsPage.tsx +55 -21
  34. package/src/{forms-table → forms-page/forms-table}/FormsTable.tsx +14 -6
  35. package/src/{forms-table → forms-page/forms-table}/index.ts +0 -0
  36. package/src/{forms-table → forms-page/forms-table}/styles.scss +0 -0
  37. package/src/forms-page/styles.scss +5 -5
  38. package/src/group-form-entry-workflow/GroupFormEntryWorkflow.tsx +413 -0
  39. package/src/group-form-entry-workflow/group-banner/GroupBanner.test.tsx +9 -0
  40. package/src/group-form-entry-workflow/group-banner/GroupBanner.tsx +45 -0
  41. package/src/group-form-entry-workflow/group-banner/index.ts +3 -0
  42. package/src/group-form-entry-workflow/group-banner/styles.scss +60 -0
  43. package/src/group-form-entry-workflow/group-search/CompactGroupResults.tsx +106 -0
  44. package/src/group-form-entry-workflow/group-search/CompactGroupSearch.tsx +63 -0
  45. package/src/group-form-entry-workflow/group-search/GroupSearch.tsx +93 -0
  46. package/src/group-form-entry-workflow/group-search/compact-group-result.scss +64 -0
  47. package/src/group-form-entry-workflow/group-search/compact-group-search.scss +35 -0
  48. package/src/group-form-entry-workflow/group-search/group-search.scss +94 -0
  49. package/src/group-form-entry-workflow/group-search/mock-group-data.ts +79 -0
  50. package/src/group-form-entry-workflow/group-search/useGroupSearch.ts +14 -0
  51. package/src/group-form-entry-workflow/group-search-header/GroupSearchHeader.tsx +42 -0
  52. package/src/group-form-entry-workflow/group-search-header/index.ts +3 -0
  53. package/src/{patient-search-header → group-form-entry-workflow/group-search-header}/styles.scss +5 -6
  54. package/src/group-form-entry-workflow/index.ts +3 -0
  55. package/src/group-form-entry-workflow/styles.scss +86 -0
  56. package/src/hooks/useKeyPress.ts +31 -0
  57. package/src/hooks/usePostCohort.ts +18 -0
  58. package/src/index.ts +5 -1
  59. package/src/patient-card/PatientCard.tsx +11 -9
  60. package/src/patient-card/styles.scss +9 -8
  61. package/translations/en.json +30 -1
  62. package/.github/pull_request_template.md +0 -18
  63. package/.github/workflows/node.js.yml +0 -121
  64. package/dist/132.js +0 -1
  65. package/dist/187.js +0 -1
  66. package/dist/247.js +0 -1
  67. package/dist/294.js +0 -2
  68. package/dist/294.js.LICENSE.txt +0 -14
  69. package/dist/312.js +0 -1
  70. package/dist/412.js +0 -1
  71. package/dist/536.js +0 -2
  72. package/dist/536.js.LICENSE.txt +0 -8
  73. package/dist/574.js +0 -1
  74. package/dist/592.js +0 -1
  75. package/dist/595.js +0 -2
  76. package/dist/595.js.LICENSE.txt +0 -1
  77. package/dist/776.js +0 -1
  78. package/dist/804.js +0 -1
  79. package/dist/880.js +0 -2
  80. package/dist/880.js.LICENSE.txt +0 -20
  81. package/dist/906.js +0 -1
  82. package/dist/935.js +0 -2
  83. package/dist/935.js.LICENSE.txt +0 -23
  84. package/dist/990.js +0 -1
  85. package/dist/openmrs-esm-fast-data-entry-app.js.buildmanifest.json +0 -433
  86. package/dist/openmrs-esm-fast-data-entry-app.old +0 -1
  87. package/src/form-review-card/styles.scss +0 -38
File without changes
@@ -1 +1 @@
1
- System.register("@openmrs/esm-fast-data-entry-app",[],function(a,b){var c=void 0;return{execute:function(){a((()=>{function g(a){var b=m[a];if(void 0!==b)return b.exports;var c=m[a]={id:a,loaded:!1,exports:{}};return G[a].call(c.exports,c,c.exports,g),c.loaded=!0,c.exports}var j,k,q,w,x,y,z,A,B,C,r,D,E,F,G={1858:(a,b,c)=>{(0,c(2722).s)(1)},2722:(a,b,c)=>{const d=c(3905).R;b.s=function(a){if(a||(a=1),!c.y.meta||!c.y.meta.url)throw console.error("__system_context__",c.y),Error("systemjs-webpack-interop was provided an unknown SystemJS context. Expected context.meta.url, but none was provided");c.p=d(c.y.meta.url,a)}},5356:(a,b,c)=>{c(1858)},3905:(a,b)=>{b.R=function(b,c){var d=document.createElement("a");d.href=b;for(var e="/"===d.pathname[0]?d.pathname:"/"+d.pathname,f=0,g=e.length;f!==c&&0<=g;)"/"===e[--g]&&f++;if(f!==c)throw Error("systemjs-webpack-interop: rootDirectoryLevel ("+c+") is greater than the number of directories ("+f+") in the URL path "+b);var h=e.slice(0,g+1);return d.protocol+"//"+d.host+h},Number.isInteger},6751:(b,d,f)=>{var g={app:()=>(c||((self.webpackChunk_openmrs_esm_fast_data_entry_app=self.webpackChunk_openmrs_esm_fast_data_entry_app||[]).push([[132],{8132:(b,c,d)=>{function e(){var b={featureName:"fast-data-entry-app",moduleName:"@openmrs/esm-fast-data-entry-app"};return(0,f.defineConfigSchema)("@openmrs/esm-fast-data-entry-app",a),(0,f.registerBreadcrumbs)([{path:"".concat(window.spaBase,"/forms"),title:"Forms",parent:"".concat(window.spaBase,"/home")}]),{pages:[{load:(0,f.getAsyncLifecycle)(function(){return Promise.all([d.e(211),d.e(804)]).then(d.bind(d,9804))},b),route:"forms"}],extensions:[{name:"forms-app-link",slot:"app-menu-slot",load:(0,f.getAsyncLifecycle)(function(){return Promise.all([d.e(211),d.e(397),d.e(776)]).then(d.bind(d,5776))},b),online:!0,offline:!0}]}}d.r(c),d.d(c,{backendDependencies:()=>h,importTranslation:()=>g,setupOpenMRS:()=>e,assets:()=>["187.js","247.js","294.js","312.js","412.js","openmrs-esm-fast-data-entry-app.js","536.js","574.js","592.js","595.js","776.js","804.js","880.js","906.js","935.js","990.js"]});var f=d(311),a={formCategories:{_type:f.Type.Array,_description:"Organize forms into categories. A form can belong to multiple categories.",_elements:{name:{_type:f.Type.String,_description:"Category name"},forms:{_type:f.Type.Array,_description:"List of forms for this category.",_elements:{formUUID:{_type:f.Type.UUID,_description:"UUID of form"},name:{_type:f.Type.String,_description:"Name of form"}}}},_default:[{name:"ICRC Forms",forms:[{formUUID:"0cefb866-110c-4f16-af58-560932a1db1f",name:"Adult Triage"}]},{name:"Distress Scales",forms:[{formUUID:"9f26aad4-244a-46ca-be49-1196df1a8c9a",name:"POC Sample Form 1"}]}]},formCategoriesToShow:{_type:f.Type.Array,_description:"Forms to show by default on the forms app home page.",_elements:{_type:f.Type.String,_description:"Name of category"},_default:["ICRC Forms","Distress Scales"]}},g=d(3979),h={fhir2:"^1.2.0","webservices.rest":"^2.2.0"}},3979:(b,c,d)=>{function e(a){if(!d.o(f,a))return Promise.resolve().then(()=>{var b=new Error("Cannot find module '"+a+"'");throw b.code="MODULE_NOT_FOUND",b});var b=f[a],c=b[0];return d.e(b[1]).then(()=>d(c))}var f={"./en.json":[3574,574]};e.keys=()=>Object.keys(f),e.id=3979,b.exports=e}}]),c=f.e(132).then(()=>()=>f(8132))),c)},e=(a,b)=>(f.R=b,b=f.o(g,a)?g[a]():Promise.resolve().then(()=>{throw new Error("Module \""+a+"\" does not exist in container.")}),f.R=void 0,b),h=(a,b)=>{if(f.S){var c=f.S["default"];if(c&&c!==a)throw new Error("Container initialization failed as it has already been initialized with a different share scope");return f.S["default"]=a,f.I("default",b)}};f.d(d,{get:()=>e,init:()=>h})}},m={};return g.m=G,g.c=m,g.y=b,g.n=a=>{var b=a&&a.__esModule?()=>a.default:()=>a;return g.d(b,{a:b}),b},g.d=(a,b)=>{for(var c in b)g.o(b,c)&&!g.o(a,c)&&Object.defineProperty(a,c,{enumerable:!0,get:b[c]})},g.f={},g.e=a=>Promise.all(Object.keys(g.f).reduce((b,c)=>(g.f[c](a,b),b),[])),g.u=a=>a+".js",g.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(a){if("object"==typeof window)return window}}(),g.o=(a,b)=>Object.prototype.hasOwnProperty.call(a,b),j={},k="@openmrs/esm-fast-data-entry-app:",g.l=(a,b,c)=>{if(j[a])j[a].push(b);else{var e,h;if(void 0!==c)for(var m,n=document.getElementsByTagName("script"),o=0;o<n.length;o++)if(m=n[o],m.getAttribute("src")==a||m.getAttribute("data-webpack")==k+c){e=m;break}e||(h=!0,(e=document.createElement("script")).charset="utf-8",e.timeout=120,g.nc&&e.setAttribute("nonce",g.nc),e.setAttribute("data-webpack",k+c),e.src=a),j[a]=[b];var q=(b,c)=>{e.onerror=e.onload=null,clearTimeout(d);var f=j[a];if(delete j[a],e.parentNode&&e.parentNode.removeChild(e),f&&f.forEach(a=>a(c)),b)return b(c)},d=setTimeout(q.bind(null,void 0,{type:"timeout",target:e}),12e4);e.onerror=q.bind(null,e.onerror),e.onload=q.bind(null,e.onload),h&&document.head.appendChild(e)}},g.r=a=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(a,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(a,"__esModule",{value:!0})},g.nmd=a=>(a.paths=[],a.children||(a.children=[]),a),(()=>{g.S={};var b={},c={};g.I=(d,e)=>{e||(e=[]);var f=c[d];if(f||(f=c[d]={}),!(0<=e.indexOf(f))){if(e.push(f),b[d])return b[d];g.o(g.S,d)||(g.S[d]={});var h=g.S[d],a=(a,b,c,d)=>{var e=h[a]=h[a]||{},f=e[b];f&&(f.loaded||(!d==!f.eager?!("@openmrs/esm-fast-data-entry-app">f.from):!d))||(e[b]={get:c,from:"@openmrs/esm-fast-data-entry-app",eager:!!d})},i=[];return"default"===d&&(a("@openmrs/esm-framework","3.4.1-pre.189",()=>Promise.all([g.e(595),g.e(211)]).then(()=>()=>g(595))),a("carbon-icons","7.0.7",()=>g.e(906).then(()=>()=>g(906))),a("react-dom","16.14.0",()=>Promise.all([g.e(935),g.e(211)]).then(()=>()=>g(3935))),a("react-i18next","11.18.3",()=>Promise.all([g.e(247),g.e(211)]).then(()=>()=>g(8247))),a("react-router-dom","5.3.3",()=>Promise.all([g.e(536),g.e(211)]).then(()=>()=>g(536))),a("react","16.14.0",()=>g.e(294).then(()=>()=>g(7294)))),b[d]=i.length?Promise.all(i).then(()=>b[d]=1):1}}})(),g.p="",q=a=>{var b=a=>a.split(".").map(a=>+a==a?+a:a),c=/^([^-+]+)?(?:-([^+]+))?(?:\+(.+))?$/.exec(a),d=c[1]?b(c[1]):[];return c[2]&&(d.length++,d.push.apply(d,b(c[2]))),c[3]&&(d.push([]),d.push.apply(d,b(c[3]))),d},w=(b,c)=>{b=q(b),c=q(c);for(var d=0;;){if(d>=b.length)return d<c.length&&"u"!=(typeof c[d])[0];var f=b[d],g=(typeof f)[0];if(d>=c.length)return"u"==g;var a=c[d],h=(typeof a)[0];if(g!=h)return"o"==g&&"n"==h||"s"==h||"u"==g;if("o"!=g&&"u"!=g&&f!=a)return f<a;d++}},x=a=>{function b(){return g.pop().replace(/^\((.+)\)$/,"$1")}var c=a[0],d="";if(1===a.length)return"*";if(c+.5){d+=0==c?">=":-1==c?"<":1==c?"^":2==c?"~":0<c?"=":"!=";for(var e=1,f=1;f<a.length;f++)e--,d+="u"==(typeof(h=a[f]))[0]?"-":(0<e?".":"")+(e=2,h);return d}var g=[];for(f=1;f<a.length;f++){var h=a[f];g.push(0===h?"not("+b()+")":1===h?"("+b()+" || "+b()+")":2===h?g.pop()+" "+g.pop():x(h))}return b()},y=(b,e)=>{if(0 in b){e=q(e);var g=b[0],i=0>g;i&&(g=-g-1);for(var j=0,k=1,m=!0;;k++,j++){var n,o,v=k<b.length?(typeof b[k])[0]:"";if(j>=e.length||"o"==(o=(typeof(n=e[j]))[0]))return!m||("u"==v?k>g&&!i:""==v!=i);if("u"==o){if(!m||"u"!=v)return!1;}else if(!m)"s"!=v&&"n"!=v&&(m=!1,k--);else if(v==o){if(!(k<=g)){if(i?n>b[k]:n<b[k])return!1;n!=b[k]&&(m=!1)}else if(n!=b[k])return!1;}else if("s"!=v&&"n"!=v){if(i||k<=g)return!1;m=!1,k--}else{if(k<=g||o<v!=i)return!1;m=!1}}}var d=[],p=d.pop.bind(d);for(j=1;j<b.length;j++){var c=b[j];d.push(1==c?p()|p():2==c?p()&p():c?y(c,e):!p())}return!!p()},z=(a,b)=>{var c=a[b];return Object.keys(c).reduce((a,b)=>a&&(c[a].loaded||!w(a,b))?a:b,0)},A=(a,b,c,d)=>"Unsatisfied version "+c+" from "+(c&&a[b][c].from)+" of shared singleton module "+b+" (required "+x(d)+")",B=(a,b,c,d)=>{var e=z(a,c);return y(d,e)||"undefined"!=typeof console&&console.warn&&console.warn(A(a,c,e,d)),C(a[c][e])},C=a=>(a.loaded=1,a.get()),r=(b=>function(c,d,e,f){var h=g.I(c);return h&&h.then?h.then(b.bind(b,c,g.S[c],d,e,f)):b(0,g.S[c],d,e,f)})((a,b,c,d,e)=>b&&g.o(b,c)?B(b,0,c,d):e()),D={},E={311:()=>r("default","@openmrs/esm-framework",[1,"next"],()=>Promise.all([g.e(595),g.e(211)]).then(()=>()=>g(595))),4211:()=>r("default","react",[1,16,14],()=>g.e(294).then(()=>()=>g(7294))),2221:()=>r("default","react-router-dom",[1,5,0,0],()=>g.e(536).then(()=>()=>g(536))),3397:()=>r("default","react-i18next",[1,11],()=>g.e(247).then(()=>()=>g(8247))),8408:()=>r("default","react-dom",[1,16,0],()=>g.e(935).then(()=>()=>g(3935)))},F={132:[311],211:[4211],397:[3397],804:[2221],990:[8408]},g.f.consumes=(a,b)=>{g.o(F,a)&&F[a].forEach(a=>{if(g.o(D,a))return b.push(D[a]);var c=b=>{D[a]=0,g.m[a]=c=>{delete g.c[a],c.exports=b()}},d=b=>{delete D[a],g.m[a]=()=>{throw delete g.c[a],b}};try{var e=E[a]();e.then?b.push(D[a]=e.then(c).catch(d)):c(e)}catch(a){d(a)}})},(()=>{var b={447:0};g.f.j=(c,d)=>{var e=g.o(b,c)?b[c]:void 0;if(0!==e)if(e)d.push(e[2]);else if(/^(211|397)$/.test(c))b[c]=0;else{var f=new Promise((a,d)=>e=b[c]=[a,d]);d.push(e[2]=f);var h=g.p+g.u(c),j=new Error;g.l(h,d=>{if(g.o(b,c)&&(0!==(e=b[c])&&(b[c]=void 0),e)){var f=d&&("load"===d.type?"missing":d.type),h=d&&d.target&&d.target.src;j.message="Loading chunk "+c+" failed.\n("+f+": "+h+")",j.name="ChunkLoadError",j.type=f,j.request=h,e[1](j)}},"chunk-"+c,c)}};var a=(c,d)=>{var e,f,[h,a,i]=d,j=0;if(h.some(a=>0!==b[a])){for(e in a)g.o(a,e)&&(g.m[e]=a[e]);i&&i(g)}for(c&&c(d);j<h.length;j++)f=h[j],g.o(b,f)&&b[f]&&b[f][0](),b[f]=0},c=self.webpackChunk_openmrs_esm_fast_data_entry_app=self.webpackChunk_openmrs_esm_fast_data_entry_app||[];c.forEach(a.bind(null,0)),c.push=a.bind(null,c.push.bind(c))})(),g.nc=void 0,g(5356),g(6751)})())}}});
1
+ var _openmrs_esm_fast_data_entry_app;(()=>{function b(a){var c=h[a];if(void 0!==c)return c.exports;var d=h[a]={id:a,loaded:!1,exports:{}};return G[a].call(d.exports,d,d.exports,b),d.loaded=!0,d.exports}var j,k,q,v,w,x,y,z,A,B,C,D,E,F,G={7140:(b,c,d)=>{var f={"./start":()=>d.e(132).then(()=>()=>d(8132))},e=(a,b)=>(d.R=b,b=d.o(f,a)?f[a]():Promise.resolve().then(()=>{throw new Error("Module \""+a+"\" does not exist in container.")}),d.R=void 0,b),a=(b,c)=>{if(d.S){var e=d.S["default"];if(e&&e!==b)throw new Error("Container initialization failed as it has already been initialized with a different share scope");return d.S["default"]=b,d.I("default",c)}};d.d(c,{get:()=>e,init:()=>a})}},h={};b.m=G,b.c=h,b.n=a=>{var c=a&&a.__esModule?()=>a.default:()=>a;return b.d(c,{a:c}),c},b.d=(a,c)=>{for(var d in c)b.o(c,d)&&!b.o(a,d)&&Object.defineProperty(a,d,{enumerable:!0,get:c[d]})},b.f={},b.e=a=>Promise.all(Object.keys(b.f).reduce((c,d)=>(b.f[d](a,c),c),[])),b.u=a=>a+".js",b.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(a){if("object"==typeof window)return window}}(),b.o=(a,b)=>Object.prototype.hasOwnProperty.call(a,b),j={},k="@openmrs/esm-fast-data-entry-app:",b.l=(c,e,g)=>{if(j[c])j[c].push(e);else{var h,a;if(void 0!==g)for(var m,n=document.getElementsByTagName("script"),o=0;o<n.length;o++)if(m=n[o],m.getAttribute("src")==c||m.getAttribute("data-webpack")==k+g){h=m;break}h||(a=!0,(h=document.createElement("script")).charset="utf-8",h.timeout=120,b.nc&&h.setAttribute("nonce",b.nc),h.setAttribute("data-webpack",k+g),h.src=c),j[c]=[e];var q=(b,f)=>{h.onerror=h.onload=null,clearTimeout(d);var e=j[c];if(delete j[c],h.parentNode&&h.parentNode.removeChild(h),e&&e.forEach(a=>a(f)),b)return b(f)},d=setTimeout(q.bind(null,void 0,{type:"timeout",target:h}),12e4);h.onerror=q.bind(null,h.onerror),h.onload=q.bind(null,h.onload),a&&document.head.appendChild(h)}},b.r=a=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(a,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(a,"__esModule",{value:!0})},b.nmd=a=>(a.paths=[],a.children||(a.children=[]),a),(()=>{b.S={};var c={},d={};b.I=(e,f)=>{f||(f=[]);var g=d[e];if(g||(g=d[e]={}),!(0<=f.indexOf(g))){if(f.push(g),c[e])return c[e];b.o(b.S,e)||(b.S[e]={});var h=b.S[e],i=(b,c,d,e)=>{var f=h[b]=h[b]||{},a=f[c];a&&(a.loaded||(!e==!a.eager?!("@openmrs/esm-fast-data-entry-app">a.from):!e))||(f[c]={get:d,from:"@openmrs/esm-fast-data-entry-app",eager:!!e})},j=[];return"default"===e&&(i("@carbon/react","1.11.0",()=>Promise.all([b.e(820),b.e(327),b.e(569),b.e(672),b.e(183)]).then(()=>()=>b(8569))),i("@openmrs/esm-framework","4.0.2-pre.275",()=>Promise.all([b.e(595),b.e(672)]).then(()=>()=>b(595))),i("react-dom","18.2.0",()=>Promise.all([b.e(935),b.e(672)]).then(()=>()=>b(3935))),i("react-i18next","11.18.5",()=>Promise.all([b.e(247),b.e(672)]).then(()=>()=>b(8247))),i("react-router-dom","6.3.0",()=>Promise.all([b.e(68),b.e(672)]).then(()=>()=>b(6068))),i("react","18.2.0",()=>b.e(294).then(()=>()=>b(7294)))),c[e]=j.length?Promise.all(j).then(()=>c[e]=1):1}}})(),(()=>{var a;b.g.importScripts&&(a=b.g.location+"");var c=b.g.document;if(!a&&c&&(c.currentScript&&(a=c.currentScript.src),!a)){var d=c.getElementsByTagName("script");d.length&&(a=d[d.length-1].src)}if(!a)throw new Error("Automatic publicPath is not supported in this browser");a=a.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),b.p=a})(),q=a=>{var b=a=>a.split(".").map(a=>+a==a?+a:a),c=/^([^-+]+)?(?:-([^+]+))?(?:\+(.+))?$/.exec(a),d=c[1]?b(c[1]):[];return c[2]&&(d.length++,d.push.apply(d,b(c[2]))),c[3]&&(d.push([]),d.push.apply(d,b(c[3]))),d},v=(b,c)=>{b=q(b),c=q(c);for(var d=0;;){if(d>=b.length)return d<c.length&&"u"!=(typeof c[d])[0];var f=b[d],a=(typeof f)[0];if(d>=c.length)return"u"==a;var g=c[d],h=(typeof g)[0];if(a!=h)return"o"==a&&"n"==h||"s"==h||"u"==a;if("o"!=a&&"u"!=a&&f!=g)return f<g;d++}},w=a=>{function b(){return g.pop().replace(/^\((.+)\)$/,"$1")}var c=a[0],d="";if(1===a.length)return"*";if(c+.5){d+=0==c?">=":-1==c?"<":1==c?"^":2==c?"~":0<c?"=":"!=";for(var e=1,f=1;f<a.length;f++)e--,d+="u"==(typeof(h=a[f]))[0]?"-":(0<e?".":"")+(e=2,h);return d}var g=[];for(f=1;f<a.length;f++){var h=a[f];g.push(0===h?"not("+b()+")":1===h?"("+b()+" || "+b()+")":2===h?g.pop()+" "+g.pop():w(h))}return b()},x=(b,e)=>{if(0 in b){e=q(e);var g=b[0],j=0>g;j&&(g=-g-1);for(var a=0,k=1,m=!0;;k++,a++){var o,t,v=k<b.length?(typeof b[k])[0]:"";if(a>=e.length||"o"==(t=(typeof(o=e[a]))[0]))return!m||("u"==v?k>g&&!j:""==v!=j);if("u"==t){if(!m||"u"!=v)return!1;}else if(!m)"s"!=v&&"n"!=v&&(m=!1,k--);else if(v==t){if(!(k<=g)){if(j?o>b[k]:o<b[k])return!1;o!=b[k]&&(m=!1)}else if(o!=b[k])return!1;}else if("s"!=v&&"n"!=v){if(j||k<=g)return!1;m=!1,k--}else{if(k<=g||t<v!=j)return!1;m=!1}}}var d=[],p=d.pop.bind(d);for(a=1;a<b.length;a++){var c=b[a];d.push(1==c?p()|p():2==c?p()&p():c?x(c,e):!p())}return!!p()},y=(a,b)=>{var c=a[b];return Object.keys(c).reduce((a,b)=>a&&(c[a].loaded||!v(a,b))?a:b,0)},z=(a,b,c,d)=>"Unsatisfied version "+c+" from "+(c&&a[b][c].from)+" of shared singleton module "+b+" (required "+w(d)+")",A=(b,c,d,e)=>{var f=y(b,d);return x(e,f)||"undefined"!=typeof console&&console.warn&&console.warn(z(b,d,f,e)),B(b[d][f])},B=a=>(a.loaded=1,a.get()),C=(c=>function(d,e,f,g){var a=b.I(d);return a&&a.then?a.then(c.bind(c,d,b.S[d],e,f,g)):c(0,b.S[d],e,f,g)})((c,d,e,f,g)=>d&&b.o(d,e)?A(d,0,e,f):g()),D={},E={1672:()=>C("default","react",[1,18],()=>b.e(294).then(()=>()=>b(7294))),5183:()=>C("default","react-dom",[1,18],()=>b.e(935).then(()=>()=>b(3935))),1132:()=>C("default","@openmrs/esm-framework",[0],()=>Promise.all([b.e(595),b.e(672)]).then(()=>()=>b(595))),1338:()=>C("default","react-router-dom",[1,6],()=>b.e(68).then(()=>()=>b(6068))),3397:()=>C("default","react-i18next",[1,11],()=>b.e(247).then(()=>()=>b(8247))),4422:()=>C("default","@carbon/react",[1,1,9,0],()=>Promise.all([b.e(820),b.e(327),b.e(569),b.e(183)]).then(()=>()=>b(8569)))},F={132:[1132],183:[5183],397:[3397],672:[1672],804:[1338],877:[4422]},b.f.consumes=(a,c)=>{b.o(F,a)&&F[a].forEach(d=>{if(b.o(D,d))return c.push(D[d]);var e=a=>{D[d]=0,b.m[d]=c=>{delete b.c[d],c.exports=a()}},f=a=>{delete D[d],b.m[d]=()=>{throw delete b.c[d],a}};try{var g=E[d]();g.then?c.push(D[d]=g.then(e).catch(f)):e(g)}catch(a){f(a)}})},(()=>{var c={447:0};b.f.j=(d,e)=>{var f=b.o(c,d)?c[d]:void 0;if(0!==f)if(f)e.push(f[2]);else if(/^(183|397|672)$/.test(d))c[d]=0;else{var g=new Promise((b,e)=>f=c[d]=[b,e]);e.push(f[2]=g);var a=b.p+b.u(d),h=new Error;b.l(a,e=>{if(b.o(c,d)&&(0!==(f=c[d])&&(c[d]=void 0),f)){var g=e&&("load"===e.type?"missing":e.type),a=e&&e.target&&e.target.src;h.message="Loading chunk "+d+" failed.\n("+g+": "+a+")",h.name="ChunkLoadError",h.type=g,h.request=a,f[1](h)}},"chunk-"+d,d)}};var a=(d,e)=>{var f,g,[h,j,i]=e,k=0;if(h.some(a=>0!==c[a])){for(f in j)b.o(j,f)&&(b.m[f]=j[f]);i&&i(b)}for(d&&d(e);k<h.length;k++)g=h[k],b.o(c,g)&&c[g]&&c[g][0](),c[g]=0},d=self.webpackChunk_openmrs_esm_fast_data_entry_app=self.webpackChunk_openmrs_esm_fast_data_entry_app||[];d.forEach(a.bind(null,0)),d.push=a.bind(null,d.push.bind(d))})(),b.nc=void 0;var m=b(7140);_openmrs_esm_fast_data_entry_app=m})();
package/jest.config.json CHANGED
@@ -1,18 +1,20 @@
1
- {
2
- "transform": {
3
- "^.+\\.tsx?$": "babel-jest"
4
- },
5
- "transformIgnorePatterns": [
6
- "/node_modules/(?!@openmrs)"
7
- ],
8
- "moduleNameMapper": {
9
- "^@carbon/icons-react/es/(.*)$": "@carbon/icons-react/lib/$1",
10
- "^carbon-components-react/es/(.*)$": "carbon-components-react/lib/$1",
11
- "@openmrs/esm-framework": "@openmrs/esm-framework/mock",
12
- "\\.(s?css)$": "identity-obj-proxy"
13
- },
14
- "setupFilesAfterEnv": [
15
- "<rootDir>/src/setup-tests.ts"
16
- ],
17
- "testEnvironment": "jsdom"
18
- }
1
+
2
+ {
3
+ "transform": {
4
+ "^.+\\.tsx?$": "@swc/jest"
5
+ },
6
+ "transformIgnorePatterns": ["/node_modules/(?!@openmrs)"],
7
+ "moduleNameMapper": {
8
+ "\\.(s?css)$": "identity-obj-proxy",
9
+ "@openmrs/esm-framework": "@openmrs/esm-framework/mock",
10
+ "^lodash-es/(.*)$": "lodash/$1",
11
+ "^uuid$": "<rootDir>/node_modules/uuid/dist/index.js"
12
+ },
13
+ "setupFilesAfterEnv": [
14
+ "<rootDir>/src/setup-tests.ts"
15
+ ],
16
+ "testEnvironment": "jsdom",
17
+ "testEnvironmentOptions": {
18
+ "url": "http://localhost/"
19
+ }
20
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openmrs/esm-fast-data-entry-app",
3
- "version": "1.0.0-pre.59",
3
+ "version": "1.0.1-pre.10",
4
4
  "license": "MPL-2.0",
5
5
  "description": "An OpenMRS 3.x microfrontend",
6
6
  "browser": "dist/openmrs-esm-fast-data-entry-app.js",
@@ -42,43 +42,29 @@
42
42
  "bugs": {
43
43
  "url": "https://github.com/openmrs/openmrs-esm-fast-data-entry-app/issues"
44
44
  },
45
- "resolutions": {
46
- "**/@types/react": "^16.14.5"
47
- },
48
- "dependencies": {},
49
45
  "peerDependencies": {
50
- "@openmrs/esm-framework": "next",
51
- "carbon-icons": "7.x",
52
- "dayjs": "1.x",
53
- "react": "^16.14",
54
- "react-dom": "^16.0",
46
+ "@carbon/react": "^1.9.0",
47
+ "@openmrs/esm-framework": "*",
48
+ "react": "18.x",
49
+ "react-dom": "18.x",
55
50
  "react-i18next": "11.x",
56
- "react-router-dom": "^5.0.0"
51
+ "react-router-dom": "6.x"
57
52
  },
58
53
  "devDependencies": {
59
- "@babel/core": "^7.14.3",
60
- "@babel/plugin-proposal-class-properties": "^7.13.0",
61
- "@babel/preset-env": "^7.14.4",
62
- "@babel/preset-react": "^7.13.13",
63
- "@babel/preset-typescript": "^7.13.0",
64
- "@babel/runtime": "^7.14.0",
54
+ "@carbon/react": "^1.9.0",
65
55
  "@openmrs/esm-framework": "next",
56
+ "@swc/core": "^1.2.245",
57
+ "@swc/jest": "^0.2.22",
66
58
  "@testing-library/dom": "^7.20.0",
67
- "@testing-library/jest-dom": "^5.11.0",
68
- "@testing-library/react": "^10.4.3",
69
- "@testing-library/user-event": "^12.0.11",
70
- "@types/carbon-components-react": "^7.34.0",
71
- "@types/carbon__icons-react": "^10.31.0",
72
- "@types/jest": "^26.0.23",
73
- "@types/react": "^16.14.5",
74
- "@types/react-dom": "^16.9.12",
75
- "@types/react-router-dom": "^5.1.7",
76
- "@types/testing-library__jest-dom": "^5.14.1",
59
+ "@testing-library/jest-dom": "^5.16.5",
60
+ "@testing-library/react": "^13.3.0",
61
+ "@testing-library/user-event": "^14.4.3",
62
+ "@types/jest": "^28.1.7",
63
+ "@types/react-dom": "^18.0.6",
64
+ "@types/react-router-dom": "^5.3.3",
65
+ "@types/testing-library__jest-dom": "^5.14.5",
77
66
  "@types/webpack-env": "^1.16.0",
78
67
  "@typescript-eslint/parser": "^5.14.0",
79
- "babel-eslint": "^10.1.0",
80
- "babel-jest": "^27.0.2",
81
- "babel-preset-minify": "^0.5.1",
82
68
  "concurrently": "^6.2.0",
83
69
  "eslint": "^8.20.0",
84
70
  "eslint-config-prettier": "^8.3.0",
@@ -87,18 +73,25 @@
87
73
  "eslint-plugin-prettier": "^4.2.1",
88
74
  "husky": "^8.0.1",
89
75
  "identity-obj-proxy": "^3.0.0",
90
- "jest": "^26.4.2",
91
- "jest-cli": "^26.4.2",
76
+ "jest": "^28.1.3",
77
+ "jest-cli": "^28.1.3",
78
+ "jest-environment-jsdom": "^28.1.3",
92
79
  "openmrs": "next",
93
80
  "prettier": "^2.3.0",
94
81
  "pretty-quick": "^3.1.0",
95
- "react": "^16.14",
96
- "react-dom": "^16.0.0",
97
- "react-i18next": "^11.16.9",
98
- "react-router-dom": "^5.0.0",
82
+ "react": "^18.2.0",
83
+ "react-dom": "^18.2.0",
84
+ "react-i18next": "^11.18.4",
85
+ "react-router-dom": "^6.3.0",
86
+ "semver": "^7.3.7",
99
87
  "swc-loader": "^0.2.3",
100
88
  "swr": "^1.3.0",
101
89
  "typescript": "^4.7.3",
102
90
  "webpack": "^5.73.0"
103
- }
104
- }
91
+ },
92
+ "packageManager": "yarn@3.2.2",
93
+ "dependencies": {
94
+ "react-hook-form": "^7.34.2"
95
+ },
96
+ "stableVersion": "1.0.0"
97
+ }
@@ -1,5 +1,5 @@
1
- import React from "react";
2
- import { ExtensionSlot } from "@openmrs/esm-framework";
1
+ import React, { useEffect } from "react";
2
+ import { detach, ExtensionSlot } from "@openmrs/esm-framework";
3
3
  import useGetPatient from "./hooks/useGetPatient";
4
4
 
5
5
  export interface Order {
@@ -106,6 +106,7 @@ interface FormParams {
106
106
  encounterUuid?: string;
107
107
  showDiscardSubmitButtons?: boolean;
108
108
  handlePostResponse?: (Encounter) => void;
109
+ handleEncounterCreate?: (Object) => void;
109
110
  }
110
111
 
111
112
  const FormBootstrap = ({
@@ -115,9 +116,14 @@ const FormBootstrap = ({
115
116
  visitTypeUuid,
116
117
  encounterUuid,
117
118
  handlePostResponse,
119
+ handleEncounterCreate,
118
120
  }: FormParams) => {
119
121
  const patient = useGetPatient(patientUuid);
120
122
 
123
+ useEffect(() => {
124
+ return () => detach("form-widget-slot", "form-widget-slot");
125
+ });
126
+
121
127
  return (
122
128
  <div>
123
129
  {formUuid && patientUuid && patient && (
@@ -133,6 +139,7 @@ const FormBootstrap = ({
133
139
  encounterUuid: encounterUuid ?? "",
134
140
  closeWorkspace: () => undefined,
135
141
  handlePostResponse,
142
+ handleEncounterCreate,
136
143
  showDiscardSubmitButtons: false,
137
144
  }}
138
145
  />
package/src/Root.tsx CHANGED
@@ -1,17 +1,24 @@
1
1
  import React from "react";
2
- import { BrowserRouter, Route, Switch } from "react-router-dom";
2
+ import { BrowserRouter, Route, Routes } from "react-router-dom";
3
3
  import { appPath } from "./constant";
4
4
  const FormsPage = React.lazy(() => import("./forms-page"));
5
5
  const FormEntryWorkflow = React.lazy(() => import("./form-entry-workflow"));
6
+ const GroupFormEntryWorkflow = React.lazy(
7
+ () => import("./group-form-entry-workflow")
8
+ );
6
9
 
7
10
  const Root = () => {
8
11
  return (
9
12
  <main>
10
13
  <BrowserRouter basename={appPath}>
11
- <Switch>
12
- <Route exact path="/" children={<FormsPage />} />
13
- <Route path="/:formUuid?" children={<FormEntryWorkflow />} />
14
- </Switch>
14
+ <Routes>
15
+ <Route path="/" element={<FormsPage />} />
16
+ <Route path="/form/:formUuid" element={<FormEntryWorkflow />} />
17
+ <Route
18
+ path="/groupform/:formUuid"
19
+ element={<GroupFormEntryWorkflow />}
20
+ />
21
+ </Routes>
15
22
  </BrowserRouter>
16
23
  </main>
17
24
  );
@@ -0,0 +1,209 @@
1
+ import React, { useCallback, useContext, useState } from "react";
2
+ import {
3
+ ComposedModal,
4
+ Button,
5
+ ModalHeader,
6
+ ModalFooter,
7
+ ModalBody,
8
+ TextInput,
9
+ FormLabel,
10
+ } from "@carbon/react";
11
+ import { Add, Close } from "@carbon/react/icons";
12
+ import { useTranslation } from "react-i18next";
13
+ import { ExtensionSlot } from "@openmrs/esm-framework";
14
+ import styles from "./styles.scss";
15
+ import GroupFormWorkflowContext from "../context/GroupFormWorkflowContext";
16
+
17
+ const MemExtension = React.memo(ExtensionSlot);
18
+
19
+ const PatientRow = ({ patient, removePatient }) => {
20
+ const { t } = useTranslation();
21
+ return (
22
+ <li key={patient.uuid} className={styles.patientRow}>
23
+ <span className={styles.patientName}>{patient?.display}</span>
24
+ <span>
25
+ <Button
26
+ kind="tertiary"
27
+ size="sm"
28
+ onClick={() => removePatient(patient.uuid)}
29
+ renderIcon={Close}
30
+ tooltipPosition="right"
31
+ >
32
+ {t("remove", "Remove")}
33
+ </Button>
34
+ </span>
35
+ </li>
36
+ );
37
+ };
38
+
39
+ const NewGroupForm = (props) => {
40
+ const {
41
+ name,
42
+ setName,
43
+ patientList,
44
+ updatePatientList,
45
+ errors,
46
+ validate,
47
+ removePatient,
48
+ } = props;
49
+ const { t } = useTranslation();
50
+
51
+ return (
52
+ <div
53
+ style={{
54
+ display: "flex",
55
+ flexDirection: "column",
56
+ rowGap: "1rem",
57
+ }}
58
+ >
59
+ <TextInput
60
+ labelText={t("newGroupName", "New Group Name")}
61
+ value={name}
62
+ onChange={(e) => setName(e.target.value)}
63
+ onBlur={() => validate("name")}
64
+ />
65
+ {errors?.name && (
66
+ <p className={styles.formError}>
67
+ {t("groupNameError", "Please enter a group name.")}
68
+ </p>
69
+ )}
70
+ <FormLabel>Patients in group</FormLabel>
71
+ {errors?.patientList && (
72
+ <p className={styles.formError}>
73
+ {t("noPatientError", "Please enter at least one patient.")}
74
+ </p>
75
+ )}
76
+ {!errors?.patientList && (
77
+ <ul>
78
+ {patientList?.map((patient, index) => (
79
+ <PatientRow
80
+ patient={patient}
81
+ removePatient={removePatient}
82
+ key={index}
83
+ />
84
+ ))}
85
+ </ul>
86
+ )}
87
+
88
+ <FormLabel>Search for patients to add to group</FormLabel>
89
+ <div className={styles.searchBar}>
90
+ <MemExtension
91
+ extensionSlotName="patient-search-bar-slot"
92
+ state={{
93
+ selectPatientAction: updatePatientList,
94
+ buttonProps: {
95
+ kind: "primary",
96
+ },
97
+ }}
98
+ />
99
+ </div>
100
+ </div>
101
+ );
102
+ };
103
+
104
+ const AddGroupModal = () => {
105
+ const { setGroup } = useContext(GroupFormWorkflowContext);
106
+ const { t } = useTranslation();
107
+ const [open, setOpen] = useState(false);
108
+ const [errors, setErrors] = useState({});
109
+ const [name, setName] = useState("");
110
+ const [patientList, setPatientList] = useState([]);
111
+
112
+ const handleCancel = () => {
113
+ setOpen(false);
114
+ };
115
+
116
+ const removePatient = useCallback(
117
+ (patientUuid: string) =>
118
+ setPatientList((patientList) =>
119
+ patientList.filter((patient) => patient.uuid !== patientUuid)
120
+ ),
121
+ [setPatientList]
122
+ );
123
+
124
+ const validate = useCallback(
125
+ (field?: string | undefined) => {
126
+ let valid = true;
127
+ if (field) {
128
+ valid = field === "name" ? !!name : !!patientList.length;
129
+ setErrors((errors) => ({
130
+ ...errors,
131
+ [field]: valid ? null : "required",
132
+ }));
133
+ } else {
134
+ if (!name) {
135
+ setErrors((errors) => ({ ...errors, name: "required" }));
136
+ valid = false;
137
+ } else {
138
+ setErrors((errors) => ({ ...errors, name: null }));
139
+ }
140
+ if (!patientList.length) {
141
+ setErrors((errors) => ({ ...errors, patientList: "required" }));
142
+ valid = false;
143
+ } else {
144
+ setErrors((errors) => ({ ...errors, patientList: null }));
145
+ }
146
+ }
147
+ return valid;
148
+ },
149
+ [name, patientList.length]
150
+ );
151
+
152
+ const updatePatientList = useCallback(
153
+ (patient) => {
154
+ setPatientList((patientList) => {
155
+ if (!patientList.find((p) => p.uuid === patient.uuid)) {
156
+ return [...patientList, patient];
157
+ } else {
158
+ return patientList;
159
+ }
160
+ });
161
+ setErrors((errors) => ({ ...errors, patientList: null }));
162
+ },
163
+ [setPatientList]
164
+ );
165
+
166
+ const handleSubmit = () => {
167
+ if (validate()) {
168
+ setGroup({ id: "1234", name: name, members: patientList });
169
+ }
170
+ };
171
+
172
+ return (
173
+ <div className={styles.modal}>
174
+ <Button
175
+ onClick={() => setOpen(true)}
176
+ renderIcon={Add}
177
+ iconDescription="Add"
178
+ >
179
+ {t("createNewGroup", "Create New Group")}
180
+ </Button>
181
+ <ComposedModal open={open} onClose={() => setOpen(false)}>
182
+ <ModalHeader>{t("createNewGroup", "Create New Group")}</ModalHeader>
183
+ <ModalBody>
184
+ <NewGroupForm
185
+ {...{
186
+ name,
187
+ setName,
188
+ patientList,
189
+ updatePatientList,
190
+ errors,
191
+ validate,
192
+ removePatient,
193
+ }}
194
+ />
195
+ </ModalBody>
196
+ <ModalFooter>
197
+ <Button kind="secondary" onClick={handleCancel}>
198
+ {t("cancel", "Cancel")}
199
+ </Button>
200
+ <Button kind="primary" onClick={handleSubmit}>
201
+ {t("createGroup", "Create Group")}
202
+ </Button>
203
+ </ModalFooter>
204
+ </ComposedModal>
205
+ </div>
206
+ );
207
+ };
208
+
209
+ export default AddGroupModal;
@@ -0,0 +1,35 @@
1
+ @use '@carbon/styles/scss/spacing';
2
+ @use '@carbon/colors';
3
+
4
+ .modal {
5
+ :global(.cds--modal) {
6
+ z-index: 90;
7
+ }
8
+ :global(.cds--modal-container) {
9
+ height: 600px;
10
+ }
11
+ :global(.cds--modal-content) {
12
+ height: 100%;
13
+ }
14
+ }
15
+
16
+ .searchBar > div > div > div {
17
+ width: 100%
18
+ }
19
+
20
+ .formError {
21
+ color: red;
22
+ }
23
+
24
+ .patientRow {
25
+ display: flex;
26
+ width: "100%";
27
+ }
28
+
29
+ .patientName {
30
+ flex-grow: 1;
31
+ padding: spacing.$spacing-02;
32
+ &:hover {
33
+ background-color: colors.$gray-20;
34
+ }
35
+ }
@@ -2,7 +2,7 @@ import React, { useEffect, useMemo, useReducer } from "react";
2
2
  import reducer from "./FormWorkflowReducer";
3
3
  import { useParams, useLocation } from "react-router-dom";
4
4
  interface ParamTypes {
5
- formUuid: string;
5
+ formUuid?: string;
6
6
  }
7
7
 
8
8
  const initialActions = {
@@ -1,7 +1,7 @@
1
1
  import { navigate } from "@openmrs/esm-framework";
2
2
  import { initialWorkflowState } from "./FormWorkflowContext";
3
3
 
4
- export const fdeWorkflowStorageVersion = "1.0.12";
4
+ export const fdeWorkflowStorageVersion = "1.0.13";
5
5
  export const fdeWorkflowStorageName = "openmrs:fastDataEntryWorkflowState";
6
6
  const persistData = (data) => {
7
7
  localStorage.setItem(fdeWorkflowStorageName, JSON.stringify(data));