diff --git a/package-lock.json b/package-lock.json
index 8a91bf9..7c5f51b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -16,6 +16,7 @@
"@types/node": "^16.11.27",
"@types/react": "^18.0.6",
"@types/react-dom": "^18.0.2",
+ "@types/react-select": "^5.0.1",
"buffer": "^6.0.3",
"fhirclient": "^2.4.0",
"formik": "^2.2.9",
@@ -24,6 +25,7 @@
"react-dom": "^18.2.0",
"react-router-dom": "^6.3.0",
"react-scripts": "^5.0.1",
+ "react-select": "^5.6.0",
"typescript": "^4.6.3",
"web-vitals": "^2.1.4",
"yup": "^0.32.11"
@@ -351,9 +353,9 @@
}
},
"node_modules/@babel/helper-plugin-utils": {
- "version": "7.16.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz",
- "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==",
+ "version": "7.20.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz",
+ "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==",
"engines": {
"node": ">=6.9.0"
}
@@ -888,11 +890,11 @@
}
},
"node_modules/@babel/plugin-syntax-jsx": {
- "version": "7.16.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.7.tgz",
- "integrity": "sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q==",
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz",
+ "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.16.7"
+ "@babel/helper-plugin-utils": "^7.18.6"
},
"engines": {
"node": ">=6.9.0"
@@ -1746,11 +1748,11 @@
}
},
"node_modules/@babel/runtime": {
- "version": "7.17.9",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz",
- "integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==",
+ "version": "7.20.1",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.1.tgz",
+ "integrity": "sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==",
"dependencies": {
- "regenerator-runtime": "^0.13.4"
+ "regenerator-runtime": "^0.13.10"
},
"engines": {
"node": ">=6.9.0"
@@ -1950,6 +1952,128 @@
"postcss": "^8.3"
}
},
+ "node_modules/@emotion/babel-plugin": {
+ "version": "11.10.5",
+ "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz",
+ "integrity": "sha512-xE7/hyLHJac7D2Ve9dKroBBZqBT7WuPQmWcq7HSGb84sUuP4mlOWoB8dvVfD9yk5DHkU1m6RW7xSoDtnQHNQeA==",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.16.7",
+ "@babel/plugin-syntax-jsx": "^7.17.12",
+ "@babel/runtime": "^7.18.3",
+ "@emotion/hash": "^0.9.0",
+ "@emotion/memoize": "^0.8.0",
+ "@emotion/serialize": "^1.1.1",
+ "babel-plugin-macros": "^3.1.0",
+ "convert-source-map": "^1.5.0",
+ "escape-string-regexp": "^4.0.0",
+ "find-root": "^1.1.0",
+ "source-map": "^0.5.7",
+ "stylis": "4.1.3"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@emotion/cache": {
+ "version": "11.10.5",
+ "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.5.tgz",
+ "integrity": "sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==",
+ "dependencies": {
+ "@emotion/memoize": "^0.8.0",
+ "@emotion/sheet": "^1.2.1",
+ "@emotion/utils": "^1.2.0",
+ "@emotion/weak-memoize": "^0.3.0",
+ "stylis": "4.1.3"
+ }
+ },
+ "node_modules/@emotion/hash": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz",
+ "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ=="
+ },
+ "node_modules/@emotion/memoize": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz",
+ "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA=="
+ },
+ "node_modules/@emotion/react": {
+ "version": "11.10.5",
+ "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.5.tgz",
+ "integrity": "sha512-TZs6235tCJ/7iF6/rvTaOH4oxQg2gMAcdHemjwLKIjKz4rRuYe1HJ2TQJKnAcRAfOUDdU8XoDadCe1rl72iv8A==",
+ "dependencies": {
+ "@babel/runtime": "^7.18.3",
+ "@emotion/babel-plugin": "^11.10.5",
+ "@emotion/cache": "^11.10.5",
+ "@emotion/serialize": "^1.1.1",
+ "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0",
+ "@emotion/utils": "^1.2.0",
+ "@emotion/weak-memoize": "^0.3.0",
+ "hoist-non-react-statics": "^3.3.1"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0",
+ "react": ">=16.8.0"
+ },
+ "peerDependenciesMeta": {
+ "@babel/core": {
+ "optional": true
+ },
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@emotion/serialize": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.1.tgz",
+ "integrity": "sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA==",
+ "dependencies": {
+ "@emotion/hash": "^0.9.0",
+ "@emotion/memoize": "^0.8.0",
+ "@emotion/unitless": "^0.8.0",
+ "@emotion/utils": "^1.2.0",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@emotion/sheet": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.1.tgz",
+ "integrity": "sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA=="
+ },
+ "node_modules/@emotion/unitless": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz",
+ "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw=="
+ },
+ "node_modules/@emotion/use-insertion-effect-with-fallbacks": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz",
+ "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==",
+ "peerDependencies": {
+ "react": ">=16.8.0"
+ }
+ },
+ "node_modules/@emotion/utils": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz",
+ "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw=="
+ },
+ "node_modules/@emotion/weak-memoize": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz",
+ "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg=="
+ },
"node_modules/@eslint/eslintrc": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.3.tgz",
@@ -2010,6 +2134,19 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/@floating-ui/core": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.0.1.tgz",
+ "integrity": "sha512-bO37brCPfteXQfFY0DyNDGB3+IMe4j150KFQcgJ5aBP295p9nBGeHEs/p0czrRbtlHq4Px/yoPXO/+dOCcF4uA=="
+ },
+ "node_modules/@floating-ui/dom": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.0.4.tgz",
+ "integrity": "sha512-maYJRv+sAXTy4K9mzdv0JPyNW5YPVHrqtY90tEdI6XNpuLOP26Ci2pfwPsKBA/Wh4Z3FX5sUrtUFTdMYj9v+ug==",
+ "dependencies": {
+ "@floating-ui/core": "^1.0.1"
+ }
+ },
"node_modules/@hapi/hoek": {
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
@@ -3702,6 +3839,23 @@
"@types/react": "*"
}
},
+ "node_modules/@types/react-select": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@types/react-select/-/react-select-5.0.1.tgz",
+ "integrity": "sha512-h5Im0AP0dr4AVeHtrcvQrLV+gmPa7SA0AGdxl2jOhtwiE6KgXBFSogWw8az32/nusE6AQHlCOHQWjP1S/+oMWA==",
+ "deprecated": "This is a stub types definition. react-select provides its own type definitions, so you do not need this installed.",
+ "dependencies": {
+ "react-select": "*"
+ }
+ },
+ "node_modules/@types/react-transition-group": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz",
+ "integrity": "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==",
+ "dependencies": {
+ "@types/react": "*"
+ }
+ },
"node_modules/@types/resolve": {
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
@@ -6620,6 +6774,15 @@
"utila": "~0.4"
}
},
+ "node_modules/dom-helpers": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
+ "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
+ "dependencies": {
+ "@babel/runtime": "^7.8.7",
+ "csstype": "^3.0.2"
+ }
+ },
"node_modules/dom-serializer": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
@@ -7817,16 +7980,19 @@
},
"node_modules/fhir/node_modules/inherits": {
"version": "2.0.3",
+ "dev": true,
"inBundle": true,
"license": "ISC"
},
"node_modules/fhir/node_modules/lodash": {
"version": "4.17.21",
+ "dev": true,
"inBundle": true,
"license": "MIT"
},
"node_modules/fhir/node_modules/path": {
"version": "0.12.7",
+ "dev": true,
"inBundle": true,
"license": "MIT",
"dependencies": {
@@ -7836,6 +8002,7 @@
},
"node_modules/fhir/node_modules/process": {
"version": "0.11.10",
+ "dev": true,
"inBundle": true,
"license": "MIT",
"engines": {
@@ -7844,6 +8011,7 @@
},
"node_modules/fhir/node_modules/q": {
"version": "1.5.1",
+ "dev": true,
"inBundle": true,
"license": "MIT",
"engines": {
@@ -7853,11 +8021,13 @@
},
"node_modules/fhir/node_modules/sax": {
"version": "1.2.4",
+ "dev": true,
"inBundle": true,
"license": "ISC"
},
"node_modules/fhir/node_modules/util": {
"version": "0.10.4",
+ "dev": true,
"inBundle": true,
"license": "MIT",
"dependencies": {
@@ -7866,6 +8036,7 @@
},
"node_modules/fhir/node_modules/xml-js": {
"version": "1.6.8",
+ "dev": true,
"inBundle": true,
"license": "MIT",
"dependencies": {
@@ -8041,6 +8212,11 @@
"url": "https://github.com/avajs/find-cache-dir?sponsor=1"
}
},
+ "node_modules/find-root": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
+ "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng=="
+ },
"node_modules/find-up": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
@@ -20305,6 +20481,11 @@
"node": ">= 4.0.0"
}
},
+ "node_modules/memoize-one": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
+ "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
+ },
"node_modules/merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
@@ -22877,6 +23058,41 @@
"node": ">=10"
}
},
+ "node_modules/react-select": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.6.0.tgz",
+ "integrity": "sha512-uUvP/72rA8NGhOL16RVBaeC12Wa4NUE0iXIa6hz0YRno9ZgxTmpuMeKzjR7vHcwmigpVCoe0prP+3NVb6Obq8Q==",
+ "dependencies": {
+ "@babel/runtime": "^7.12.0",
+ "@emotion/cache": "^11.4.0",
+ "@emotion/react": "^11.8.1",
+ "@floating-ui/dom": "^1.0.1",
+ "@types/react-transition-group": "^4.4.0",
+ "memoize-one": "^6.0.0",
+ "prop-types": "^15.6.0",
+ "react-transition-group": "^4.3.0",
+ "use-isomorphic-layout-effect": "^1.1.2"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
+ "node_modules/react-transition-group": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
+ "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
+ "dependencies": {
+ "@babel/runtime": "^7.5.5",
+ "dom-helpers": "^5.0.1",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.6.2"
+ },
+ "peerDependencies": {
+ "react": ">=16.6.0",
+ "react-dom": ">=16.6.0"
+ }
+ },
"node_modules/readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
@@ -22952,9 +23168,9 @@
}
},
"node_modules/regenerator-runtime": {
- "version": "0.13.9",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
- "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
+ "version": "0.13.10",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz",
+ "integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw=="
},
"node_modules/regenerator-transform": {
"version": "0.15.0",
@@ -23960,6 +24176,11 @@
"postcss": "^8.2.15"
}
},
+ "node_modules/stylis": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz",
+ "integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA=="
+ },
"node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@@ -24610,6 +24831,19 @@
"punycode": "^2.1.0"
}
},
+ "node_modules/use-isomorphic-layout-effect": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz",
+ "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -25836,9 +26070,9 @@
}
},
"@babel/helper-plugin-utils": {
- "version": "7.16.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz",
- "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA=="
+ "version": "7.20.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz",
+ "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ=="
},
"@babel/helper-remap-async-to-generator": {
"version": "7.16.8",
@@ -26187,11 +26421,11 @@
}
},
"@babel/plugin-syntax-jsx": {
- "version": "7.16.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.7.tgz",
- "integrity": "sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q==",
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz",
+ "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==",
"requires": {
- "@babel/helper-plugin-utils": "^7.16.7"
+ "@babel/helper-plugin-utils": "^7.18.6"
}
},
"@babel/plugin-syntax-logical-assignment-operators": {
@@ -26742,11 +26976,11 @@
}
},
"@babel/runtime": {
- "version": "7.17.9",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz",
- "integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==",
+ "version": "7.20.1",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.1.tgz",
+ "integrity": "sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==",
"requires": {
- "regenerator-runtime": "^0.13.4"
+ "regenerator-runtime": "^0.13.10"
}
},
"@babel/runtime-corejs3": {
@@ -26871,6 +27105,107 @@
"postcss-value-parser": "^4.2.0"
}
},
+ "@emotion/babel-plugin": {
+ "version": "11.10.5",
+ "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz",
+ "integrity": "sha512-xE7/hyLHJac7D2Ve9dKroBBZqBT7WuPQmWcq7HSGb84sUuP4mlOWoB8dvVfD9yk5DHkU1m6RW7xSoDtnQHNQeA==",
+ "requires": {
+ "@babel/helper-module-imports": "^7.16.7",
+ "@babel/plugin-syntax-jsx": "^7.17.12",
+ "@babel/runtime": "^7.18.3",
+ "@emotion/hash": "^0.9.0",
+ "@emotion/memoize": "^0.8.0",
+ "@emotion/serialize": "^1.1.1",
+ "babel-plugin-macros": "^3.1.0",
+ "convert-source-map": "^1.5.0",
+ "escape-string-regexp": "^4.0.0",
+ "find-root": "^1.1.0",
+ "source-map": "^0.5.7",
+ "stylis": "4.1.3"
+ },
+ "dependencies": {
+ "escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
+ }
+ }
+ },
+ "@emotion/cache": {
+ "version": "11.10.5",
+ "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.5.tgz",
+ "integrity": "sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==",
+ "requires": {
+ "@emotion/memoize": "^0.8.0",
+ "@emotion/sheet": "^1.2.1",
+ "@emotion/utils": "^1.2.0",
+ "@emotion/weak-memoize": "^0.3.0",
+ "stylis": "4.1.3"
+ }
+ },
+ "@emotion/hash": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz",
+ "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ=="
+ },
+ "@emotion/memoize": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz",
+ "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA=="
+ },
+ "@emotion/react": {
+ "version": "11.10.5",
+ "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.5.tgz",
+ "integrity": "sha512-TZs6235tCJ/7iF6/rvTaOH4oxQg2gMAcdHemjwLKIjKz4rRuYe1HJ2TQJKnAcRAfOUDdU8XoDadCe1rl72iv8A==",
+ "requires": {
+ "@babel/runtime": "^7.18.3",
+ "@emotion/babel-plugin": "^11.10.5",
+ "@emotion/cache": "^11.10.5",
+ "@emotion/serialize": "^1.1.1",
+ "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0",
+ "@emotion/utils": "^1.2.0",
+ "@emotion/weak-memoize": "^0.3.0",
+ "hoist-non-react-statics": "^3.3.1"
+ }
+ },
+ "@emotion/serialize": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.1.tgz",
+ "integrity": "sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA==",
+ "requires": {
+ "@emotion/hash": "^0.9.0",
+ "@emotion/memoize": "^0.8.0",
+ "@emotion/unitless": "^0.8.0",
+ "@emotion/utils": "^1.2.0",
+ "csstype": "^3.0.2"
+ }
+ },
+ "@emotion/sheet": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.1.tgz",
+ "integrity": "sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA=="
+ },
+ "@emotion/unitless": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz",
+ "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw=="
+ },
+ "@emotion/use-insertion-effect-with-fallbacks": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz",
+ "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==",
+ "requires": {}
+ },
+ "@emotion/utils": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz",
+ "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw=="
+ },
+ "@emotion/weak-memoize": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz",
+ "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg=="
+ },
"@eslint/eslintrc": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.3.tgz",
@@ -26915,6 +27250,19 @@
}
}
},
+ "@floating-ui/core": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.0.1.tgz",
+ "integrity": "sha512-bO37brCPfteXQfFY0DyNDGB3+IMe4j150KFQcgJ5aBP295p9nBGeHEs/p0czrRbtlHq4Px/yoPXO/+dOCcF4uA=="
+ },
+ "@floating-ui/dom": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.0.4.tgz",
+ "integrity": "sha512-maYJRv+sAXTy4K9mzdv0JPyNW5YPVHrqtY90tEdI6XNpuLOP26Ci2pfwPsKBA/Wh4Z3FX5sUrtUFTdMYj9v+ug==",
+ "requires": {
+ "@floating-ui/core": "^1.0.1"
+ }
+ },
"@hapi/hoek": {
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
@@ -28192,6 +28540,22 @@
"@types/react": "*"
}
},
+ "@types/react-select": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@types/react-select/-/react-select-5.0.1.tgz",
+ "integrity": "sha512-h5Im0AP0dr4AVeHtrcvQrLV+gmPa7SA0AGdxl2jOhtwiE6KgXBFSogWw8az32/nusE6AQHlCOHQWjP1S/+oMWA==",
+ "requires": {
+ "react-select": "*"
+ }
+ },
+ "@types/react-transition-group": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz",
+ "integrity": "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==",
+ "requires": {
+ "@types/react": "*"
+ }
+ },
"@types/resolve": {
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
@@ -30275,6 +30639,15 @@
"utila": "~0.4"
}
},
+ "dom-helpers": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
+ "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
+ "requires": {
+ "@babel/runtime": "^7.8.7",
+ "csstype": "^3.0.2"
+ }
+ },
"dom-serializer": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
@@ -31161,15 +31534,18 @@
"dependencies": {
"inherits": {
"version": "2.0.3",
- "bundled": true
+ "bundled": true,
+ "dev": true
},
"lodash": {
"version": "4.17.21",
- "bundled": true
+ "bundled": true,
+ "dev": true
},
"path": {
"version": "0.12.7",
"bundled": true,
+ "dev": true,
"requires": {
"process": "^0.11.1",
"util": "^0.10.3"
@@ -31177,19 +31553,23 @@
},
"process": {
"version": "0.11.10",
- "bundled": true
+ "bundled": true,
+ "dev": true
},
"q": {
"version": "1.5.1",
- "bundled": true
+ "bundled": true,
+ "dev": true
},
"sax": {
"version": "1.2.4",
- "bundled": true
+ "bundled": true,
+ "dev": true
},
"util": {
"version": "0.10.4",
"bundled": true,
+ "dev": true,
"requires": {
"inherits": "2.0.3"
}
@@ -31197,6 +31577,7 @@
"xml-js": {
"version": "1.6.8",
"bundled": true,
+ "dev": true,
"requires": {
"sax": "^1.2.4"
}
@@ -31326,6 +31707,11 @@
"pkg-dir": "^4.1.0"
}
},
+ "find-root": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
+ "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng=="
+ },
"find-up": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
@@ -42693,6 +43079,11 @@
"fs-monkey": "1.0.3"
}
},
+ "memoize-one": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
+ "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
+ },
"merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
@@ -44413,6 +44804,33 @@
}
}
},
+ "react-select": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.6.0.tgz",
+ "integrity": "sha512-uUvP/72rA8NGhOL16RVBaeC12Wa4NUE0iXIa6hz0YRno9ZgxTmpuMeKzjR7vHcwmigpVCoe0prP+3NVb6Obq8Q==",
+ "requires": {
+ "@babel/runtime": "^7.12.0",
+ "@emotion/cache": "^11.4.0",
+ "@emotion/react": "^11.8.1",
+ "@floating-ui/dom": "^1.0.1",
+ "@types/react-transition-group": "^4.4.0",
+ "memoize-one": "^6.0.0",
+ "prop-types": "^15.6.0",
+ "react-transition-group": "^4.3.0",
+ "use-isomorphic-layout-effect": "^1.1.2"
+ }
+ },
+ "react-transition-group": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
+ "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
+ "requires": {
+ "@babel/runtime": "^7.5.5",
+ "dom-helpers": "^5.0.1",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.6.2"
+ }
+ },
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
@@ -44472,9 +44890,9 @@
}
},
"regenerator-runtime": {
- "version": "0.13.9",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
- "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
+ "version": "0.13.10",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz",
+ "integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw=="
},
"regenerator-transform": {
"version": "0.15.0",
@@ -45214,6 +45632,11 @@
"postcss-selector-parser": "^6.0.4"
}
},
+ "stylis": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz",
+ "integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA=="
+ },
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@@ -45700,6 +46123,12 @@
"punycode": "^2.1.0"
}
},
+ "use-isomorphic-layout-effect": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz",
+ "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==",
+ "requires": {}
+ },
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
diff --git a/package.json b/package.json
index 2b7c53c..7c42ed4 100644
--- a/package.json
+++ b/package.json
@@ -11,6 +11,7 @@
"@types/node": "^16.11.27",
"@types/react": "^18.0.6",
"@types/react-dom": "^18.0.2",
+ "@types/react-select": "^5.0.1",
"buffer": "^6.0.3",
"fhirclient": "^2.4.0",
"formik": "^2.2.9",
@@ -19,6 +20,7 @@
"react-dom": "^18.2.0",
"react-router-dom": "^6.3.0",
"react-scripts": "^5.0.1",
+ "react-select": "^5.6.0",
"typescript": "^4.6.3",
"web-vitals": "^2.1.4",
"yup": "^0.32.11"
diff --git a/src/components/reports/CustomSelectField.tsx b/src/components/reports/CustomSelectField.tsx
new file mode 100644
index 0000000..6e4b04a
--- /dev/null
+++ b/src/components/reports/CustomSelectField.tsx
@@ -0,0 +1,48 @@
+import { FieldProps } from "formik";
+import Select from "react-select";
+
+interface Option {
+ label: string;
+ value: string;
+}
+
+interface Props extends FieldProps {
+ options: Option[];
+ isMulti: boolean;
+ className?: string;
+ placeholder?: string;
+}
+
+const CustomSelectField = ({ className, placeholder, field, form, options, isMulti = false }: Props) => {
+ const onChange = (option: Option | Option[]) => {
+ form.setFieldValue(
+ field.name,
+ isMulti ? (option as Option[]).map((item: Option) => item.value) : (option as Option).value,
+ );
+ };
+
+ const getValue = () => {
+ if (options) {
+ return isMulti
+ ? options.filter((option: any) => field?.value?.indexOf(option.value) >= 0)
+ : options.find((option: any) => option.value === field.value);
+ } else {
+ return isMulti ? [] : ("" as any);
+ }
+ };
+
+ return (
+
+ );
+};
+
+export default CustomSelectField;
diff --git a/src/components/reports/FieldSet.tsx b/src/components/reports/FieldSet.tsx
index 8e135dc..971c2cd 100644
--- a/src/components/reports/FieldSet.tsx
+++ b/src/components/reports/FieldSet.tsx
@@ -1,6 +1,7 @@
import { ErrorMessage, Field } from "formik";
import { ChangeEventHandler, FC } from "react";
import { RequiredCoding } from "../../code_systems/types";
+import CustomSelectField from "./CustomSelectField";
type Props = {
name: string;
@@ -10,6 +11,7 @@ type Props = {
selectOptions?: RequiredCoding[];
disabled?: boolean;
onChange?: ChangeEventHandler;
+ isMulti?: boolean;
};
/**
@@ -17,10 +19,11 @@ type Props = {
* @param name html id and name of the field
* @param label label to display to the user
* @param selectOptions if present, will display as a select drop-down with these options
+ * @param isMulti if true, then multiple-selection from a drop-down
* @param rest any other props to pass though to Formik
* @constructor
*/
-const FieldSet: FC = ({ name, label, selectOptions, ...rest }) => {
+const FieldSet: FC = ({ name, label, selectOptions, isMulti, ...rest }) => {
let field: JSX.Element = ;
if (selectOptions !== undefined) {
@@ -37,6 +40,20 @@ const FieldSet: FC = ({ name, label, selectOptions, ...rest }) => {
);
}
+ if (isMulti && selectOptions) {
+ field = (
+ ({ label: `${opt.display} (${opt.code})`, value: opt.code }))}
+ component={CustomSelectField}
+ placeholder="Select multi options..."
+ isMulti={true}
+ />
+ );
+ }
+
return (
<>
diff --git a/src/components/reports/FormDefaults.ts b/src/components/reports/FormDefaults.ts
index d85a976..2f22f80 100644
--- a/src/components/reports/FormDefaults.ts
+++ b/src/components/reports/FormDefaults.ts
@@ -25,7 +25,7 @@ export const initialValues: FormValues = {
collectionDateTime: "04/06/2019 12:00",
receivedDateTime: "04/06/2019 15:00",
authorisedDateTime: "04/06/2019 15:30",
- reasonForTest: "R59", // epilepsy
+ reasonForTest: ["R59"], // epilepsy
reasonForTestText:
"Sequence variant screening in Donald Duck because of epilepsy and atypical absences. " +
"An SLC2A1 variant is suspected.",
@@ -107,7 +107,7 @@ export const noValues: FormValues = {
collectionDateTime: "",
receivedDateTime: "",
authorisedDateTime: "",
- reasonForTest: "",
+ reasonForTest: [""],
reasonForTestText: "",
},
variant: [],
diff --git a/src/components/reports/ReportForm.test.tsx b/src/components/reports/ReportForm.test.tsx
index 0b005b4..984e9b0 100644
--- a/src/components/reports/ReportForm.test.tsx
+++ b/src/components/reports/ReportForm.test.tsx
@@ -17,7 +17,7 @@ type DropDown = {
value: string;
};
-const setDummyValues = (withDates: boolean, dropDowns?: DropDown[]) => {
+const setDummyValues = (withDates: boolean, dropDowns?: DropDown[], multiSelect?: DropDown[]) => {
const dummyValue = "Always_the_same";
const form = screen.getByRole("form");
@@ -53,6 +53,14 @@ const setDummyValues = (withDates: boolean, dropDowns?: DropDown[]) => {
});
}
+ if (multiSelect) {
+ multiSelect.map((singleSelect) => {
+ const field = within(form).getByLabelText(singleSelect.field);
+ clearAndType(field, singleSelect.value);
+ userEvent.tab();
+ });
+ }
+
if (withDates) {
within(form)
.queryAllByLabelText(/date/i)
@@ -85,9 +93,9 @@ async function setLabAndPatient() {
});
}
-async function setDummyAndNext(withDates: boolean, dropDowns?: DropDown[]) {
+async function setDummyAndNext(withDates: boolean, dropDowns?: DropDown[], multiSelect?: DropDown[]) {
await act(async () => {
- setDummyValues(withDates, dropDowns);
+ setDummyValues(withDates, dropDowns, multiSelect);
});
await act(async () => {
@@ -96,10 +104,11 @@ async function setDummyAndNext(withDates: boolean, dropDowns?: DropDown[]) {
}
const setSample = () => {
- return setDummyAndNext(true, [
- { field: /specimen type/i, value: "122555007" },
- { field: /test reason/i, value: "R59" },
- ]);
+ return setDummyAndNext(
+ true,
+ [{ field: /specimen type/i, value: "122555007" }],
+ [{ field: /test reason/i, value: "R59" }],
+ );
};
async function setVariantFields() {
diff --git a/src/components/reports/formDataValidation.test.tsx b/src/components/reports/formDataValidation.test.tsx
index 796603f..732f010 100644
--- a/src/components/reports/formDataValidation.test.tsx
+++ b/src/components/reports/formDataValidation.test.tsx
@@ -1,4 +1,10 @@
-import { optionalDateTime, patientSchema, requiredDate, requiredDateTime } from "./formDataValidation";
+import {
+ optionalDateTime,
+ patientSchema,
+ requiredDate,
+ requiredDateTime,
+ requiredStringArray,
+} from "./formDataValidation";
import * as Yup from "yup";
import { ValidationError } from "yup";
import { Patient } from "@smile-cdr/fhirts/dist/FHIR-R4/interfaces/IPatient";
@@ -67,6 +73,31 @@ describe("Custom form validation", () => {
};
await patientSchema.validate(model);
}
+
await expect(validateModel).rejects.toThrow(ValidationError);
});
+
+ test.each([
+ ["undefined", undefined, false],
+ ["undefined value in array", [undefined], false],
+ ["empty value in array", [""], false],
+ ["single value", ["one"], true],
+ ["multiple values", ["one", "two", "three"], true],
+ ])(
+ "String array with '%s' pass validation",
+ async (description: string, value: string[] | undefined | undefined[], validates: boolean) => {
+ const schema = Yup.object({
+ requiredStringArray: requiredStringArray,
+ }).required();
+
+ const model = { requiredStringArray: value };
+ const validateModel = async () => await schema.validate(model);
+
+ if (validates) {
+ await expect(validateModel).resolves;
+ } else {
+ await expect(validateModel).rejects.toThrow(ValidationError);
+ }
+ },
+ );
});
diff --git a/src/components/reports/formDataValidation.ts b/src/components/reports/formDataValidation.ts
index 75b53f1..16a8d78 100644
--- a/src/components/reports/formDataValidation.ts
+++ b/src/components/reports/formDataValidation.ts
@@ -24,6 +24,10 @@ export const dateTime = Yup.string()
});
export const requiredDateTime = dateTime.required();
export const optionalDateTime = dateTime.optional();
+export const requiredStringArray = Yup.array()
+ .of(Yup.string().required())
+ .required()
+ .test("required", "Select at least one value", (value) => value !== undefined && value.length !== 0);
const boolField = Yup.boolean().default(false).nullable(false);
@@ -68,7 +72,7 @@ export const sampleSchema = Yup.object({
receivedDateTime: requiredDateTime,
authorisedDateTime: optionalDateTime,
specimenType: requiredString,
- reasonForTest: requiredString,
+ reasonForTest: requiredStringArray,
reasonForTestText: optionalString,
});
diff --git a/src/components/reports/formSteps/Sample.tsx b/src/components/reports/formSteps/Sample.tsx
index 6adb184..127e855 100644
--- a/src/components/reports/formSteps/Sample.tsx
+++ b/src/components/reports/formSteps/Sample.tsx
@@ -14,7 +14,7 @@ const Sample: FC = () => {
-
+
>
);
};
diff --git a/src/fhir/api.ts b/src/fhir/api.ts
index 93cea3a..4e885b8 100644
--- a/src/fhir/api.ts
+++ b/src/fhir/api.ts
@@ -34,10 +34,10 @@ export const bundleRequest = (form: FormValues, reportedGenes: RequiredCoding[])
};
/**
- * Generates a unique report identifier that is unique for a sample and a reason for testing.
+ * Generates a unique report identifier that is unique for a sample and reasons for testing.
* @param sample data from the sample form
*/
-const getUniqueReportIdentifier = (sample: SampleSchema) => `${sample.specimenCode}_${sample.reasonForTest}`;
+const getUniqueReportIdentifier = (sample: SampleSchema) => `${sample.specimenCode}_${sample.reasonForTest.join("-")}`;
export const createBundle = (form: FormValues, reportedGenes: RequiredCoding[]): Bundle => {
const reportIdentifier = getUniqueReportIdentifier(form.sample);
diff --git a/src/fhir/resources.ts b/src/fhir/resources.ts
index a7bf905..dbbe19f 100644
--- a/src/fhir/resources.ts
+++ b/src/fhir/resources.ts
@@ -521,12 +521,10 @@ export const serviceRequestAndId = (
},
],
};
- request.reasonCode = [
- {
- coding: [codedValue(diseases, sample.reasonForTest)],
- text: sample.reasonForTestText,
- },
- ];
+ request.reasonCode = sample.reasonForTest.map((reason) => ({
+ coding: [codedValue(diseases, reason)],
+ text: sample.reasonForTestText,
+ }));
const identifier = createIdentifier(reportIdentifier);
request.identifier = [identifier];
@@ -559,7 +557,7 @@ export const reportAndId = (
reference("Practitioner", authoriserIdentifier),
];
report.code = {
- coding: [codedValue(diseases, sample.reasonForTest)],
+ coding: sample.reasonForTest.map((reason) => codedValue(diseases, reason)),
};
report.conclusion = result.clinicalConclusion;
const identifier = createIdentifier(reportIdentifier);