diff --git a/ui/package-lock.json b/ui/package-lock.json index c6beabb9c..0bdc71247 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -1152,6 +1152,22 @@ "regenerator-runtime": "^0.13.4" } }, + "@babel/runtime-corejs2": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.14.0.tgz", + "integrity": "sha512-btR4E8JiGlmmDI5YgirlG9z3T91rBdxnVh2YuEStrHDcekffaaIeK+CE0S4IaYUyYhMa7rFDfF2GEO79XNbLEA==", + "requires": { + "core-js": "^2.6.5", + "regenerator-runtime": "^0.13.4" + }, + "dependencies": { + "core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==" + } + } + }, "@babel/runtime-corejs3": { "version": "7.13.17", "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.13.17.tgz", @@ -1250,6 +1266,43 @@ } } }, + "@fortawesome/fontawesome-common-types": { + "version": "0.2.35", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.35.tgz", + "integrity": "sha512-IHUfxSEDS9dDGqYwIW7wTN6tn/O8E0n5PcAHz9cAaBoZw6UpG20IG/YM3NNLaGPwPqgjBAFjIURzqoQs3rrtuw==" + }, + "@fortawesome/fontawesome-svg-core": { + "version": "1.2.35", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.35.tgz", + "integrity": "sha512-uLEXifXIL7hnh2sNZQrIJWNol7cTVIzwI+4qcBIq9QWaZqUblm0IDrtSqbNg+3SQf8SMGHkiSigD++rHmCHjBg==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.35" + } + }, + "@fortawesome/free-regular-svg-icons": { + "version": "5.15.3", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-5.15.3.tgz", + "integrity": "sha512-q4/p8Xehy9qiVTdDWHL4Z+o5PCLRChePGZRTXkl+/Z7erDVL8VcZUuqzJjs6gUz6czss4VIPBRdCz6wP37/zMQ==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.35" + } + }, + "@fortawesome/free-solid-svg-icons": { + "version": "5.15.3", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.3.tgz", + "integrity": "sha512-XPeeu1IlGYqz4VWGRAT5ukNMd4VHUEEJ7ysZ7pSSgaEtNvSo+FLurybGJVmiqkQdK50OkSja2bfZXOeyMGRD8Q==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.35" + } + }, + "@fortawesome/react-fontawesome": { + "version": "0.1.14", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.14.tgz", + "integrity": "sha512-4wqNb0gRLVaBm/h+lGe8UfPPivcbuJ6ecI4hIgW0LjI7kzpYB9FkN0L9apbVzg+lsBdcTf0AlBtODjcSX5mmKA==", + "requires": { + "prop-types": "^15.7.2" + } + }, "@hapi/address": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", @@ -1284,6 +1337,15 @@ "@hapi/hoek": "^8.3.0" } }, + "@hypnosphi/create-react-context": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@hypnosphi/create-react-context/-/create-react-context-0.3.1.tgz", + "integrity": "sha512-V1klUed202XahrWJLLOT3EXNeCpFHCcJntdFGI15ntCwau+jfT386w7OFTMaCqOgXUH1fa0w/I1oZs+i/Rfr0A==", + "requires": { + "gud": "^1.0.0", + "warning": "^4.0.3" + } + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1694,6 +1756,83 @@ } } }, + "@popperjs/core": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.9.2.tgz", + "integrity": "sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q==" + }, + "@restart/context": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@restart/context/-/context-2.1.4.tgz", + "integrity": "sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q==" + }, + "@restart/hooks": { + "version": "0.3.26", + "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.3.26.tgz", + "integrity": "sha512-7Hwk2ZMYm+JLWcb7R9qIXk1OoUg1Z+saKWqZXlrvFwT3w6UArVNWgxYOzf+PJoK9zZejp8okPAKTctthhXLt5g==", + "requires": { + "lodash": "^4.17.20", + "lodash-es": "^4.17.20" + } + }, + "@rjsf/bootstrap-4": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@rjsf/bootstrap-4/-/bootstrap-4-2.5.1.tgz", + "integrity": "sha512-USijizR4MkYtMOdbZWt3HDDc9vWmMvmiskqXwV2jEUBMPSu1UG0bZS2HKzqfnMJcJRT1P7Tj4O3sGwgE+7FCpw==", + "requires": { + "react-icons": "^3.10.0" + } + }, + "@rjsf/core": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@rjsf/core/-/core-2.5.1.tgz", + "integrity": "sha512-km8NYScXNONaL5BiSLS6wyDj49pOLZtn0iXg7Zxlm921uuf3o2AAX5SuZS5kB4Zj2zlrVMrXESexfX6bxdDYHw==", + "requires": { + "@babel/runtime-corejs2": "^7.8.7", + "@types/json-schema": "^7.0.4", + "ajv": "^6.7.0", + "core-js": "^2.5.7", + "json-schema-merge-allof": "^0.6.0", + "jsonpointer": "^4.0.1", + "lodash": "^4.17.15", + "prop-types": "^15.7.2", + "react-app-polyfill": "^1.0.4", + "react-is": "^16.9.0", + "shortid": "^2.2.14" + }, + "dependencies": { + "core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==" + }, + "react-app-polyfill": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-1.0.6.tgz", + "integrity": "sha512-OfBnObtnGgLGfweORmdZbyEz+3dgVePQBb3zipiaDsMHV1NpWm0rDFYIVXFV/AK+x4VIIfWHhrdMIeoTLyRr2g==", + "requires": { + "core-js": "^3.5.0", + "object-assign": "^4.1.1", + "promise": "^8.0.3", + "raf": "^3.4.1", + "regenerator-runtime": "^0.13.3", + "whatwg-fetch": "^3.0.0" + }, + "dependencies": { + "core-js": { + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.12.1.tgz", + "integrity": "sha512-Ne9DKPHTObRuB09Dru5AjwKjY4cJHVGu+y5f7coGn1E9Grkc3p2iBwE9AI/nJzsE29mQF7oq+mhYYRqOMFN1Bw==" + } + } + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } + } + }, "@rollup/plugin-node-resolve": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz", @@ -1971,6 +2110,14 @@ "@babel/types": "^7.3.0" } }, + "@types/classnames": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@types/classnames/-/classnames-2.3.1.tgz", + "integrity": "sha512-zeOWb0JGBoVmlQoznvqXbE0tEC/HONsnoUNH19Hc96NFsTAwTXbTqb8FMYkru1F/iqp7a18Ws3nWJvtA1sHD1A==", + "requires": { + "classnames": "*" + } + }, "@types/eslint": { "version": "7.2.10", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.10.tgz", @@ -2007,6 +2154,19 @@ "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", "integrity": "sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA==" }, + "@types/http-proxy": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.6.tgz", + "integrity": "sha512-+qsjqR75S/ib0ig0R9WN+CDoZeOBU6F2XLewgC4KVgdXiNHiKKHFEMRHOrs5PbYE97D5vataw5wPj4KLYfUkuQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/invariant": { + "version": "2.2.34", + "resolved": "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.34.tgz", + "integrity": "sha512-lYUtmJ9BqUN688fGY1U1HZoWT1/Jrmgigx2loq4ZcJpICECm/Om3V314BxdzypO0u5PORKGMM6x0OXaljV1YFg==" + }, "@types/istanbul-lib-coverage": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", @@ -2072,11 +2232,34 @@ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==" }, + "@types/prop-types": { + "version": "15.7.3", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", + "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" + }, "@types/q": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" }, + "@types/react": { + "version": "17.0.6", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.6.tgz", + "integrity": "sha512-u/TtPoF/hrvb63LdukET6ncaplYsvCvmkceasx8oG84/ZCsoLxz9Z/raPBP4lTAiWW1Jb889Y9svHmv8R26dWw==", + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "@types/react-transition-group": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.1.tgz", + "integrity": "sha512-vIo69qKKcYoJ8wKCJjwSgCTM+z3chw3g18dkrDfVX665tMH7tmbDxEAnPdey4gTlwZz5QuHGzd+hul0OVZDqqQ==", + "requires": { + "@types/react": "*" + } + }, "@types/resolve": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", @@ -2085,6 +2268,11 @@ "@types/node": "*" } }, + "@types/scheduler": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz", + "integrity": "sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA==" + }, "@types/source-list-map": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", @@ -2116,6 +2304,11 @@ "source-map": "^0.6.1" } }, + "@types/warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-DSUBJorY+ZYrdA04fEZU9fjiPlI=" + }, "@types/webpack": { "version": "4.41.27", "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.27.tgz", @@ -3292,8 +3485,7 @@ "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "optional": true + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" }, "bindings": { "version": "1.5.0", @@ -3374,6 +3566,11 @@ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" }, + "bootstrap": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.0.tgz", + "integrity": "sha512-Io55IuQY3kydzHtbGvQya3H+KorS/M9rSNyfCGCg9WZ4pyT/lCxIlpJgG1GXW/PswzC84Tr2fBYi+7+jFVQQBw==" + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3704,7 +3901,6 @@ "version": "3.5.1", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", - "optional": true, "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", @@ -3766,6 +3962,11 @@ } } }, + "classnames": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", + "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" + }, "clean-css": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", @@ -3988,6 +4189,32 @@ } } }, + "compute-gcd": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/compute-gcd/-/compute-gcd-1.2.1.tgz", + "integrity": "sha512-TwMbxBNz0l71+8Sc4czv13h4kEqnchV9igQZBi6QUaz09dnz13juGnnaWWJTRsP3brxOoxeB4SA2WELLw1hCtg==", + "requires": { + "validate.io-array": "^1.0.3", + "validate.io-function": "^1.0.2", + "validate.io-integer-array": "^1.0.0" + } + }, + "compute-lcm": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/compute-lcm/-/compute-lcm-1.1.2.tgz", + "integrity": "sha512-OFNPdQAXnQhDSKioX8/XYT6sdUlXwpeMjfd6ApxMJfyZ4GxmLR1xvMERctlYhlHwIiz6CSpBc2+qYKjHGZw4TQ==", + "requires": { + "compute-gcd": "^1.2.1", + "validate.io-array": "^1.0.3", + "validate.io-function": "^1.0.2", + "validate.io-integer-array": "^1.0.0" + } + }, + "compute-scroll-into-view": { + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.17.tgz", + "integrity": "sha512-j4dx+Fb0URmzbwwMUrhqWM2BEWHdFGx+qZ9qqASHRPqvTYdqvWnHg0H1hIbcyLnvgnoNAVMlwkepyqM3DaIFUg==" + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -4524,6 +4751,11 @@ } } }, + "csstype": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", + "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==" + }, "cyclist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", @@ -4561,6 +4793,11 @@ "whatwg-url": "^8.0.0" } }, + "date-fns": { + "version": "2.21.3", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.21.3.tgz", + "integrity": "sha512-HeYdzCaFflc1i4tGbj7JKMjM4cKGYoyxwcIIkHzNgCkX8xXDNJDZXgDDVchIWpN4eQc3lH37WarduXFZJOtxfw==" + }, "debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", @@ -4607,6 +4844,11 @@ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, + "deep-object-diff": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/deep-object-diff/-/deep-object-diff-1.1.0.tgz", + "integrity": "sha512-b+QLs5vHgS+IoSNcUE4n9HP2NwcHj7aqnJWsjPtuG75Rh5TOaGt0OjAYInh77d5T16V5cRDC+Pw/6ZZZiETBGw==" + }, "deepmerge": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", @@ -4853,6 +5095,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": "0.2.2", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", @@ -6183,6 +6434,11 @@ } } }, + "file-saver": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", + "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==" + }, "file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", @@ -6202,6 +6458,11 @@ "to-regex-range": "^5.0.1" } }, + "filter-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", + "integrity": "sha1-mzERErxsYSehbgFsbF1/GeCAXFs=" + }, "finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", @@ -6308,9 +6569,9 @@ } }, "follow-redirects": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.3.tgz", - "integrity": "sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==" + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", + "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==" }, "for-in": { "version": "1.0.2", @@ -6747,6 +7008,11 @@ "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", "optional": true }, + "gud": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz", + "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==" + }, "gzip-size": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", @@ -7121,110 +7387,21 @@ } }, "http-proxy-middleware": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", - "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-1.3.1.tgz", + "integrity": "sha512-13eVVDYS4z79w7f1+NPllJtOQFx/FdUW4btIvVRMaRlUY9VGstAbo5MOhLEuUgZFRHn3x50ufn25zkj/boZnEg==", "requires": { - "http-proxy": "^1.17.0", - "is-glob": "^4.0.0", - "lodash": "^4.17.11", - "micromatch": "^3.1.10" + "@types/http-proxy": "^1.17.5", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" }, "dependencies": { - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-number": { + "is-plain-obj": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==" } } }, @@ -7401,6 +7578,14 @@ "side-channel": "^1.0.4" } }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "requires": { + "loose-envify": "^1.0.0" + } + }, "ip": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", @@ -7461,7 +7646,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "optional": true, "requires": { "binary-extensions": "^2.0.0" } @@ -8776,6 +8960,24 @@ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" }, + "json-schema-compare": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/json-schema-compare/-/json-schema-compare-0.2.2.tgz", + "integrity": "sha512-c4WYmDKyJXhs7WWvAWm3uIYnfyWFoIp+JEoX34rctVvEkMYCPGhXtvmFFXiffBbxfZsvQ0RNnV5H7GvDF5HCqQ==", + "requires": { + "lodash": "^4.17.4" + } + }, + "json-schema-merge-allof": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/json-schema-merge-allof/-/json-schema-merge-allof-0.6.0.tgz", + "integrity": "sha512-LEw4VMQVRceOPLuGRWcxW5orTTiR9ZAtqTAe4rQUjNADTeR81bezBVFa0MqIwp0YmHIM1KkhSjZM7o+IQhaPbQ==", + "requires": { + "compute-lcm": "^1.1.0", + "json-schema-compare": "^0.2.2", + "lodash": "^4.17.4" + } + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -8813,6 +9015,11 @@ "universalify": "^2.0.0" } }, + "jsonpointer": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.1.0.tgz", + "integrity": "sha512-CXcRvMyTlnR53xMcKnuMzfCA5i/nfblTnnr74CZb6C4vG39eu6w51t7nKmU5MfLfbTgGItliNyjO/ciNPDqClg==" + }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", @@ -8948,6 +9155,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, "lodash._reinterpolate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", @@ -8990,6 +9202,11 @@ "lodash._reinterpolate": "^3.0.0" } }, + "lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=" + }, "lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", @@ -9648,6 +9865,22 @@ "prepend-http": "^1.0.0", "query-string": "^4.1.0", "sort-keys": "^1.0.0" + }, + "dependencies": { + "query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "requires": { + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" + } } }, "npm-run-path": { @@ -10249,6 +10482,11 @@ "ts-pnp": "^1.1.6" } }, + "popper.js": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", + "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==" + }, "portfinder": { "version": "1.0.28", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", @@ -11392,6 +11630,22 @@ } } }, + "prop-types-extra": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", + "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", + "requires": { + "react-is": "^16.3.2", + "warning": "^4.0.0" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } + } + }, "proxy-addr": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", @@ -11477,12 +11731,14 @@ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, "query-string": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", - "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.0.0.tgz", + "integrity": "sha512-Iy7moLybliR5ZgrK/1R3vjrXq03S13Vz4Rbm5Jg3EFq1LUmQppto0qtXz4vqZ386MSRjZgnTSZ9QC+NZOSd/XA==", "requires": { - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" + "decode-uri-component": "^0.2.0", + "filter-obj": "^1.1.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" } }, "querystring": { @@ -11575,6 +11831,82 @@ "whatwg-fetch": "^3.4.1" } }, + "react-bootstrap": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.6.0.tgz", + "integrity": "sha512-PaeOGeRC2+JH9Uf1PukJgXcIpfGlrKKHEBZIArymjenYzSJ/RhO2UdNX+e7nalsCFFZLRRgQ0/FKkscW2LmmRg==", + "requires": { + "@babel/runtime": "^7.13.8", + "@restart/context": "^2.1.4", + "@restart/hooks": "^0.3.26", + "@types/classnames": "^2.2.10", + "@types/invariant": "^2.2.33", + "@types/prop-types": "^15.7.3", + "@types/react": ">=16.9.35", + "@types/react-transition-group": "^4.4.1", + "@types/warning": "^3.0.0", + "classnames": "^2.2.6", + "dom-helpers": "^5.1.2", + "invariant": "^2.2.4", + "prop-types": "^15.7.2", + "prop-types-extra": "^1.1.0", + "react-overlays": "^5.0.0", + "react-transition-group": "^4.4.1", + "uncontrollable": "^7.2.1", + "warning": "^4.0.3" + } + }, + "react-bootstrap-typeahead": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/react-bootstrap-typeahead/-/react-bootstrap-typeahead-5.1.4.tgz", + "integrity": "sha512-CfoaSjGV3MZS9yrkLfYkvimzRYru1Ko7qKKzacbsBeZ/sHCxFvUhxnCXmTy/K2vZCkOmAQpU/sbgQVOkMRNlSQ==", + "requires": { + "@babel/runtime": "^7.3.4", + "@restart/hooks": "^0.3.22", + "classnames": "^2.2.0", + "fast-deep-equal": "^3.1.1", + "invariant": "^2.2.1", + "lodash.debounce": "^4.0.8", + "prop-types": "^15.5.8", + "react-overlays": "^4.1.1", + "react-popper": "^1.0.0", + "scroll-into-view-if-needed": "^2.2.20", + "warning": "^4.0.1" + }, + "dependencies": { + "react-overlays": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-4.1.1.tgz", + "integrity": "sha512-WtJifh081e6M24KnvTQoNjQEpz7HoLxqt8TwZM7LOYIkYJ8i/Ly1Xi7RVte87ZVnmqQ4PFaFiNHZhSINPSpdBQ==", + "requires": { + "@babel/runtime": "^7.12.1", + "@popperjs/core": "^2.5.3", + "@restart/hooks": "^0.3.25", + "@types/warning": "^3.0.0", + "dom-helpers": "^5.2.0", + "prop-types": "^15.7.2", + "uncontrollable": "^7.0.0", + "warning": "^4.0.3" + } + } + } + }, + "react-contenteditable": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/react-contenteditable/-/react-contenteditable-3.3.5.tgz", + "integrity": "sha512-38A7hlRQfb2KQAQT0kIJC2YlQUU7jcyYM4eh1fj6kAYb3Hmk6hHlr0snelyxVSpPXjPdFllrnSsPkzUS5AtrEA==", + "requires": { + "fast-deep-equal": "^2.0.1", + "prop-types": "^15.7.1" + }, + "dependencies": { + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + } + } + }, "react-dev-utils": { "version": "11.0.4", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.4.tgz", @@ -11747,11 +12079,73 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz", "integrity": "sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew==" }, + "react-hook-form": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.6.4.tgz", + "integrity": "sha512-eKLRWkZcUKGYKMnKvN/VwPVc8t3pjfs69UEp/DJNS2ccGk18UKFq/XE049W+ye144aUj+1++NgUjs2/yMNuBWw==" + }, + "react-icons": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-3.11.0.tgz", + "integrity": "sha512-JRgiI/vdF6uyBgyZhVyYJUZAop95Sy4XDe/jmT3R/bKliFWpO/uZBwvSjWEdxwzec7SYbEPNPck0Kff2tUGM2Q==", + "requires": { + "camelcase": "^5.0.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + } + } + }, + "react-infinite-scroll-component": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/react-infinite-scroll-component/-/react-infinite-scroll-component-6.1.0.tgz", + "integrity": "sha512-SQu5nCqy8DxQWpnUVLx7V7b7LcA37aM7tvoWjTLZp1dk6EJibM5/4EJKzOnl07/BsM1Y40sKLuqjCwwH/xV0TQ==", + "requires": { + "throttle-debounce": "^2.1.0" + } + }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, + "react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, + "react-overlays": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-5.0.1.tgz", + "integrity": "sha512-plwUJieTBbLSrgvQ4OkkbTD/deXgxiJdNuKzo6n1RWE3OVnQIU5hffCGS/nvIuu6LpXFs2majbzaXY8rcUVdWA==", + "requires": { + "@babel/runtime": "^7.13.8", + "@popperjs/core": "^2.8.6", + "@restart/hooks": "^0.3.26", + "@types/warning": "^3.0.0", + "dom-helpers": "^5.2.0", + "prop-types": "^15.7.2", + "uncontrollable": "^7.2.1", + "warning": "^4.0.3" + } + }, + "react-popper": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.11.tgz", + "integrity": "sha512-VSA/bS+pSndSF2fiasHK/PTEEAyOpX60+H5EPAjoArr8JGm+oihu4UbrqcEBpQibJxBVCpYyjAX7abJ+7DoYVg==", + "requires": { + "@babel/runtime": "^7.1.2", + "@hypnosphi/create-react-context": "^0.3.1", + "deep-equal": "^1.1.1", + "popper.js": "^1.14.4", + "prop-types": "^15.6.1", + "typed-styles": "^0.0.7", + "warning": "^4.0.2" + } + }, "react-refresh": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", @@ -11861,6 +12255,26 @@ "workbox-webpack-plugin": "5.1.4" } }, + "react-scroll": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/react-scroll/-/react-scroll-1.8.2.tgz", + "integrity": "sha512-f2ZEG5fsPbPTySI9ekcFpETCcNlqbmwbQj9hhzYK8tkgv+PA8APatSt66o/q0KSkDZxyT98ONTtXp9x0lyowEw==", + "requires": { + "lodash.throttle": "^4.1.1", + "prop-types": "^15.7.2" + } + }, + "react-transition-group": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz", + "integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==", + "requires": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + } + }, "read-pkg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", @@ -11954,7 +12368,6 @@ "version": "3.5.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "optional": true, "requires": { "picomatch": "^2.2.1" } @@ -12690,6 +13103,14 @@ "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-10.0.0.tgz", "integrity": "sha512-vTxrZz4dX5W86M6oVWVdOVe72ZiPs41Oi7Z6Km4W5Turyz28mrXSJhhEBZoRtzJWIv3833WKVwLSDWWkEfupMg==" }, + "sass": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.33.0.tgz", + "integrity": "sha512-9v0MUXnSi62FtfjqcwZ+b8B9FIxdwFEb3FPUkjEPXWd0b5KcnPGSp2XF9WrzcH1ZxedfgJVTdA3A1j4eEj53xg==", + "requires": { + "chokidar": ">=3.0.0 <4.0.0" + } + }, "sass-loader": { "version": "10.1.1", "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-10.1.1.tgz", @@ -12746,6 +13167,14 @@ "ajv-keywords": "^3.5.2" } }, + "scroll-into-view-if-needed": { + "version": "2.2.28", + "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.28.tgz", + "integrity": "sha512-8LuxJSuFVc92+0AdNv4QOxRL4Abeo1DgLnGNkn1XlaujPH/3cCFz3QI60r2VNu4obJJROzgnIUw5TKQkZvZI1w==", + "requires": { + "compute-scroll-into-view": "^1.0.17" + } + }, "select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -12814,6 +13243,11 @@ "randombytes": "^2.1.0" } }, + "serialize-query-params": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/serialize-query-params/-/serialize-query-params-1.3.3.tgz", + "integrity": "sha512-rJIIETRuGUVbLekC73IiXV3738ylEHbHK1kxaXAbhxbxfio0yvVXaRMF+OyLZOBMwdgDHYLaj6EMBAEiSf8C/g==" + }, "serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", @@ -12944,6 +13378,21 @@ "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", "optional": true }, + "shortid": { + "version": "2.2.16", + "resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.16.tgz", + "integrity": "sha512-Ugt+GIZqvGXCIItnsL+lvFJOiN7RYqlGy7QE41O3YC1xbNSeDGIRO7xg2JJXIAj1cAGnOeC1r7/T9pgrtQbv4g==", + "requires": { + "nanoid": "^2.1.0" + }, + "dependencies": { + "nanoid": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz", + "integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==" + } + } + }, "side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -13260,6 +13709,11 @@ "wbuf": "^1.7.3" } }, + "split-on-first": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", + "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==" + }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", @@ -13445,9 +13899,9 @@ "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" }, "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", + "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=" }, "string-length": { "version": "4.0.2", @@ -13922,6 +14376,11 @@ "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==" }, + "throttle-debounce": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-2.3.0.tgz", + "integrity": "sha512-H7oLPV0P7+jgvrk+6mwwwBDmxTaxnu9HMXmloNLXwnNO0ZxZ31Orah2n8lU1eMPvsaowP2CX+USCgyovXfdOFQ==" + }, "through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", @@ -14164,6 +14623,11 @@ "mime-types": "~2.1.24" } }, + "typed-styles": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.7.tgz", + "integrity": "sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q==" + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -14188,6 +14652,17 @@ "which-boxed-primitive": "^1.0.2" } }, + "uncontrollable": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", + "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", + "requires": { + "@babel/runtime": "^7.6.3", + "@types/react": ">=16.9.11", + "invariant": "^2.2.4", + "react-lifecycles-compat": "^3.0.4" + } + }, "unicode-canonical-property-names-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", @@ -14383,11 +14858,39 @@ "requires-port": "^1.0.0" } }, + "urs": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/urs/-/urs-0.0.8.tgz", + "integrity": "sha512-LaSSPpr91XrVA3vW2zPupw4K6DSQEDKdL4yQZX1mO2fpljIMpB5zctrjRvxLurelWSgKsHsCmfHNCImscryirQ==" + }, "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" }, + "use-http": { + "version": "1.0.20", + "resolved": "https://registry.npmjs.org/use-http/-/use-http-1.0.20.tgz", + "integrity": "sha512-3JOASSO828AsUwGjH3nhjUxHpR0lxIUSSNO/OM+0YydETX6FWJV5zWiGKTOV1Gsxu/3GLRFUbEJ1Cl3mUGkfnw==", + "requires": { + "urs": "^0.0.8", + "use-ssr": "^1.0.24", + "utility-types": "^3.10.0" + } + }, + "use-query-params": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/use-query-params/-/use-query-params-1.2.2.tgz", + "integrity": "sha512-Uyfe+/TECsNNzCSkgUM1MM24OEGxGE4aeWvZEf0a14iQFp/m43wiqI1HZ9oTlrRSZwD5yABeLc9rN+wtiB5B3Q==", + "requires": { + "serialize-query-params": "^1.3.3" + } + }, + "use-ssr": { + "version": "1.0.24", + "resolved": "https://registry.npmjs.org/use-ssr/-/use-ssr-1.0.24.tgz", + "integrity": "sha512-0MFps7ezL57/3o0yl4CvrHLlp9z20n1rQZV/lSRz7if+TUoM6POU1XdOvEjIgjgKeIhTEye1U0khrIYWCTWw4g==" + }, "util": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", @@ -14424,6 +14927,11 @@ "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=" }, + "utility-types": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz", + "integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==" + }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -14466,6 +14974,38 @@ "spdx-expression-parse": "^3.0.0" } }, + "validate.io-array": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/validate.io-array/-/validate.io-array-1.0.6.tgz", + "integrity": "sha1-W1osr9j4uFq7L4hroVPy2Tond00=" + }, + "validate.io-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/validate.io-function/-/validate.io-function-1.0.2.tgz", + "integrity": "sha1-NDoZgC7TsZaCaceA5VjpNBHAutc=" + }, + "validate.io-integer": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/validate.io-integer/-/validate.io-integer-1.0.5.tgz", + "integrity": "sha1-FoSWSAuVviJH7EQ/IjPeT4mHgGg=", + "requires": { + "validate.io-number": "^1.0.3" + } + }, + "validate.io-integer-array": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/validate.io-integer-array/-/validate.io-integer-array-1.0.0.tgz", + "integrity": "sha1-LKveAzKTpry+Bj/q/pHq9GsToIk=", + "requires": { + "validate.io-array": "^1.0.3", + "validate.io-integer": "^1.0.4" + } + }, + "validate.io-number": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/validate.io-number/-/validate.io-number-1.0.3.tgz", + "integrity": "sha1-9j/+2iSL8opnqNSODjtGGhZluvg=" + }, "value-equal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", @@ -14520,6 +15060,14 @@ "makeerror": "1.0.x" } }, + "warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "requires": { + "loose-envify": "^1.0.0" + } + }, "watchpack": { "version": "1.7.5", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", @@ -15290,6 +15838,17 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, + "http-proxy-middleware": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", + "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", + "requires": { + "http-proxy": "^1.17.0", + "is-glob": "^4.0.0", + "lodash": "^4.17.11", + "micromatch": "^3.1.10" + } + }, "import-local": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", diff --git a/ui/public/assets/schema/attribute/attribute.schema.json b/ui/public/assets/schema/attribute/attribute.schema.json new file mode 100644 index 000000000..cc99dc3a6 --- /dev/null +++ b/ui/public/assets/schema/attribute/attribute.schema.json @@ -0,0 +1,102 @@ +{ + "type": "object", + "required": [ + "name", + "attributeType" + ], + "properties": { + "name": { + "title": "label.entity-attribute-name", + "description": "tooltip.entity-attribute-name", + "type": "string", + "minLength": 1, + "maxLength": 255 + }, + "attributeType": { + "title": "label.entity-attribute-type", + "description": "tooltip.entity-attribute-type", + "type": "string", + "enum": [ + "STRING", + "BOOLEAN", + "SELECTION_LIST" + ], + "enumNames": [ + "value.string", + "value.boolean", + "value.list" + ] + }, + "helpText": { + "title": "label.entity-attribute-help", + "description": "tooltip.entity-attribute-help", + "type": "string", + "minLength": 1, + "maxLength": 255 + } + }, + "dependencies": { + "attributeType": { + "oneOf": [ + { + "properties": { + "attributeType": { + "enum": [ + "STRING" + ] + }, + "defaultValueString": { + "title": "label.entity-attribute-default", + "description": "tooltip.entity-attribute-default", + "type": "string" + } + } + }, + { + "properties": { + "attributeType": { + "enum": [ + "BOOLEAN" + ] + }, + "defaultValueBoolean": { + "title": "label.entity-attribute-default", + "description": "tooltip.entity-attribute-default", + "type": "boolean", + "default": true, + "enumNames": ["True", "False"] + } + } + }, + { + "properties": { + "attributeType": { + "enum": [ + "SELECTION_LIST" + ] + }, + "customAttrListDefinitions": { + "title": "label.entity-attribute-list-options", + "description": "tooltip.entity-attribute-list-options", + "type": "array", + "items": { + "title": "label.list-options", + "type": "object", + "properties": { + "value": { + "type": "string", + "placeholder": "Option" + }, + "default": { + "type": "boolean", + "default": false + } + } + } + } + } + } + ] + } + } +} \ No newline at end of file diff --git a/ui/src/app/App.js b/ui/src/app/App.js index ee40bb538..b3f8a2419 100644 --- a/ui/src/app/App.js +++ b/ui/src/app/App.js @@ -17,6 +17,7 @@ import Dashboard from './dashboard/view/Dashboard'; import Header from './core/components/Header'; import { UserProvider } from './core/user/UserContext'; import { Metadata } from './metadata/Metadata'; +import { Attribute } from './metadata/Attribute'; import { Notifications } from './notifications/hoc/Notifications'; import { NotificationList } from './notifications/component/NotificationList'; import { UserConfirmation, ConfirmWindow } from './core/components/UserConfirmation'; @@ -59,6 +60,7 @@ function App() { + diff --git a/ui/src/app/core/components/Header.js b/ui/src/app/core/components/Header.js index 294be7943..ac98ec7d1 100644 --- a/ui/src/app/core/components/Header.js +++ b/ui/src/app/core/components/Header.js @@ -26,6 +26,18 @@ export function Header () { + + + + + + + + + + + + @@ -34,11 +46,11 @@ export function Header () { - Metadata Source + - Metadata Provider + diff --git a/ui/src/app/form/component/fields/StringListWithDefaultField.js b/ui/src/app/form/component/fields/StringListWithDefaultField.js new file mode 100644 index 000000000..3f8ba8b74 --- /dev/null +++ b/ui/src/app/form/component/fields/StringListWithDefaultField.js @@ -0,0 +1,147 @@ +import React from 'react'; + +import Row from "react-bootstrap/Row"; +import Col from "react-bootstrap/Col"; +import Form from 'react-bootstrap/Form'; + +import Button from 'react-bootstrap/Button'; + +import AddButton from "../AddButton"; + +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faTrash } from '@fortawesome/free-solid-svg-icons'; + +const ArrayFieldDescription = ({ + DescriptionField, + idSchema, + description, +}) => { + if (!description) { + return null; + } + + const id = `${idSchema.$id}__description`; + return ; +}; + + +const ArrayFieldTitle = ({ + TitleField, + idSchema, + title, + required, +}) => { + if (!title) { + return null; + } + + const id = `${idSchema.$id}__title`; + return ; +}; + +const defItem = { + value: '', + default: false +} + +const StringListWithDefaultField = ({ + schema, + label, + id, + name, + disabled, + value, + readonly, + rawErrors, + onChange, + errorSchema, + formData, + registry, + ...props +}) => { + + const { fields } = registry; + const [items, setItems] = React.useState([ + ...(formData ? formData : []) + ]); + + React.useEffect(() => { + onChange(items); + }, [items, onChange]); + + const onAdd = () => { + setItems([...items, { ...defItem }]); + }; + + const setValue = (item, value) => { + item.value = value; + setItems([...items]); + }; + + const setDefault = (item) => { + const current = items.find(i => i.default); + if (current) { + current.default = false; + } + item.default = true; + setItems([...items]); + }; + + const removeItem = (item) => { + setItems([...items.filter(i => i !== item)]); + }; + + return ( + + + + + {} + + {(props.uiSchema["ui:description"] || schema.description) && ( + + )} + + + {items && items.map((p, idx) => + + setValue(p, value)}> + setDefault(p) } + > + removeItem(p)}> + + + + )} + + + + + ); +}; + + +export default StringListWithDefaultField; \ No newline at end of file diff --git a/ui/src/app/form/component/index.js b/ui/src/app/form/component/index.js index 3ca8039a8..013e118db 100644 --- a/ui/src/app/form/component/index.js +++ b/ui/src/app/form/component/index.js @@ -14,12 +14,14 @@ import ObjectFieldTemplate from './templates/ObjectFieldTemplate'; import TitleField from './fields/TitleField'; import DescriptionField from './fields/DescriptionField'; import FilterTargetField from './fields/FilterTargetField'; +import StringListWithDefaultField from './fields/StringListWithDefaultField'; export const fields = { // SchemaField: CustomSchemaField TitleField, DescriptionField, - FilterTargetField + FilterTargetField, + StringListWithDefaultField }; export const templates = { diff --git a/ui/src/app/form/component/templates/ArrayFieldTemplate.js b/ui/src/app/form/component/templates/ArrayFieldTemplate.js index 7af4e2dde..e138c10a0 100644 --- a/ui/src/app/form/component/templates/ArrayFieldTemplate.js +++ b/ui/src/app/form/component/templates/ArrayFieldTemplate.js @@ -239,46 +239,44 @@ const DefaultNormalArrayFieldTemplate = (props) => { const showTitle = props.uiSchema.hasOwnProperty("ui:title") ? props.uiSchema["ui:title"] === false && !props.canAdd ? false : true : true; return ( - - - - - {showTitle && + + + {showTitle && } + {props.canAdd && ( + + )} + {(props.uiSchema["ui:description"] || props.schema.description) && ( + } - {props.canAdd && ( - - )} - {(props.uiSchema["ui:description"] || props.schema.description) && ( - - )} - - - {props.items && props.items.map(p => - props.schema.items.type === 'object' || props.schema.items.$ref ? - ObjectArrayItem({type: props.uiSchema.type, ...p}) - : - DefaultArrayItem({...p, uiSchema: props.uiSchema.items }) - )} - - - - + description={ + props.uiSchema["ui:description"] || props.schema.description + } + /> + )} + + + {props.items && props.items.map(p => + props.schema.items.type === 'object' || props.schema.items.$ref ? + ObjectArrayItem({ type: props.uiSchema.type, ...p }) + : + DefaultArrayItem({ ...p, uiSchema: props.uiSchema.items }) + )} + + + ); }; diff --git a/ui/src/app/form/component/widgets/SelectWidget.js b/ui/src/app/form/component/widgets/SelectWidget.js index c38388e8c..9a2cd421c 100644 --- a/ui/src/app/form/component/widgets/SelectWidget.js +++ b/ui/src/app/form/component/widgets/SelectWidget.js @@ -86,7 +86,7 @@ const SelectWidget = ({ return ( - 0 ? "text-danger" : ""}`}> + 0 ? "text-danger" : ""}`}> {(label || schema.title) && required ? : null} @@ -103,7 +103,7 @@ const SelectWidget = ({ disabled={disabled} readOnly={readonly} autoFocus={autofocus} - className={rawErrors.length > 0 ? "is-invalid" : ""} + className={touched && rawErrors.length > 0 ? "is-invalid" : ""} onBlur={ onBlur && ((event) => { diff --git a/ui/src/app/metadata/Attribute.js b/ui/src/app/metadata/Attribute.js new file mode 100644 index 000000000..c8d2aa502 --- /dev/null +++ b/ui/src/app/metadata/Attribute.js @@ -0,0 +1,30 @@ +import React from 'react'; +import { Switch, Route, useRouteMatch, Redirect } from 'react-router-dom'; +import { MetadataAttributes } from './hoc/MetadataAttributes'; +import { NewAttribute } from './new/NewAttribute'; +import { MetadataAttributeEdit } from './view/MetadataAttributeEdit'; +import { MetadataAttributeList } from './view/MetadataAttributeList'; + +export function Attribute() { + + let { path } = useRouteMatch(); + + return ( + + + + {(entities, onDelete) => + + } + + } /> + + + } /> + + + } /> + + + ); +} \ No newline at end of file diff --git a/ui/src/app/metadata/component/DeleteConfirmation.js b/ui/src/app/metadata/component/DeleteConfirmation.js new file mode 100644 index 000000000..e441f9442 --- /dev/null +++ b/ui/src/app/metadata/component/DeleteConfirmation.js @@ -0,0 +1,59 @@ +import React from 'react'; + +import Modal from 'react-bootstrap/Modal'; + +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons'; +import Translate from '../../i18n/components/translate'; + +export function DeleteConfirmation({ children, onConfirm, onCancel, body, title }) { + + const [deleting, setDeleting] = React.useState(false); + + const ref = React.useRef(); + + const onConfirmClick = () => { + if (onConfirm) { + onConfirm(); + } + if (ref.current && typeof ref.current === 'function') { + ref.current(); + } + setDeleting(false); + } + + const onCancelClick = () => { + if (onCancel) { + onCancel(); + } + setDeleting(false); + }; + + const onShow = (callback) => { + ref.current = callback; + setDeleting(true); + }; + + return ( + <> + {children((callback) => onShow(callback))} + onCancelClick()}> + {title && Delete Metadata Source?} + + + + You are deleting an entity. This cannot be undone. Continue? + + + + onConfirmClick()}> + Delete + {' '} + onCancelClick()}> + Cancel + + + + > + ); +} \ No newline at end of file diff --git a/ui/src/app/metadata/domain/attribute/CustomAttributeDefinition.js b/ui/src/app/metadata/domain/attribute/CustomAttributeDefinition.js new file mode 100644 index 000000000..d04cfab6e --- /dev/null +++ b/ui/src/app/metadata/domain/attribute/CustomAttributeDefinition.js @@ -0,0 +1,120 @@ +import { defaultsDeep } from "lodash"; + +export const CustomAttributeDefinition = { + label: 'Metadata Attribute', + type: '@MetadataAttribute', + steps: [], + schema: `/assets/schema/attribute/attribute.schema.json`, + + uiSchema: { + layout: { + groups: [ + { + size: 6, + classNames: '', + fields: [ + 'name', + 'attributeType', + 'helpText' + ] + }, + { + size: 6, + classNames: 'bg-light border rounded p-4', + fields: [ + 'defaultValue', + 'defaultValueBoolean', + 'defaultValueString', + 'customAttrListDefinitions' + ] + } + ] + }, + defaultValueBoolean: { + 'ui:widget': 'radio' + }, + customAttrListDefinitions: { + 'ui:field': 'StringListWithDefaultField', + 'ui:title': 'label.entity-attribute-list-options', + items: { + default: { + 'ui:widget': 'checkbox' + } + } + } + }, + + parser: (data) => { + if (!data) { + return data; + } + const { attributeType } = data; + let parsed = { ...data }; + if (attributeType === 'SELECTION_LIST') { + parsed = { + ...parsed, + defaultValue: data.customAttrListDefinitions.find(d => d.default)?.value, + customAttrListDefinitions: data.customAttrListDefinitions.map(d => d.value) + } + } + + if (attributeType === 'BOOLEAN') { + parsed = { + ...parsed, + defaultValue: data.defaultValueBoolean + } + } + + if (attributeType === 'STRING') { + parsed = { + ...parsed, + defaultValue: data.defaultValueString + } + } + + return parsed; + }, + + formatter: (changes) => { + if (!changes) { + return changes; + } + let formatted = { ...changes }; + const { attributeType } = changes; + + if (attributeType === 'SELECTION_LIST') { + formatted = { + ...formatted, + customAttrListDefinitions: formatted.customAttrListDefinitions.map(d => ({ + value: d, + default: d === changes.defaultValue + })) + } + } + + if (attributeType === 'BOOLEAN') { + formatted = { + ...formatted, + defaultValueBoolean: formatted.defaultValue === 'true' ? true : false + } + } + + if (attributeType === 'STRING') { + formatted = { + ...formatted, + defaultValueString: formatted.defaultValue + } + } + + return formatted; + } +} + +export const CustomAttributeEditor = { + ...CustomAttributeDefinition, + uiSchema: defaultsDeep({ + attributeType: { + 'ui:disabled': true + } + }, CustomAttributeDefinition.uiSchema) +}; \ No newline at end of file diff --git a/ui/src/app/metadata/domain/index.js b/ui/src/app/metadata/domain/index.js index 70edb596c..7a8cfb83d 100644 --- a/ui/src/app/metadata/domain/index.js +++ b/ui/src/app/metadata/domain/index.js @@ -1,3 +1,4 @@ +import { CustomAttributeDefinition } from './attribute/CustomAttributeDefinition'; import { MetadataFilterEditorTypes } from './filter'; import { MetadataProviderEditorTypes, MetadataProviderWizardTypes } from './provider'; import { SourceEditor, SourceWizard } from "./source/SourceDefinition"; @@ -20,12 +21,17 @@ export const FilterEditorTypes = [ ...MetadataFilterEditorTypes ]; +export const AttributeEditorTypes = [ + CustomAttributeDefinition +] + export const getWizard = (type) => ProviderWizardTypes.find(def => def.type === type) || FilterEditorTypes.find(def => def.type === type) || SourceWizard; export const getDefinition = (type) => + typeof type === 'string' ? ProviderEditorTypes.find(def => def.type === type) || FilterEditorTypes.find(def => def.type === type) || - SourceEditor; \ No newline at end of file + SourceEditor : type; \ No newline at end of file diff --git a/ui/src/app/metadata/editor/MetadataAttributeEditor.js b/ui/src/app/metadata/editor/MetadataAttributeEditor.js new file mode 100644 index 000000000..9c13e2a5f --- /dev/null +++ b/ui/src/app/metadata/editor/MetadataAttributeEditor.js @@ -0,0 +1,54 @@ +import React from 'react'; +import { MetadataFormContext, setFormDataAction, setFormErrorAction } from '../hoc/MetadataFormContext'; +import { MetadataDefinitionContext, MetadataSchemaContext } from '../hoc/MetadataSchema'; + +import Form from '@rjsf/bootstrap-4'; + +import { fields, widgets } from '../../form/component'; +import { templates } from '../../form/component'; + +function ErrorListTemplate() { + return (<>>); +} + +export function MetadataAttributeEditor({ children }) { + + const definition = React.useContext(MetadataDefinitionContext); + const schema = React.useContext(MetadataSchemaContext); + + const { state, dispatch } = React.useContext(MetadataFormContext); + const { metadata, errors } = state; + + const onChange = (changes) => { + dispatch(setFormDataAction(changes.formData)); + dispatch(setFormErrorAction(changes.errors)); + // setBlocking(true); + }; + + return ( + + + {children(metadata, errors)} + + + + + onChange(form)} + schema={schema} + uiSchema={definition.uiSchema} + FieldTemplate={templates.FieldTemplate} + ObjectFieldTemplate={templates.ObjectFieldTemplate} + ArrayFieldTemplate={templates.ArrayFieldTemplate} + fields={fields} + widgets={widgets} + liveValidate={true} + ErrorList={ErrorListTemplate}> + <>> + + + + + ); +} \ No newline at end of file diff --git a/ui/src/app/metadata/editor/MetadataEditor.js b/ui/src/app/metadata/editor/MetadataEditor.js index 1290d07c1..491f06fe9 100644 --- a/ui/src/app/metadata/editor/MetadataEditor.js +++ b/ui/src/app/metadata/editor/MetadataEditor.js @@ -11,7 +11,6 @@ import { MetadataDefinitionContext, MetadataSchemaContext } from '../hoc/Metadat import { MetadataEditorForm } from './MetadataEditorForm'; import { MetadataEditorNav } from './MetadataEditorNav'; import { getMetadataPath, useMetadataEntities, useMetadataUpdater } from '../hooks/api'; -import { useMetadataObject } from '../hoc/MetadataSelector'; import { NavLink } from 'react-router-dom'; import { useTranslator } from '../../i18n/hooks'; import API_BASE_PATH from '../../App.constant'; @@ -34,7 +33,7 @@ export function MetadataEditor ({ current }) { const onChange = (changes) => { dispatch(setFormDataAction(changes.formData)); - dispatch(setFormErrorAction(section, changes.errors)); + dispatch(setFormErrorAction(changes.errors)); // setBlocking(true); }; diff --git a/ui/src/app/metadata/editor/MetadataFilterEditor.js b/ui/src/app/metadata/editor/MetadataFilterEditor.js index 46033696d..f34d676c0 100644 --- a/ui/src/app/metadata/editor/MetadataFilterEditor.js +++ b/ui/src/app/metadata/editor/MetadataFilterEditor.js @@ -28,7 +28,7 @@ export function MetadataFilterEditor({children}) { const onChange = (changes) => { dispatch(setFormDataAction(changes.formData)); - dispatch(setFormErrorAction(section, changes.errors)); + dispatch(setFormErrorAction(changes.errors)); // setBlocking(true); }; diff --git a/ui/src/app/metadata/hoc/MetadataAttributes.js b/ui/src/app/metadata/hoc/MetadataAttributes.js new file mode 100644 index 000000000..c4c59d3c0 --- /dev/null +++ b/ui/src/app/metadata/hoc/MetadataAttributes.js @@ -0,0 +1,34 @@ +import React from 'react'; +import { useMetadataAttribute, useMetadataAttributes } from '../hooks/api'; + +export function MetadataAttributes ({children}) { + + const { get, response } = useMetadataAttributes({ + cachePolicy: 'no-cache' + }); + + const attrApi = useMetadataAttribute(); + + const { del } = attrApi; + + const [attributes, setAttributes] = React.useState([]); + + async function loadAttributes() { + const list = await get(``); + if (response.ok) { + setAttributes(list); + } + } + + async function removeAttribute(id) { + await del(`/${id}`); + if (attrApi.response.ok) { + loadAttributes(); + } + } + + /*eslint-disable react-hooks/exhaustive-deps*/ + React.useEffect(() => { loadAttributes() }, []); + + return (<>{children(attributes, removeAttribute)}>); +} \ No newline at end of file diff --git a/ui/src/app/metadata/hoc/MetadataFormContext.js b/ui/src/app/metadata/hoc/MetadataFormContext.js index e809239ff..e12b33210 100644 --- a/ui/src/app/metadata/hoc/MetadataFormContext.js +++ b/ui/src/app/metadata/hoc/MetadataFormContext.js @@ -28,11 +28,10 @@ export const setFormDataAction = (payload) => { } } -export const setFormErrorAction = (page, errors) => { +export const setFormErrorAction = (errors) => { return { type: MetadataFormActions.SET_FORM_ERROR, payload: { - page, errors } } @@ -59,8 +58,7 @@ function reducer(state, action) { function MetadataForm({ children, initial = {}, onChange }) { const metadata = { - ...useFormattedMetadata(), - ...initial + ...useFormattedMetadata(initial) }; const [state, dispatch] = React.useReducer(reducer, { @@ -113,7 +111,8 @@ function usePagesWithErrors(definition) { function useFormattedMetadata(initial = {}) { const definition = React.useContext(MetadataDefinitionContext); const schema = React.useContext(MetadataSchemaContext); - return definition.formatter(React.useContext(MetadataObjectContext), schema); + const obj = React.useContext(MetadataObjectContext); + return definition.formatter(initial ? initial : obj, schema); } function useMetadataFormContext () { diff --git a/ui/src/app/metadata/hooks/api.js b/ui/src/app/metadata/hooks/api.js index c799d4be4..5e224812e 100644 --- a/ui/src/app/metadata/hooks/api.js +++ b/ui/src/app/metadata/hooks/api.js @@ -115,4 +115,14 @@ export function useMetadataUpdater (path, current) { update, error } +} + +export function useMetadataAttributes (opts = {}, onMount) { + // + return useFetch(`${API_BASE_PATH}/custom/entity/attributes`, opts, onMount); +} + +export function useMetadataAttribute(opts = {}, onMount) { + // + return useFetch(`${API_BASE_PATH}/custom/entity/attribute`, opts, onMount); } \ No newline at end of file diff --git a/ui/src/app/metadata/new/NewAttribute.js b/ui/src/app/metadata/new/NewAttribute.js new file mode 100644 index 000000000..88a6537ec --- /dev/null +++ b/ui/src/app/metadata/new/NewAttribute.js @@ -0,0 +1,82 @@ +import { faSave, faSpinner } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import React from 'react'; +import { Prompt, useHistory } from 'react-router'; +import Translate from '../../i18n/components/translate'; +import { MetadataAttributeEditor } from '../editor/MetadataAttributeEditor'; +import { useMetadataAttribute } from '../hooks/api'; + +import {CustomAttributeDefinition} from '../domain/attribute/CustomAttributeDefinition'; +import MetadataSchema from '../hoc/MetadataSchema'; +import { MetadataForm } from '../hoc/MetadataFormContext'; + +export function NewAttribute() { + const history = useHistory(); + + const definition = CustomAttributeDefinition; + + const { post, response, loading } = useMetadataAttribute({}); + + const [blocking, setBlocking] = React.useState(false); + + async function save(metadata) { + await post(``, definition.parser(metadata)); + if (response.ok) { + gotoDetail({ refresh: true }); + } + }; + + const cancel = () => { + gotoDetail(); + }; + + const gotoDetail = (state = null) => { + setBlocking(false); + history.push(`/metadata/attributes`, state); + }; + + return ( + + + `message.unsaved-editor` + } + /> + + + + + Add a new metadata attribute + + + + + + + + {(filter, errors) => + + save(filter)} + disabled={errors.length > 0 || loading} + aria-label="Save changes to the metadata source. You will return to the dashboard"> + + Save + + cancel()} aria-label="Cancel changes, go back to dashboard"> + Cancel + + + } + + + + + + + ); +} \ No newline at end of file diff --git a/ui/src/app/metadata/view/MetadataAttributeEdit.js b/ui/src/app/metadata/view/MetadataAttributeEdit.js new file mode 100644 index 000000000..6d035851c --- /dev/null +++ b/ui/src/app/metadata/view/MetadataAttributeEdit.js @@ -0,0 +1,101 @@ +import { faSave, faSpinner } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import React from 'react'; +import { Prompt, useHistory, useParams } from 'react-router'; +import Translate from '../../i18n/components/translate'; +import { MetadataAttributeEditor } from '../editor/MetadataAttributeEditor'; +import { useMetadataAttribute } from '../hooks/api'; + +import { CustomAttributeDefinition, CustomAttributeEditor } from '../domain/attribute/CustomAttributeDefinition'; +import MetadataSchema from '../hoc/MetadataSchema'; +import { MetadataForm } from '../hoc/MetadataFormContext'; + +export function MetadataAttributeEdit() { + const { id } = useParams(); + const history = useHistory(); + + const definition = CustomAttributeDefinition; + + const { get, put, response, loading } = useMetadataAttribute({ + cachePolicy: 'no-cache' + }); + + const [blocking, setBlocking] = React.useState(false); + + async function loadAttribute() { + const attr = await get(`/${id}`); + if (response.ok) { + setAttribute(attr); + } + } + + async function save(metadata) { + await put(``, definition.parser(metadata)); + if (response.ok) { + gotoDetail({ refresh: true }); + } + }; + + const cancel = () => { + gotoDetail(); + }; + + const gotoDetail = (state = null) => { + setBlocking(false); + history.push(`/metadata/attributes`, state); + }; + + const [attribute, setAttribute] = React.useState(); + + /*eslint-disable react-hooks/exhaustive-deps*/ + React.useEffect(() => { + loadAttribute(); + }, []); + + return ( + + + `message.unsaved-editor` + } + /> + + + + + Add a new metadata attribute + + + + + + {attribute && + + + {(filter, errors) => + + save(filter)} + disabled={errors.length > 0 || loading} + aria-label="Save changes to the metadata source. You will return to the dashboard"> + + Save + + cancel()} aria-label="Cancel changes, go back to dashboard"> + Cancel + + + } + + + } + + + + + ); +} \ No newline at end of file diff --git a/ui/src/app/metadata/view/MetadataAttributeList.js b/ui/src/app/metadata/view/MetadataAttributeList.js new file mode 100644 index 000000000..e91313116 --- /dev/null +++ b/ui/src/app/metadata/view/MetadataAttributeList.js @@ -0,0 +1,89 @@ +import { faEdit, faPlusCircle, faTrash } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import React from 'react'; +import { Link } from 'react-router-dom'; + +import { Translate } from '../../i18n/components/translate'; +import { useTranslator } from '../../i18n/hooks'; + +import { DeleteConfirmation } from '../component/DeleteConfirmation'; + +export function MetadataAttributeList ({entities, onDelete}) { + + const translator = useTranslator(); + + const remove = (id) => { + onDelete(id); + } + + return ( + + {(block) => + + + + + + Custom Entity Attributes + + + + + + + Add new attribute + + + + + + + + Attribute Name + + + Type + + + Help Text + + + Default Value + + Actions + + + + {entities.map((attr, i) => + + {attr.name} + {translator(`value.${attr.attributeType}`)} + {attr.helpText} + {attr.defaultValue?.toString()} + + + + + Edit + + + block(() => remove(attr.name))}> + + + Delete + + + + + )} + + + + + + + + } + + ); +} \ No newline at end of file diff --git a/ui/src/app/metadata/wizard/MetadataProviderWizard.js b/ui/src/app/metadata/wizard/MetadataProviderWizard.js index 5f612bfb4..c2d06380d 100644 --- a/ui/src/app/metadata/wizard/MetadataProviderWizard.js +++ b/ui/src/app/metadata/wizard/MetadataProviderWizard.js @@ -35,7 +35,7 @@ export function MetadataProviderWizard({onRestart}) { const onChange = (changes) => { formDispatch(setFormDataAction(changes.formData)); - formDispatch(setFormErrorAction(current, changes.errors)); + formDispatch(setFormErrorAction(changes.errors)); // console.log('change', changes); }; diff --git a/ui/src/app/metadata/wizard/MetadataSourceWizard.js b/ui/src/app/metadata/wizard/MetadataSourceWizard.js index 735c19e17..1af478d8b 100644 --- a/ui/src/app/metadata/wizard/MetadataSourceWizard.js +++ b/ui/src/app/metadata/wizard/MetadataSourceWizard.js @@ -37,7 +37,7 @@ export function MetadataSourceWizard ({ onShowNav }) { const onChange = (changes) => { formDispatch(setFormDataAction(changes.formData)); - formDispatch(setFormErrorAction(current, changes.errors)); + formDispatch(setFormErrorAction(changes.errors)); // console.log('change', changes); };
+ You are deleting an entity. This cannot be undone. Continue? +